aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp2
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp2
-rw-r--r--src/server/game/Accounts/RBAC.h1
-rw-r--r--src/server/game/Chat/Chat.cpp13
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp458
-rw-r--r--src/server/game/Conditions/ConditionMgr.h19
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp11
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp101
-rw-r--r--src/server/game/Globals/ObjectMgr.h5
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp24
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp4
-rw-r--r--src/server/game/Instances/InstanceScript.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp6
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp33
-rw-r--r--src/server/game/Scripting/ScriptMgr.h10
-rw-r--r--src/server/game/Server/WorldSession.cpp26
-rw-r--r--src/server/game/Spells/Spell.cpp15
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellScript.cpp4
-rw-r--r--src/server/game/Spells/SpellScript.h5
-rw-r--r--src/server/game/Tools/PlayerDump.cpp8
-rw-r--r--src/server/game/World/World.cpp5
-rw-r--r--src/server/game/World/World.h4
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp4
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp4
-rw-r--r--src/server/scripts/Commands/cs_group.cpp2
-rw-r--r--src/server/scripts/Commands/cs_list.cpp16
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp14
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp10
-rw-r--r--src/server/scripts/Commands/cs_quest.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp618
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h9
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp91
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp1
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp254
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp106
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp203
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h63
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp17
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp49
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp328
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/nexus.h45
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp26
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.h12
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp166
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp43
-rw-r--r--src/server/scripts/Northrend/zone_icecrown.cpp241
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp38
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h8
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp25
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h6
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp14
-rw-r--r--src/server/scripts/World/go_scripts.cpp67
-rw-r--r--src/server/shared/Common.h3
-rw-r--r--src/server/shared/Networking/MessageBuffer.h8
-rw-r--r--src/server/shared/Networking/Socket.h3
-rw-r--r--src/server/shared/Networking/SocketMgr.h11
-rw-r--r--src/server/worldserver/worldserver.conf.dist18
67 files changed, 1533 insertions, 1787 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 5f6573ad1a6..36eedae90ef 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2264,7 +2264,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (linked)
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
else
- TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
+ TC_LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
}
}
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 79b9557fc2b..43fe9a80bc3 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -462,7 +462,7 @@ void AccountMgr::LoadRBAC()
while (result->NextRow());
TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
- result = LoginDatabase.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
+ result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmID);
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 7001374d90a..d63ba84605e 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -100,6 +100,7 @@ enum RBACPermissions
RBAC_PERM_COMMANDS_PINFO_CHECK_PERSONAL_DATA = 48,
RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE = 49,
RBAC_PERM_MAY_CHECK_OWN_EMAIL = 50,
+ RBAC_PERM_ALLOW_TWO_SIDE_TRADE = 51,
// Free space for core permissions (till 149)
// Roles (Permissions with delegated permissions) use 199 and descending
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 6f614994489..f05ce5bded9 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -982,7 +982,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
if (!idS)
return 0;
- uint32 id = (uint32)atol(idS);
+ uint32 id = atoul(idS);
switch (type)
{
@@ -995,13 +995,10 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
if (!talentEntry)
return 0;
- int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
+ uint32 rank = param1_str ? atol(param1_str) : 0u;
if (rank >= MAX_TALENT_RANK)
return 0;
- if (rank < 0)
- rank = 0;
-
return talentEntry->RankID[rank];
}
case SPELL_LINK_ENCHANT:
@@ -1009,7 +1006,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
return id;
case SPELL_LINK_GLYPH:
{
- uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0;
+ uint32 glyph_prop_id = param1_str ? atoul(param1_str) : 0;
GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id);
if (!glyphPropEntry)
@@ -1082,7 +1079,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text)
}
case SPELL_LINK_CREATURE:
{
- uint32 lowguid = (uint32)atol(idS);
+ uint32 lowguid = atoul(idS);
if (CreatureData const* data = sObjectMgr->GetCreatureData(lowguid))
return ObjectGuid(HIGHGUID_UNIT, data->id, lowguid);
@@ -1091,7 +1088,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text)
}
case SPELL_LINK_GAMEOBJECT:
{
- uint32 lowguid = (uint32)atol(idS);
+ uint32 lowguid = atoul(idS);
if (GameObjectData const* data = sObjectMgr->GetGOData(lowguid))
return ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, lowguid);
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 094a8345395..f7fa719a610 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -29,6 +29,79 @@
#include "SpellMgr.h"
#include "Spell.h"
+char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
+{
+ "None",
+ "Creature Loot",
+ "Disenchant Loot",
+ "Fishing Loot",
+ "GameObject Loot",
+ "Item Loot",
+ "Mail Loot",
+ "Milling Loot",
+ "Pickpocketing Loot",
+ "Prospecting Loot",
+ "Reference Loot",
+ "Skinning Loot",
+ "Spell Loot",
+ "Spell Impl. Target",
+ "Gossip Menu",
+ "Gossip Menu Option",
+ "Creature Vehicle",
+ "Spell Expl. Target",
+ "Spell Click Event",
+ "Quest Accept",
+ "Quest Show Mark",
+ "Vehicle Spell",
+ "SmartScript",
+ "Npc Vendor",
+ "Spell Proc",
+ "Phase Def"
+};
+
+ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
+{
+ { "None", false, false, false },
+ { "Aura", true, true, true },
+ { "Item Stored", true, true, true },
+ { "Item Equipped", true, false, false },
+ { "Zone", true, false, false },
+ { "Reputation", true, true, false },
+ { "Team", true, false, false },
+ { "Skill", true, true, false },
+ { "Quest Rewarded", true, false, false },
+ { "Quest Taken", true, false, false },
+ { "Drunken", true, false, false },
+ { "WorldState", true, true, false },
+ { "Active Event", true, false, false },
+ { "Instance Info", true, true, true },
+ { "Quest None", true, false, false },
+ { "Class", true, false, false },
+ { "Race", true, false, false },
+ { "Achievement", true, false, false },
+ { "Title", true, false, false },
+ { "SpawnMask", true, false, false },
+ { "Gender", true, false, false },
+ { "Unit State", true, false, false },
+ { "Map", true, false, false },
+ { "Area", true, false, false },
+ { "CreatureType", true, false, false },
+ { "Spell Known", true, false, false },
+ { "PhaseMask", true, false, false },
+ { "Level", true, true, false },
+ { "Quest Completed", true, false, false },
+ { "Near Creature", true, true, false },
+ { "Near GameObject", true, true, false },
+ { "Object Entry or Guid", true, true, true },
+ { "Object TypeMask", true, false, false },
+ { "Relation", true, true, false },
+ { "Reaction", true, true, false },
+ { "Distance", true, true, true },
+ { "Alive", false, false, false },
+ { "Health Value", true, true, false },
+ { "Health Pct", true, true, false }
+};
+
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
bool Condition::Meets(ConditionSourceInfo& sourceInfo)
@@ -38,7 +111,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
// object not present, return false
if (!object)
{
- TC_LOG_DEBUG("condition", "Condition object not found for condition (Entry: %u Type: %u Group: %u)", SourceEntry, SourceType, SourceGroup);
+ TC_LOG_DEBUG("condition", "Condition object not found for %s", ToString().c_str());
return false;
}
bool condMeets = false;
@@ -535,6 +608,34 @@ uint32 Condition::GetMaxAvailableConditionTargets()
}
}
+std::string Condition::ToString(bool ext /*= false*/) const
+{
+ std::ostringstream ss;
+ ss << "[Condition ";
+ ss << "SourceType: " << SourceType;
+ if (SourceType < CONDITION_SOURCE_TYPE_MAX)
+ ss << " (" << ConditionMgr::StaticSourceTypeData[SourceType] << ")";
+ else
+ ss << " (Unknown)";
+ if (ConditionMgr::CanHaveSourceGroupSet(SourceType))
+ ss << ", SourceGroup: " << SourceGroup;
+ ss << ", SourceEntry: " << SourceEntry;
+ if (ConditionMgr::CanHaveSourceIdSet(SourceType))
+ ss << ", SourceId: " << SourceId;
+
+ if (ext)
+ {
+ ss << ", ConditionType: " << ConditionType;
+ if (ConditionType < CONDITION_MAX)
+ ss << " (" << ConditionMgr::StaticConditionTypeData[ConditionType].Name << ")";
+ else
+ ss << " (Unknown)";
+ }
+
+ ss << "]";
+ return ss.str();
+}
+
ConditionMgr::ConditionMgr() { }
ConditionMgr::~ConditionMgr()
@@ -597,7 +698,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
std::map<uint32, bool> ElseGroupStore;
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
- TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1);
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", (*i)->ToString().c_str(), (*i)->ConditionValue1);
if ((*i)->isLoaded())
{
//! Find ElseGroup in ElseGroupStore
@@ -618,8 +719,8 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
}
else
{
- TC_LOG_DEBUG("condition", "IsPlayerMeetToConditionList: Reference template -%u not found",
- (*i)->ReferenceId);//checked at loading, should never happen
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s Reference template -%u not found",
+ (*i)->ToString().c_str(), (*i)->ReferenceId); // checked at loading, should never happen
}
}
@@ -658,7 +759,7 @@ bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, Con
return IsObjectMeetToConditionList(sourceInfo, conditions);
}
-bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
+bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
{
return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
@@ -681,7 +782,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
}
-bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const
+bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
{
return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
}
@@ -715,7 +816,7 @@ ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, u
if (i != (*itr).second.end())
{
cond = (*i).second;
- TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
+ TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId);
}
}
return cond;
@@ -747,7 +848,7 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32
if (i != (*itr).second.end())
{
cond = (*i).second;
- TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d event_id %u", entryOrGuid, eventId);
+ TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d eventId %u", entryOrGuid, eventId);
}
}
return cond;
@@ -895,26 +996,26 @@ void ConditionMgr::LoadConditions(bool isReload)
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
{
- TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceGroup = %u!", cond->ToString().c_str(), cond->SourceGroup);
delete cond;
continue;
}
if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
{
- TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId);
+ TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceId = %u!", cond->ToString().c_str(), cond->SourceId);
delete cond;
continue;
}
if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL)
{
- TC_LOG_ERROR("sql.sql", "Condition type %u entry %i can't have ErrorType (%u), set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorType);
+ TC_LOG_ERROR("sql.sql", "%s can't have ErrorType (%u), set to 0!", cond->ToString().c_str(), cond->ErrorType);
cond->ErrorType = 0;
}
if (cond->ErrorTextId && !cond->ErrorType)
{
- TC_LOG_ERROR("sql.sql", "Condition type %u entry %i has any ErrorType, ErrorTextId (%u) is set, set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorTextId);
+ TC_LOG_ERROR("sql.sql", "%s has any ErrorType, ErrorTextId (%u) is set, set to 0!", cond->ToString().c_str(), cond->ErrorTextId);
cond->ErrorTextId = 0;
}
@@ -1005,7 +1106,7 @@ void ConditionMgr::LoadConditions(bool isReload)
if (!valid)
{
- TC_LOG_ERROR("sql.sql", "Not handled grouped condition, SourceGroup %u", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s Not handled grouped condition.", cond->ToString().c_str());
delete cond;
}
else
@@ -1038,21 +1139,20 @@ void ConditionMgr::LoadConditions(bool isReload)
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
-
}
bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot)
{
if (!loot)
{
- TC_LOG_ERROR("sql.sql", "ConditionMgr: LootTemplate %u not found", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s LootTemplate %u not found.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
if (loot->addConditionItem(cond))
return true;
- TC_LOG_ERROR("sql.sql", "ConditionMgr: Item %u not found in LootTemplate %u", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s Item %u not found in LootTemplate %u.", cond->ToString().c_str(), cond->SourceEntry, cond->SourceGroup);
return false;
}
@@ -1072,7 +1172,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond)
}
}
- TC_LOG_ERROR("sql.sql", "addToGossipMenus: GossipMenu %u not found", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s GossipMenu %u not found.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
@@ -1091,7 +1191,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond)
}
}
- TC_LOG_ERROR("sql.sql", "addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->SourceGroup, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s GossipMenuId %u Item %u not found.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry);
return false;
}
@@ -1116,12 +1216,12 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
continue;
// build new shared mask with found effect
- uint32 sharedMask = (1<<i);
+ uint32 sharedMask = (1 << i);
ConditionList* cmp = spellInfo->Effects[i].ImplicitTargetConditions;
for (uint8 effIndex = i+1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
if (spellInfo->Effects[effIndex].ImplicitTargetConditions == cmp)
- sharedMask |= 1<<effIndex;
+ sharedMask |= 1 << effIndex;
}
sharedMasks.push_back(sharedMask);
}
@@ -1148,8 +1248,8 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
// we have overlapping masks in db
if (conditionEffMask != *itr)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
- "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
+ "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
}
@@ -1182,7 +1282,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->SourceType));
+ TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1192,7 +1292,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Creature.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1200,7 +1300,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1209,7 +1309,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Disenchant.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1217,7 +1317,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1226,7 +1326,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Fishing.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1234,7 +1334,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1243,7 +1343,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Gameobject.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1251,7 +1351,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1260,7 +1360,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Item.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1268,7 +1368,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1277,7 +1377,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Mail.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1285,7 +1385,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1294,7 +1394,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Milling.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1302,7 +1402,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1311,7 +1411,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Pickpocketing.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1319,7 +1419,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1328,7 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Prospecting.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1336,7 +1436,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1345,7 +1445,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Reference.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1353,7 +1453,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1362,7 +1462,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Skinning.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1370,7 +1470,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1379,7 +1479,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Spell.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1387,7 +1487,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1397,13 +1497,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, SourceEntry does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set, ignoring.", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup (spell effectMask) set, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1411,7 +1511,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (!((1<<i) & cond->SourceGroup))
+ if (!((1 << i) & cond->SourceGroup))
continue;
switch (spellInfo->Effects[i].TargetA.GetSelectionCategory())
@@ -1435,7 +1535,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
- cond->SourceGroup &= ~(1<<i);
+ cond->SourceGroup &= ~(1 << i);
}
// all effects were removed, no need to add the condition at all
if (!cond->SourceGroup)
@@ -1446,7 +1546,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1457,48 +1557,42 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
if (!spellProto)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
}
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT:
- if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
- {
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->SourceEntry);
- return false;
- }
- break;
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK:
if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry specifies non-existing quest, skipped.", cond->ToString().c_str());
return false;
}
break;
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1506,13 +1600,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!itemTemplate)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1537,13 +1631,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX)
{
- TC_LOG_ERROR("sql.sql", "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->ConditionType), cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str());
return false;
}
if (cond->ConditionTarget >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->ToString(true).c_str());
return false;
}
@@ -1553,17 +1647,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Aura condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 > EFFECT_2)
{
- TC_LOG_ERROR("sql.sql", "Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing effect index (%u) (must be 0..2), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Aura condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ITEM:
@@ -1571,13 +1663,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
if (!proto)
{
- TC_LOG_ERROR("sql.sql", "Item condition has non existing item (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (!cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "Item condition has 0 set for item count in value2 (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s Zero item count in ConditionValue2, skipped.", cond->ToString(true).c_str());
return false;
}
break;
@@ -1587,14 +1679,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
if (!proto)
{
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has non existing item (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ZONEID:
@@ -1602,20 +1689,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1);
if (!areaEntry)
{
- TC_LOG_ERROR("sql.sql", "ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Area (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (areaEntry->zone != 0)
{
- TC_LOG_ERROR("sql.sql", "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s requires to be in area (%u) which is a subzone but zone expected, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_REPUTATION_RANK:
@@ -1623,25 +1705,18 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1);
if (!factionEntry)
{
- TC_LOG_ERROR("sql.sql", "Reputation condition has non existing faction (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing faction (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Reputation condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_TEAM:
{
if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE)
{
- TC_LOG_ERROR("sql.sql", "Team condition specifies unknown team (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s specifies unknown team (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Team condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Team condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_SKILL:
@@ -1649,17 +1724,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1);
if (!pSkill)
{
- TC_LOG_ERROR("sql.sql", "Skill condition specifies non-existing skill (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s specifies non-existing skill (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue())
{
- TC_LOG_ERROR("sql.sql", "Skill condition specifies skill (%u) with invalid value (%u), skipped", cond->ConditionValue1, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s specifies skill (%u) with invalid value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1, cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Skill condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_QUESTREWARDED:
@@ -1669,30 +1742,19 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Quest condition (Type: %u) points to non-existing quest (%u) for Source Entry %u. SourceGroup: %u, SourceTypeOrReferenceId: %u",
- cond->ConditionType, cond->ConditionValue1, cond->SourceEntry, cond->SourceGroup, cond->SourceType);
+ TC_LOG_ERROR("sql.sql", "%s points to non-existing quest (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2 > 1)
- TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ACTIVE_EVENT:
{
GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
- if (cond->ConditionValue1 >=events.size() || !events[cond->ConditionValue1].isValid())
+ if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid())
{
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has non existing event id (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing event id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ACHIEVEMENT:
@@ -1700,56 +1762,36 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1);
if (!achievement)
{
- TC_LOG_ERROR("sql.sql", "Achivement condition has non existing achivement id (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing achivement id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_CLASS:
{
if (!(cond->ConditionValue1 & CLASSMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Class condition has non existing classmask (%u), skipped", cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
+ TC_LOG_ERROR("sql.sql", "%s has non existing classmask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Class condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Class condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_RACE:
{
if (!(cond->ConditionValue1 & RACEMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Race condition has non existing racemask (%u), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
+ TC_LOG_ERROR("sql.sql", "%s has non existing racemask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Race condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Race condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_GENDER:
{
if (!Player::IsValidGender(uint8(cond->ConditionValue1)))
{
- TC_LOG_ERROR("sql.sql", "Gender condition has invalid gender (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid gender (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_MAPID:
@@ -1757,77 +1799,54 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1);
if (!me)
{
- TC_LOG_ERROR("sql.sql", "Map condition has non existing map (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing map (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Map condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Map condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_SPELL:
{
if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Spell condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value2 (%u)!", cond->ConditionValue1, cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value3 (%u)!", cond->ConditionValue1, cond->ConditionValue3);
break;
}
case CONDITION_LEVEL:
{
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Level condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Level condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_DRUNKENSTATE:
{
if (cond->ConditionValue1 > DRUNKEN_SMASHED)
{
- TC_LOG_ERROR("sql.sql", "DrunkState condition has invalid state (%u), skipped", cond->ConditionValue1);
- return false;
- }
- if (cond->ConditionValue2)
- {
- TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value2 (%u)!", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid state (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_NEAR_CREATURE:
{
if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "NearCreature condition has non existing creature template entry (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "NearCreature condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_NEAR_GAMEOBJECT:
{
if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "NearGameObject condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString().c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_OBJECT_ENTRY_GUID:
@@ -1837,7 +1856,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_UNIT:
if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2))
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature template entry (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
@@ -1846,13 +1865,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match creature entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2);
return false;
}
}
else
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature guid (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
}
@@ -1860,7 +1879,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_GAMEOBJECT:
if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2))
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
@@ -1869,13 +1888,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue2 && goData->id != cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match gameobject entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match gameobject entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2);
return false;
}
}
else
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject guid (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
}
@@ -1883,12 +1902,12 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_PLAYER:
case TYPEID_CORPSE:
if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value2 (%u)!", cond->ConditionValue2);
+ LogUselessConditionValue(cond, 2, cond->ConditionValue2);
if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value3 (%u)!", cond->ConditionValue3);
+ LogUselessConditionValue(cond, 3, cond->ConditionValue3);
break;
default:
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has wrong typeid set (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has wrong typeid set (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -1897,51 +1916,45 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!cond->ConditionValue1 || (cond->ConditionValue1 & ~(TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE)))
{
- TC_LOG_ERROR("sql.sql", "TypeMask condition has invalid typemask set (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid typemask set (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_RELATION_TO:
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 >= RELATION_MAX)
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(RelationType) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "RelationTo condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_REACTION_TO:
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (!cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(rankMask) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
break;
@@ -1950,78 +1963,55 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue3 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ComparisionType (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
break;
}
- case CONDITION_ALIVE:
- {
- if (cond->ConditionValue1)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value1 (%u)!", cond->ConditionValue1);
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value3 (%u)!", cond->ConditionValue3);
- break;
- }
case CONDITION_HP_VAL:
{
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "HpVal condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "HpVal condition has useless data in value3 (%u)!", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has useless data in value3 (%u)!", cond->ToString(true).c_str(), cond->ConditionValue3);
break;
}
case CONDITION_HP_PCT:
{
if (cond->ConditionValue1 > 100)
{
- TC_LOG_ERROR("sql.sql", "HpPct condition has too big percent value (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has too big percent value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "HpPct condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "HpPct condition has useless data in value3 (%u)!", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has useless data in value3 (%u)!", cond->ToString().c_str(), cond->ConditionValue3);
break;
}
- case CONDITION_AREAID:
- case CONDITION_INSTANCE_INFO:
- break;
case CONDITION_WORLD_STATE:
{
if (!sWorld->getWorldState(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing world state in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3);
- break;
- }
- case CONDITION_PHASEMASK:
- {
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_TITLE:
@@ -2029,7 +2019,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1);
if (!titleEntry)
{
- TC_LOG_ERROR("sql.sql", "Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing title in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2038,7 +2028,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue1 > SPAWNMASK_RAID_ALL)
{
- TC_LOG_ERROR("sql.sql", "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing SpawnMask in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2047,7 +2037,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!(cond->ConditionValue1 & UNIT_STATE_ALL_STATE_SUPPORTED))
{
- TC_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing UnitState in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2056,17 +2046,35 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!cond->ConditionValue1 || cond->ConditionValue1 > CREATURE_TYPE_GAS_CLOUD)
{
- TC_LOG_ERROR("sql.sql", "CreatureType condition has non existing CreatureType in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing CreatureType in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
}
+ case CONDITION_INSTANCE_INFO:
+ case CONDITION_AREAID:
+ case CONDITION_PHASEMASK:
+ case CONDITION_ALIVE:
+ break;
default:
break;
}
+
+ if (cond->ConditionValue1 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue1)
+ LogUselessConditionValue(cond, 1, cond->ConditionValue1);
+ if (cond->ConditionValue2 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue2)
+ LogUselessConditionValue(cond, 2, cond->ConditionValue2);
+ if (cond->ConditionValue3 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue3)
+ LogUselessConditionValue(cond, 3, cond->ConditionValue3);
+
return true;
}
+void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32 value)
+{
+ TC_LOG_ERROR("sql.sql", "%s has useless data in ConditionValue%u (%u)!", cond->ToString(true).c_str(), index, value);
+}
+
void ConditionMgr::Clean()
{
for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 24e44c662ba..621da355b7b 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -210,6 +210,8 @@ struct Condition
uint32 GetSearcherTypeMaskForCondition();
bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; }
uint32 GetMaxAvailableConditionTargets();
+
+ std::string ToString(bool ext = false) const; /// For logging purpose
};
typedef std::list<Condition*> ConditionList;
@@ -228,7 +230,6 @@ class ConditionMgr
~ConditionMgr();
public:
-
static ConditionMgr* instance()
{
static ConditionMgr instance;
@@ -243,14 +244,24 @@ class ConditionMgr
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
- bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const;
- bool CanHaveSourceIdSet(ConditionSourceType sourceType) const;
+ static bool CanHaveSourceGroupSet(ConditionSourceType sourceType);
+ static bool CanHaveSourceIdSet(ConditionSourceType sourceType);
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId);
+ struct ConditionTypeInfo
+ {
+ char const* Name;
+ bool HasConditionValue1;
+ bool HasConditionValue2;
+ bool HasConditionValue3;
+ };
+ static char const* StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
+ static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX];
+
private:
bool isSourceTypeValid(Condition* cond);
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
@@ -259,6 +270,8 @@ class ConditionMgr
bool addToSpellImplicitTargetConditions(Condition* cond);
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
+ static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value);
+
void Clean(); // free up resources
std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 4ffddde021c..6702815870f 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -607,7 +607,7 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin
for (uint32 index = 0; index < count; ++index)
{
- m_uint32Values[startOffset + index] = atol(tokens[index]);
+ m_uint32Values[startOffset + index] = atoul(tokens[index]);
_changesMask.SetBit(startOffset + index);
}
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8a45c1c6420..b8abc33f675 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -203,7 +203,7 @@ void PlayerTaxi::LoadTaxiMask(std::string const &data)
for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index)
{
// load and set bits only for existing taxi nodes
- m_taximask[index] = sTaxiNodesMask[index] & uint32(atol(*iter));
+ m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter);
}
}
@@ -229,7 +229,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint3
for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter)
{
- uint32 node = uint32(atol(*iter));
+ uint32 node = atoul(*iter);
AddTaxiDestination(node);
}
@@ -15483,12 +15483,13 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
void Player::FailQuest(uint32 questId)
{
- // Already complete quests shouldn't turn failed.
- if (GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
- return;
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
+ // Already complete quests shouldn't turn failed.
+ if (GetQuestStatus(questId) == QUEST_STATUS_COMPLETE && !quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
+ return;
+
SetQuestStatus(questId, QUEST_STATUS_FAILED);
uint16 log_slot = FindQuestSlot(questId);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9a4b7a347c8..beac32b0145 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -13852,7 +13852,7 @@ void CharmInfo::LoadPetActionBar(const std::string& data)
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
ActiveStates type = ActiveStates(atol(*iter));
++iter;
- uint32 action = uint32(atol(*iter));
+ uint32 action = atoul(*iter);
PetActionBar[index].SetActionAndType(action, type);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 9e31e901189..8dc117b3362 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -556,17 +556,17 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
+ SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr));
if (!AdditionalSpellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr));
continue;
}
if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr));
- creatureAddon.auras[i++] = uint32(atol(*itr));
+ creatureAddon.auras[i++] = atoul(*itr);
}
if (creatureAddon.mount)
@@ -1004,17 +1004,17 @@ void ObjectMgr::LoadCreatureAddons()
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
+ SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr));
if (!AdditionalSpellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has wrong spell %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr));
continue;
}
if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr));
- creatureAddon.auras[i++] = uint32(atol(*itr));
+ creatureAddon.auras[i++] = atoul(*itr);
}
if (creatureAddon.mount)
@@ -5673,35 +5673,32 @@ void ObjectMgr::LoadAreaTriggerScripts()
uint32 oldMSTime = getMSTime();
_areaTriggerScriptStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
+ QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty.");
return;
}
- uint32 count = 0;
-
do
{
- ++count;
-
Field* fields = result->Fetch();
- uint32 Trigger_ID = fields[0].GetUInt32();
- const char *scriptName = fields[1].GetCString();
+ uint32 triggerId = fields[0].GetUInt32();
+ char const* scriptName = fields[1].GetCString();
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(triggerId);
if (!atEntry)
{
- TC_LOG_ERROR("sql.sql", "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
+ TC_LOG_ERROR("sql.sql", "AreaTrigger (ID: %u) does not exist in `AreaTrigger.dbc`.", triggerId);
continue;
}
- _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
- } while (result->NextRow());
+ _areaTriggerScriptStore[triggerId] = GetScriptId(scriptName);
+ }
+ while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u areatrigger scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " areatrigger scripts in %u ms", _areaTriggerScriptStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 team)
@@ -8544,31 +8541,32 @@ void ObjectMgr::LoadScriptNames()
{
uint32 oldMSTime = getMSTime();
- _scriptNamesStore.push_back("");
+ _scriptNamesStore.emplace_back("");
+
QueryResult result = WorldDatabase.Query(
- "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
+ "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
if (!result)
{
@@ -8576,20 +8574,23 @@ void ObjectMgr::LoadScriptNames()
return;
}
- uint32 count = 1;
-
do
{
- _scriptNamesStore.push_back((*result)[0].GetString());
- ++count;
+ _scriptNamesStore.emplace_back((*result)[0].GetCString());
}
while (result->NextRow());
std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
- TC_LOG_INFO("server.loading", ">> Loaded %d Script Names in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+
+#ifdef SCRIPTS
+ for (size_t i = 1; i < _scriptNamesStore.size(); ++i)
+ UnusedScriptNames.push_back(_scriptNamesStore[i]);
+#endif
+
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " ScriptNames in %u ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
-uint32 ObjectMgr::GetScriptId(const char *name)
+uint32 ObjectMgr::GetScriptId(char const* name)
{
// use binary search to find the script name in the sorted vector
// assume "" is the first element
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 62303143202..7504f03868e 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -1253,9 +1253,8 @@ class ObjectMgr
bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
void LoadScriptNames();
- ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; }
- const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
- uint32 GetScriptId(const char *name);
+ char const* GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
+ uint32 GetScriptId(char const* name);
SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
{
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 18cd5d5bd06..7e218b601e0 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -2004,7 +2004,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
for (uint32 index = 0; index < ktcount; ++index)
- knownTitles[index] = atol(tokens[index]);
+ knownTitles[index] = atoul(tokens[index]);
for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it)
{
diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index 1e6dc1adbb9..9bee32a95e6 100644
--- a/src/server/game/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
@@ -42,14 +42,6 @@ enum CharterItemIDs
ARENA_TEAM_CHARTER_5v5 = 23562
};
-enum CharterCosts
-{
- GUILD_CHARTER_COST = 1000,
- ARENA_TEAM_CHARTER_2v2_COST = 800000,
- ARENA_TEAM_CHARTER_3v3_COST = 1200000,
- ARENA_TEAM_CHARTER_5v5_COST = 2000000
-};
-
void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
@@ -106,7 +98,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
return;
charterid = GUILD_CHARTER;
- cost = GUILD_CHARTER_COST;
+ cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
type = GUILD_CHARTER_TYPE;
}
else
@@ -122,17 +114,17 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
{
case 1:
charterid = ARENA_TEAM_CHARTER_2v2;
- cost = ARENA_TEAM_CHARTER_2v2_COST;
+ cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
type = ARENA_TEAM_CHARTER_2v2_TYPE;
break;
case 2:
charterid = ARENA_TEAM_CHARTER_3v3;
- cost = ARENA_TEAM_CHARTER_3v3_COST;
+ cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
type = ARENA_TEAM_CHARTER_3v3_TYPE;
break;
case 3:
charterid = ARENA_TEAM_CHARTER_5v5;
- cost = ARENA_TEAM_CHARTER_5v5_COST;
+ cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
type = ARENA_TEAM_CHARTER_5v5_TYPE;
break;
default:
@@ -945,7 +937,7 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid)
data << uint32(1); // index
data << uint32(GUILD_CHARTER); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(GUILD_CHARTER_COST); // charter cost
+ data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); // charter cost
data << uint32(0); // unknown
data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
}
@@ -956,21 +948,21 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid)
data << uint32(1); // index
data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost
+ data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2)); // charter cost
data << uint32(2); // unknown
data << uint32(2); // required signs?
// 3v3
data << uint32(2); // index
data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost
+ data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3)); // charter cost
data << uint32(3); // unknown
data << uint32(3); // required signs?
// 5v5
data << uint32(3); // index
data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
- data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost
+ data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5)); // charter cost
data << uint32(5); // unknown
data << uint32(5); // required signs?
}
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 4b032199604..8949b161e7b 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -676,7 +676,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
- if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam())
+ if (pOther->GetTeam() != _player->GetTeam() &&
+ (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) &&
+ !GetPlayer()->GetSession()->HasPermission(rbac::RBAC_PERM_ALLOW_TWO_SIDE_TRADE)))
{
info.Status = TRADE_STATUS_WRONG_FACTION;
SendTradeStatus(info);
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 88ee153423f..77d3d3ffe0b 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -128,7 +128,7 @@ void InstanceScript::LoadObjectData(ObjectData const* creatureData, ObjectData c
if (gameObjectData)
LoadObjectData(gameObjectData, _gameObjectInfo);
- TC_LOG_ERROR("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size());
+ TC_LOG_DEBUG("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size());
}
void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objectInfo)
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 2e859a7a56f..33d93ee1384 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -56,12 +56,12 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
Trinity::NormalizeMapCoord(destX);
Trinity::NormalizeMapCoord(destY);
- travelDistZ = distanceX*distanceX + distanceY*distanceY;
+ travelDistZ = range; // sin^2+cos^2=1, so travelDistZ=range^2; no need for sqrt below
if (is_air_ok) // 3D system above ground and above water (flying mode)
{
// Limit height change
- const float distanceZ = float(rand_norm()) * std::sqrt(travelDistZ)/2.0f;
+ const float distanceZ = float(rand_norm()) * travelDistZ/2.0f;
destZ = respZ + distanceZ;
float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);
@@ -73,7 +73,7 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
else // 2D only
{
// 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
- travelDistZ = travelDistZ >= 100.0f ? 10.0f : std::sqrt(travelDistZ);
+ travelDistZ = travelDistZ >= 10.0f ? 10.0f : travelDistZ;
// The fastest way to get an accurate result 90% of the time.
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index be0bf1aa067..d1ebcba118d 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -34,6 +34,12 @@
#include "WorldPacket.h"
#include "WorldSession.h"
+// namespace
+// {
+ UnusedScriptContainer UnusedScripts;
+ UnusedScriptNamesContainer UnusedScriptNames;
+// }
+
// This is the global static registry of scripts.
template<class TScript>
class ScriptRegistry
@@ -89,6 +95,12 @@ class ScriptRegistry
{
ScriptPointerList[id] = script;
sScriptMgr->IncrementScriptCount();
+
+ #ifdef SCRIPTS
+ UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName());
+ if (itr != UnusedScriptNames.end() && *itr == script->GetName())
+ UnusedScriptNames.erase(itr);
+ #endif
}
else
{
@@ -106,8 +118,7 @@ class ScriptRegistry
// Avoid calling "delete script;" because we are currently in the script constructor
// In a valid scenario this will not happen because every script has a name assigned in the database
- // If that happens, it's acceptable to just leak a few bytes
-
+ UnusedScripts.push_back(script);
return;
}
}
@@ -189,6 +200,15 @@ void ScriptMgr::Initialize()
FillSpellSummary();
AddScripts();
+#ifdef SCRIPTS
+ for (std::string const& scriptName : UnusedScriptNames)
+ {
+ TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, but no core script found!", scriptName.c_str());
+ }
+#endif
+
+ UnloadUnusedScripts();
+
TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
}
@@ -229,10 +249,19 @@ void ScriptMgr::Unload()
#undef SCR_CLEAR
+ UnloadUnusedScripts();
+
delete[] SpellSummary;
delete[] UnitAI::AISpellInfo;
}
+void ScriptMgr::UnloadUnusedScripts()
+{
+ for (size_t i = 0; i < UnusedScripts.size(); ++i)
+ delete UnusedScripts[i];
+ UnusedScripts.clear();
+}
+
void ScriptMgr::LoadDatabase()
{
sScriptSystemMgr->LoadScriptWaypoints();
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index f6e76763f95..6a4e2f9910a 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -873,6 +873,15 @@ class GroupScript : public ScriptObject
// Placed here due to ScriptRegistry::AddScript dependency.
#define sScriptMgr ScriptMgr::instance()
+// namespace
+// {
+ typedef std::vector<ScriptObject*> UnusedScriptContainer;
+ typedef std::list<std::string> UnusedScriptNamesContainer;
+
+ extern UnusedScriptContainer UnusedScripts;
+ extern UnusedScriptNamesContainer UnusedScriptNames;
+// }
+
// Manages registration, loading, and execution of scripts.
class ScriptMgr
{
@@ -901,6 +910,7 @@ class ScriptMgr
public: /* Unloading */
void Unload();
+ void UnloadUnusedScripts();
public: /* SpellScriptLoader */
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 69297d32105..609617f0478 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -284,11 +284,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
{
- if (!AntiDOS.EvaluateOpcode(*packet, currentTime))
- {
- KickPlayer();
- }
- else if (packet->GetOpcode() >= NUM_MSG_TYPES)
+ if (packet->GetOpcode() >= NUM_MSG_TYPES)
{
TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
, GetPlayerInfo().c_str());
@@ -320,7 +316,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
"Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str());
}
}
- else if (_player->IsInWorld())
+ else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
{
sScriptMgr->OnPacketReceive(this, *packet);
(this->*opHandle.handler)(*packet);
@@ -332,7 +328,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
"the player has not logged in yet and not recently logout");
- else
+ else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
{
// not expected _player or must checked in packet handler
sScriptMgr->OnPacketReceive(this, *packet);
@@ -345,7 +341,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
else if (_player->IsInWorld())
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
- else
+ else if(AntiDOS.EvaluateOpcode(*packet, currentTime))
{
sScriptMgr->OnPacketReceive(this, *packet);
(this->*opHandle.handler)(*packet);
@@ -365,9 +361,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (packet->GetOpcode() == CMSG_CHAR_ENUM)
m_playerRecentlyLogout = false;
- sScriptMgr->OnPacketReceive(this, *packet);
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
+ if (AntiDOS.EvaluateOpcode(*packet, currentTime))
+ {
+ sScriptMgr->OnPacketReceive(this, *packet);
+ (this->*opHandle.handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
break;
case STATUS_NEVER:
TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
@@ -1262,8 +1261,11 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co
case POLICY_LOG:
return true;
case POLICY_KICK:
+ {
TC_LOG_INFO("network", "AntiDOS: Player kicked!");
+ Session->KickPlayer();
return false;
+ }
case POLICY_BAN:
{
BanMode bm = (BanMode)sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANMODE);
@@ -1277,7 +1279,7 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co
}
sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
TC_LOG_INFO("network", "AntiDOS: Player automatically banned for %u seconds.", duration);
-
+ Session->KickPlayer();
return false;
}
default: // invalid policy
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 311182291c5..e8e1bbd8ff4 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3438,7 +3438,7 @@ void Spell::SendSpellCooldown()
{
// Handle pet cooldowns here if needed instead of in PetAI to avoid hidden cooldown restarts
Creature* _creature = m_caster->ToCreature();
- if (_creature && _creature->IsPet())
+ if (_creature && (_creature->IsPet() || _creature->IsGuardian()))
_creature->AddCreatureSpellCooldown(m_spellInfo->Id);
return;
@@ -7043,6 +7043,19 @@ bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMo
return preventDefault;
}
+void Spell::CallScriptSuccessfulDispel(SpellEffIndex effIndex)
+{
+ for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL);
+ std::list<SpellScript::EffectHandler>::iterator hookItrEnd = (*scritr)->OnEffectSuccessfulDispel.end(), hookItr = (*scritr)->OnEffectSuccessfulDispel.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ hookItr->Call(*scritr, effIndex);
+
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
void Spell::CallScriptBeforeHitHandlers()
{
for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 6e0a5fc9d3e..c219a497eb9 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -644,6 +644,7 @@ class Spell
SpellCastResult CallScriptCheckCastHandlers();
void PrepareScriptHitHandlers();
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode);
+ void CallScriptSuccessfulDispel(SpellEffIndex effIndex);
void CallScriptBeforeHitHandlers();
void CallScriptOnHitHandlers();
void CallScriptAfterHitHandlers();
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 8ab3a72b47e..fccdea7fde1 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -310,6 +310,10 @@ bool SpellScript::_Validate(SpellInfo const* entry)
if (!(*itr).GetAffectedEffectsMask(entry))
TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+ for (std::list<EffectHandler>::iterator itr = OnEffectSuccessfulDispel.begin(); itr != OnEffectSuccessfulDispel.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSuccessfulDispel` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 653ae9ab5e9..c606cb91de3 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -130,6 +130,7 @@ enum SpellScriptHookType
SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET,
SPELL_SCRIPT_HOOK_EFFECT_HIT,
SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET,
+ SPELL_SCRIPT_HOOK_EFFECT_SUCCESSFUL_DISPEL,
SPELL_SCRIPT_HOOK_BEFORE_HIT,
SPELL_SCRIPT_HOOK_HIT,
SPELL_SCRIPT_HOOK_AFTER_HIT,
@@ -292,6 +293,7 @@ class SpellScript : public _SpellScript
HookList<EffectHandler> OnEffectLaunchTarget;
HookList<EffectHandler> OnEffectHit;
HookList<EffectHandler> OnEffectHitTarget;
+ HookList<EffectHandler> OnEffectSuccessfulDispel;
#define SpellEffectFn(F, I, N) EffectHandlerFunction(&F, I, N)
// example: BeforeHit += SpellHitFn(class::function);
@@ -334,6 +336,9 @@ class SpellScript : public _SpellScript
// 11. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
// 12. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
+ // this hook is only executed after a successful dispel of any aura
+ // OnEffectSuccessfulDispel - executed just after effect successfully dispelled aura(s)
+
//
// methods allowing interaction with Spell object
//
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index 584331ad393..136f8aab22c 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -527,10 +527,10 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s
if (!changenth(line, 2, chraccount)) // characters.account update
ROLLBACK(DUMP_FILE_BROKEN);
- race = uint8(atol(getnth(line, 4).c_str()));
- playerClass = uint8(atol(getnth(line, 5).c_str()));
- gender = uint8(atol(getnth(line, 6).c_str()));
- level = uint8(atol(getnth(line, 7).c_str()));
+ race = uint8(atoul(getnth(line, 4).c_str()));
+ playerClass = uint8(atoul(getnth(line, 5).c_str()));
+ gender = uint8(atoul(getnth(line, 6).c_str()));
+ level = uint8(atoul(getnth(line, 7).c_str()));
if (name.empty())
{
// check if the original name already exists
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 47dd37936aa..de191774b77 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -692,6 +692,11 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_MIN_PET_NAME] = 2;
}
+ m_int_configs[CONFIG_CHARTER_COST_GUILD] = sConfigMgr->GetIntDefault("Guild.CharterCost", 1000);
+ m_int_configs[CONFIG_CHARTER_COST_ARENA_2v2] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.2v2", 800000);
+ m_int_configs[CONFIG_CHARTER_COST_ARENA_3v3] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.3v3", 1200000);
+ m_int_configs[CONFIG_CHARTER_COST_ARENA_5v5] = sConfigMgr->GetIntDefault("ArenaTeam.CharterCost.5v5", 2000000);
+
m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled", 0);
m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.RaceMask", 0);
m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.ClassMask", 0);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 5c97b8f5653..a02f735ed4d 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -341,6 +341,10 @@ enum WorldIntConfigs
CONFIG_BIRTHDAY_TIME,
CONFIG_CREATURE_PICKPOCKET_REFILL,
CONFIG_AHBOT_UPDATE_INTERVAL,
+ CONFIG_CHARTER_COST_GUILD,
+ CONFIG_CHARTER_COST_ARENA_2v2,
+ CONFIG_CHARTER_COST_ARENA_3v3,
+ CONFIG_CHARTER_COST_ARENA_5v5,
INT_CONFIG_VALUE_COUNT
};
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index d3d012e70d5..2eebc9cae10 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -488,7 +488,7 @@ public:
static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler* handler, char const* args)
{
- uint32 msg = atol((char*)args);
+ uint32 msg = atoul(args);
handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetSession()->GetPlayer(), msg);
return true;
}
@@ -507,7 +507,7 @@ public:
static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler* handler, char const* args)
{
- QuestFailedReason msg = static_cast<QuestFailedReason>(atol((char*)args));
+ QuestFailedReason msg = static_cast<QuestFailedReason>(atoul(args));
handler->GetSession()->GetPlayer()->SendCanTakeQuestResponse(msg);
return true;
}
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index f3ddc6f0137..c0bf2a6bb84 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -118,7 +118,7 @@ public:
if (!id)
return false;
- uint32 objectId = atol(id);
+ uint32 objectId = atoul(id);
if (!objectId)
return false;
@@ -238,7 +238,7 @@ public:
if (!id)
return false;
- uint32 objectId = atol(id);
+ uint32 objectId = atoul(id);
if (objectId)
result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index a558d977b85..06967c69888 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -269,7 +269,7 @@ public:
const char* onlineState = "";
// Parse the guid to uint32...
- ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args)));
+ ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args)));
// ... and try to extract a player out of it.
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget))
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 0f21200c22d..b57629a577e 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -65,7 +65,7 @@ public:
if (!id)
return false;
- uint32 creatureId = atol(id);
+ uint32 creatureId = atoul(id);
if (!creatureId)
{
handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
@@ -82,7 +82,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
@@ -133,11 +133,11 @@ public:
if (!*args)
return false;
- char* id = handler->extractKeyFromLink((char*)args, "Hitem");
+ char const* id = handler->extractKeyFromLink((char*)args, "Hitem");
if (!id)
return false;
- uint32 itemId = atol(id);
+ uint32 itemId = atoul(id);
if (!itemId)
{
handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
@@ -154,7 +154,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
@@ -354,7 +354,7 @@ public:
if (!id)
return false;
- uint32 gameObjectId = atol(id);
+ uint32 gameObjectId = atoul(id);
if (!gameObjectId)
{
handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
@@ -371,7 +371,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
@@ -476,7 +476,7 @@ public:
if (!*args)
return false;
- ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args)));
+ ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args)));
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName))
{
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index a853a02bb11..331a31f6c02 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1134,7 +1134,7 @@ public:
char const* id = handler->extractKeyFromLink((char*)args, "Hitem");
if (!id)
return false;
- itemId = uint32(atol(id));
+ itemId = atoul(id);
}
char const* ccount = strtok(NULL, " ");
@@ -1216,7 +1216,7 @@ public:
if (!id)
return false;
- uint32 itemSetId = atol(id);
+ uint32 itemSetId = atoul(id);
// prevent generation all items with itemset field value '0'
if (itemSetId == 0)
@@ -1357,7 +1357,7 @@ public:
return false;
}
- int32 level = uint32(atol(levelStr));
+ int32 level = atol(levelStr);
Player* target = handler->getSelectedPlayer();
if (!target)
@@ -1379,7 +1379,7 @@ public:
// If our target does not yet have the skill they are trying to add to them, the chosen level also becomes
// the max level of the new profession.
- uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
+ uint16 max = maxPureSkill ? atoul(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
if (level <= 0 || level > max || max <= 0)
return false;
@@ -1419,7 +1419,7 @@ public:
PreparedStatement* stmt = NULL;
// To make sure we get a target, we convert our guid to an omniversal...
- ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args)));
+ ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args)));
// ... and make sure we get a target, somehow.
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName))
@@ -1780,7 +1780,7 @@ public:
uint32 totalmail = uint32(fields[1].GetUInt64());
// ... we have to convert it from Char to int. We can use totalmail as it is
- rmailint = atol(readmail.c_str());
+ rmailint = atoul(readmail.c_str());
// Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given
if (totalmail >= 1)
@@ -1978,7 +1978,7 @@ public:
static bool HandleMuteInfoHelper(uint32 accountId, char const* accountName, ChatHandler *handler)
{
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO);
- stmt->setUInt16(0, accountId);
+ stmt->setUInt32(0, accountId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 987c12debb7..1434493e948 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -326,15 +326,15 @@ public:
char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
uint32 maxcount = 0;
if (fmaxcount)
- maxcount = atol(fmaxcount);
+ maxcount = atoul(fmaxcount);
char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
uint32 incrtime = 0;
if (fincrtime)
- incrtime = atol(fincrtime);
+ incrtime = atoul(fincrtime);
char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
- uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
+ uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0;
Creature* vendor = handler->getSelectedCreature();
if (!vendor)
{
@@ -564,7 +564,7 @@ public:
handler->SetSentErrorMessage(true);
return false;
}
- uint32 itemId = atol(pitem);
+ uint32 itemId = atoul(pitem);
if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId))
{
@@ -1321,7 +1321,7 @@ public:
return false;
}
- ObjectGuid receiver_guid(HIGHGUID_PLAYER, uint32(atol(receiver_str)));
+ ObjectGuid receiver_guid(HIGHGUID_PLAYER, uint32(atoul(receiver_str)));
// check online security
Player* receiver = ObjectAccessor::FindPlayer(receiver_guid);
diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp
index fb486128049..9f7098b9134 100644
--- a/src/server/scripts/Commands/cs_quest.cpp
+++ b/src/server/scripts/Commands/cs_quest.cpp
@@ -67,7 +67,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -112,7 +112,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -165,7 +165,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -269,7 +269,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
index 58f38ec4267..860cc609c7b 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
@@ -225,7 +225,7 @@ class boss_ragnaros : public CreatureScript
events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, urand(10000, 14000));
break;
case EVENT_MAGMA_BLAST:
- if (me->IsWithinMeleeRange(me->GetVictim()))
+ if (!me->IsWithinMeleeRange(me->GetVictim()))
{
DoCastVictim(SPELL_MAGMA_BLAST);
if (!_hasYelledMagmaBurst)
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index 992b20d2580..e0416b56397 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -25,10 +25,9 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "hyjal.h"
-#include "SpellAuras.h"
-#include "hyjal_trash.h"
+#include "SpellScript.h"
#include "Player.h"
+#include "hyjal.h"
enum Texts
{
@@ -39,42 +38,59 @@ enum Texts
SAY_ENRAGE = 5,
SAY_DEATH = 6,
SAY_SOUL_CHARGE = 7,
+ // YELL_ARCHIMONDE_INTRO = 8
};
enum Spells
{
- SPELL_DENOUEMENT_WISP = 32124,
- SPELL_ANCIENT_SPARK = 39349,
- SPELL_PROTECTION_OF_ELUNE = 38528,
-
- SPELL_DRAIN_WORLD_TREE = 39140,
- SPELL_DRAIN_WORLD_TREE_2 = 39141,
-
- SPELL_FINGER_OF_DEATH = 31984,
- SPELL_HAND_OF_DEATH = 35354,
- SPELL_AIR_BURST = 32014,
- SPELL_GRIP_OF_THE_LEGION = 31972,
- SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
- SPELL_DOOMFIRE_SPAWN = 32074,
- SPELL_DOOMFIRE = 31945,
- SPELL_SOUL_CHARGE_YELLOW = 32045,
- SPELL_SOUL_CHARGE_GREEN = 32051,
- SPELL_SOUL_CHARGE_RED = 32052,
- SPELL_UNLEASH_SOUL_YELLOW = 32054,
- SPELL_UNLEASH_SOUL_GREEN = 32057,
- SPELL_UNLEASH_SOUL_RED = 32053,
- SPELL_FEAR = 31970,
+ SPELL_DENOUEMENT_WISP = 32124,
+ SPELL_ANCIENT_SPARK = 39349,
+ SPELL_PROTECTION_OF_ELUNE = 38528,
+
+ SPELL_DRAIN_WORLD_TREE = 39140,
+ SPELL_DRAIN_WORLD_TREE_TRIGGERED = 39141,
+
+ SPELL_FINGER_OF_DEATH = 31984,
+ SPELL_HAND_OF_DEATH = 35354,
+ SPELL_AIR_BURST = 32014,
+ SPELL_GRIP_OF_THE_LEGION = 31972,
+ SPELL_DOOMFIRE_STRIKE = 31903, // summons two creatures
+ SPELL_DOOMFIRE_SPAWN = 32074,
+ SPELL_DOOMFIRE = 31945,
+ SPELL_SOUL_CHARGE_YELLOW = 32045,
+ SPELL_SOUL_CHARGE_GREEN = 32051,
+ SPELL_SOUL_CHARGE_RED = 32052,
+ SPELL_UNLEASH_SOUL_YELLOW = 32054,
+ SPELL_UNLEASH_SOUL_GREEN = 32057,
+ SPELL_UNLEASH_SOUL_RED = 32053,
+ SPELL_FEAR = 31970
+};
+
+enum Events
+{
+ EVENT_HAND_OF_DEATH = 1, // Raid wiper
+ EVENT_UNLEASH_SOUL_CHARGE,
+ EVENT_FINGER_OF_DEATH,
+ EVENT_GRIP_OF_THE_LEGION,
+ EVENT_FEAR,
+ EVENT_AIR_BURST,
+ EVENT_DOOMFIRE,
+ EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
+ EVENT_SUMMON_WHISP
};
enum Summons
{
- CREATURE_DOOMFIRE = 18095,
- CREATURE_DOOMFIRE_SPIRIT = 18104,
- CREATURE_ANCIENT_WISP = 17946,
- CREATURE_CHANNEL_TARGET = 22418,
+ NPC_DOOMFIRE = 18095,
+ NPC_DOOMFIRE_SPIRIT = 18104,
+ NPC_ANCIENT_WISP = 17946
};
-Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
+enum Actions
+{
+ ACTION_ENRAGE,
+ ACTION_CHANNEL_WORLD_TREE
+};
class npc_ancient_wisp : public CreatureScript
{
@@ -200,7 +216,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
-
{
//will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
//when UpdateAI needs it, it will be forced to select randomPoint
@@ -249,409 +264,309 @@ class boss_archimonde : public CreatureScript
public:
boss_archimonde() : CreatureScript("boss_archimonde") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_archimondeAI>(creature);
- }
-
- struct boss_archimondeAI : public hyjal_trashAI
+ struct boss_archimondeAI : public BossAI
{
- boss_archimondeAI(Creature* creature) : hyjal_trashAI(creature)
+ boss_archimondeAI(Creature* creature) : BossAI(creature, DATA_ARCHIMONDE)
{
Initialize();
- instance = creature->GetInstanceScript();
}
void Initialize()
{
DoomfireSpiritGUID.Clear();
- damageTaken = 0;
- WorldTreeGUID.Clear();
-
- DrainNordrassilTimer = 0;
- FearTimer = 42000;
- AirBurstTimer = 30000;
- GripOfTheLegionTimer = urand(5000, 25000);
- DoomfireTimer = 20000;
- SoulChargeTimer = urand(2000, 30000);
+
SoulChargeCount = 0;
- MeleeRangeCheckTimer = 15000;
- HandOfDeathTimer = 2000;
WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
- EnrageTimer = 600000; // 10 minutes
- CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
- SummonWispTimer = 0;
+ _unleashSpell = 0;
+ _chargeSpell = 0;
Enraged = false;
- BelowTenPercent = false;
HasProtected = false;
- IsChanneling = false;
}
- InstanceScript* instance;
-
- ObjectGuid DoomfireSpiritGUID;
- ObjectGuid WorldTreeGUID;
-
- uint32 DrainNordrassilTimer;
- uint32 FearTimer;
- uint32 AirBurstTimer;
- uint32 GripOfTheLegionTimer;
- uint32 DoomfireTimer;
- uint32 SoulChargeTimer;
- uint8 SoulChargeCount;
- uint32 MeleeRangeCheckTimer;
- uint32 HandOfDeathTimer;
- uint32 SummonWispTimer;
- uint8 WispCount;
- uint32 EnrageTimer;
- uint32 CheckDistanceTimer;
-
- bool Enraged;
- bool BelowTenPercent;
- bool HasProtected;
- bool IsChanneling;
+ void InitializeAI() override
+ {
+ BossAI::InitializeAI();
+ DoAction(ACTION_CHANNEL_WORLD_TREE);
+ }
void Reset() override
{
- instance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
-
Initialize();
+ _Reset();
+ me->RemoveAllAuras(); // Reset Soul Charge auras.
}
void EnterCombat(Unit* /*who*/) override
{
- me->InterruptSpell(CURRENT_CHANNELED_SPELL);
Talk(SAY_AGGRO);
- DoZoneInCombat();
-
- instance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
- }
-
- void KilledUnit(Unit* victim) override
- {
- Talk(SAY_SLAY);
-
- if (victim && victim->GetTypeId() == TYPEID_PLAYER)
- GainSoulCharge(victim->ToPlayer());
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_FEAR, 42000);
+ events.ScheduleEvent(EVENT_AIR_BURST, 30000);
+ events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000));
+ events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 15000);
+ events.ScheduleEvent(EVENT_HAND_OF_DEATH, 600000);
+ events.ScheduleEvent(EVENT_DISTANCE_CHECK, 30000);
}
- void GainSoulCharge(Player* victim)
+ void ExecuteEvent(uint32 eventId) override
{
- switch (victim->getClass())
+ switch (eventId)
{
- case CLASS_PRIEST:
- case CLASS_PALADIN:
- case CLASS_WARLOCK:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
+ case EVENT_HAND_OF_DEATH:
+ DoCastAOE(SPELL_HAND_OF_DEATH);
+ events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000);
+ break;
+ case EVENT_UNLEASH_SOUL_CHARGE:
+ _chargeSpell = 0;
+ _unleashSpell = 0;
+ me->InterruptNonMeleeSpells(false);
+ switch (urand(0, 2))
+ {
+ case 0:
+ _chargeSpell = SPELL_SOUL_CHARGE_RED;
+ _unleashSpell = SPELL_UNLEASH_SOUL_RED;
+ break;
+ case 1:
+ _chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
+ _unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
+ break;
+ case 2:
+ _chargeSpell = SPELL_SOUL_CHARGE_GREEN;
+ _unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
+ break;
+ }
+
+ if (me->HasAura(_chargeSpell))
+ {
+ me->RemoveAuraFromStack(_chargeSpell);
+ DoCastVictim(_unleashSpell);
+ SoulChargeCount--;
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ }
+ break;
+ case EVENT_FINGER_OF_DEATH:
+ if (!SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f)) // Checks if there are no targets in melee range
+ {
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 1000);
+ }
+ else
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 5000);
break;
- case CLASS_MAGE:
- case CLASS_ROGUE:
- case CLASS_WARRIOR:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
+ case EVENT_GRIP_OF_THE_LEGION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_GRIP_OF_THE_LEGION);
+ events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000));
break;
- case CLASS_DRUID:
- case CLASS_SHAMAN:
- case CLASS_HUNTER:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
+ case EVENT_AIR_BURST:
+ Talk(SAY_AIR_BURST);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_AIR_BURST); //not on tank
+ events.ScheduleEvent(EVENT_AIR_BURST, urand(25000, 40000));
+ break;
+ case EVENT_FEAR:
+ DoCastAOE(SPELL_FEAR);
+ events.ScheduleEvent(EVENT_FEAR, 42000);
+ break;
+ case EVENT_DOOMFIRE:
+ Talk(SAY_DOOMFIRE);
+ if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ SummonDoomfire(temp);
+ else
+ SummonDoomfire(me->GetVictim());
+ events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
+ break;
+ case EVENT_DISTANCE_CHECK:
+ if (Creature* channelTrigger = instance->GetCreature(DATA_CHANNEL_TARGET))
+ if (me->IsWithinDistInMap(channelTrigger, 75.0f))
+ DoAction(ACTION_ENRAGE);
+ events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000);
+ break;
+ case EVENT_SUMMON_WHISP:
+ DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ ++WispCount;
+ if (WispCount >= 30)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
+ break;
+ default:
break;
}
-
- SoulChargeTimer = urand(2000, 30000);
- ++SoulChargeCount;
- }
-
- void JustDied(Unit* killer) override
- {
- hyjal_trashAI::JustDied(killer);
- Talk(SAY_DEATH);
-
- instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
}
- bool CanUseFingerOfDeath()
+ void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
{
- // First we check if our current victim is in melee range or not.
- Unit* victim = me->GetVictim();
- if (victim && me->IsWithinDistInMap(victim, me->GetAttackDistance(victim)))
- return false;
-
- ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList();
- if (threatlist.empty())
- return false;
-
- std::list<Unit*> targets;
- ThreatContainer::StorageType::const_iterator itr = threatlist.begin();
- for (; itr != threatlist.end(); ++itr)
+ if (me->HealthBelowPctDamaged(10, damage))
{
- Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
- if (unit && unit->IsAlive())
- targets.push_back(unit);
- }
+ if (!Enraged)
+ DoAction(ACTION_ENRAGE);
- if (targets.empty())
- return false;
+ if (!HasProtected)
+ {
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
- targets.sort(Trinity::ObjectDistanceOrderPred(me));
- Unit* target = targets.front();
- if (target)
- {
- if (!me->IsWithinDistInMap(target, me->GetAttackDistance(target)))
- return true; // Cast Finger of Death
- else // This target is closest, he is our new tank
- me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim()));
+ // All members of raid must get this buff
+ DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true);
+ HasProtected = true;
+ events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
+ }
}
-
- return false;
}
- void JustSummoned(Creature* summoned) override
+ void KilledUnit(Unit* victim) override
{
- if (summoned->GetEntry() == CREATURE_ANCIENT_WISP)
- summoned->AI()->AttackStart(me);
- else
- {
- summoned->setFaction(me->getFaction());
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
- {
- DoomfireSpiritGUID = summoned->GetGUID();
- }
+ Talk(SAY_SLAY);
- if (summoned->GetEntry() == CREATURE_DOOMFIRE)
+ if (victim->GetTypeId() == TYPEID_PLAYER)
{
- summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
- summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
-
- if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
+ switch (victim->getClass())
{
- summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
- DoomfireSpiritGUID.Clear();
+ case CLASS_PRIEST:
+ case CLASS_PALADIN:
+ case CLASS_WARLOCK:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
+ break;
+ case CLASS_MAGE:
+ case CLASS_ROGUE:
+ case CLASS_WARRIOR:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
+ break;
+ case CLASS_DRUID:
+ case CLASS_SHAMAN:
+ case CLASS_HUNTER:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
+ break;
}
+
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ ++SoulChargeCount;
}
}
- //this is code doing close to what the summoning spell would do (spell 31903)
- void SummonDoomfire(Unit* target)
+ void JustReachedHome() override
{
- me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
- target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
-
- me->SummonCreature(CREATURE_DOOMFIRE,
- target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
+ DoAction(ACTION_CHANNEL_WORLD_TREE);
}
- void UnleashSoulCharge()
+ void JustDied(Unit* /*killer*/) override
{
- me->InterruptNonMeleeSpells(false);
-
- bool HasCast = false;
- uint32 chargeSpell = 0;
- uint32 unleashSpell = 0;
+ Talk(SAY_DEATH);
+ _JustDied();
+ // @todo: remove this when instance script gets updated, kept for compatibility only
+ instance->SetData(DATA_ARCHIMONDE, DONE);
+ }
- switch (urand(0, 2))
+ void JustSummoned(Creature* summoned) override
+ {
+ switch (summoned->GetEntry())
{
- case 0:
- chargeSpell = SPELL_SOUL_CHARGE_RED;
- unleashSpell = SPELL_UNLEASH_SOUL_RED;
- break;
- case 1:
- chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
- unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
+ case NPC_ANCIENT_WISP:
+ summoned->AI()->AttackStart(me);
break;
- case 2:
- chargeSpell = SPELL_SOUL_CHARGE_GREEN;
- unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
+ case NPC_DOOMFIRE_SPIRIT:
+ DoomfireSpiritGUID = summoned->GetGUID();
break;
- }
+ case NPC_DOOMFIRE:
+ summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
+ summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
- if (me->HasAura(chargeSpell))
- {
- me->RemoveAuraFromStack(chargeSpell);
- DoCastVictim(unleashSpell);
- HasCast = true;
- SoulChargeCount--;
+ if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
+ {
+ summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
+ DoomfireSpiritGUID.Clear();
+ }
+ break;
+ default:
+ break;
}
-
- if (HasCast)
- SoulChargeTimer = urand(2000, 30000);
}
- void UpdateAI(uint32 diff) override
+ void DoAction(int32 actionId) override
{
- if (!me->IsInCombat())
+ switch (actionId)
{
- // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
- if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35)))
- {
- me->SetVisible(false);
- me->setFaction(35);
- }
- else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35)))
- {
- me->setFaction(1720);
- me->SetVisible(true);
- }
-
- if (DrainNordrassilTimer <= diff)
- {
- if (!IsChanneling)
- {
- Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
-
- if (temp)
- WorldTreeGUID = temp->GetGUID();
-
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- {
- Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Nordrassil->SetDisplayId(11686);
- DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
- IsChanneling = true;
- }
- }
-
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- {
- Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
- DrainNordrassilTimer = 1000;
- }
- } else DrainNordrassilTimer -= diff;
+ case ACTION_ENRAGE:
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
+ Enraged = true;
+ Talk(SAY_ENRAGE);
+ break;
+ case ACTION_CHANNEL_WORLD_TREE:
+ DoCastAOE(SPELL_DRAIN_WORLD_TREE, true);
+ break;
+ default:
+ break;
}
+ }
- if (!UpdateVictim())
+ //this is code doing close to what the summoning spell would do (spell 31903)
+ void SummonDoomfire(Unit* target)
+ {
+ if (!target)
return;
- if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged)
- BelowTenPercent = true;
-
- if (!Enraged)
- {
- if (EnrageTimer <= diff)
- {
- if (HealthAbovePct(10))
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
- Enraged = true;
- Talk(SAY_ENRAGE);
- }
- } else EnrageTimer -= diff;
+ me->SummonCreature(NPC_DOOMFIRE_SPIRIT,
+ target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
- if (CheckDistanceTimer <= diff)
- {
- // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
- Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
- if (Check)
- {
- Check->SetVisible(false);
-
- if (me->IsWithinDistInMap(Check, 75))
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
- Enraged = true;
- Talk(SAY_ENRAGE);
- }
- }
- CheckDistanceTimer = 5000;
- } else CheckDistanceTimer -= diff;
- }
+ me->SummonCreature(NPC_DOOMFIRE,
+ target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
+ }
- if (BelowTenPercent)
- {
- if (!HasProtected)
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
+ private:
+ ObjectGuid DoomfireSpiritGUID;
+ uint8 SoulChargeCount;
+ uint8 WispCount;
+ uint32 _chargeSpell;
+ uint32 _unleashSpell;
+ bool Enraged;
+ bool HasProtected;
+ };
- //all members of raid must get this buff
- DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true);
- HasProtected = true;
- Enraged = true;
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_archimondeAI>(creature);
+ }
+};
- if (SummonWispTimer <= diff)
- {
- DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- SummonWispTimer = 1500;
- ++WispCount;
- } else SummonWispTimer -= diff;
+// 39142 - Drain World Tree Dummy
+class spell_archimonde_drain_world_tree_dummy : public SpellScriptLoader
+{
+ public:
+ spell_archimonde_drain_world_tree_dummy() : SpellScriptLoader("spell_archimonde_drain_world_tree_dummy") { }
- if (WispCount >= 30)
- me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
+ class spell_archimonde_drain_world_tree_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_archimonde_drain_world_tree_dummy_SpellScript);
- if (Enraged)
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- if (HandOfDeathTimer <= diff)
- {
- DoCastVictim(SPELL_HAND_OF_DEATH);
- HandOfDeathTimer = 2000;
- } else HandOfDeathTimer -= diff;
- return; // Don't do anything after this point.
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRAIN_WORLD_TREE_TRIGGERED))
+ return false;
+ return true;
}
- if (SoulChargeCount)
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
- if (SoulChargeTimer <= diff)
- UnleashSoulCharge();
- else SoulChargeTimer -= diff;
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(GetCaster(), SPELL_DRAIN_WORLD_TREE_TRIGGERED, true);
}
- if (GripOfTheLegionTimer <= diff)
- {
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
- GripOfTheLegionTimer = urand(5000, 25000);
- } else GripOfTheLegionTimer -= diff;
-
- if (AirBurstTimer <= diff)
- {
- Talk(SAY_AIR_BURST);
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
- AirBurstTimer = urand(25000, 40000);
- } else AirBurstTimer -= diff;
-
- if (FearTimer <= diff)
- {
- DoCastVictim(SPELL_FEAR);
- FearTimer = 42000;
- } else FearTimer -= diff;
-
- if (DoomfireTimer <= diff)
+ void Register() override
{
- Talk(SAY_DOOMFIRE);
- Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
- if (!temp)
- temp = me->GetVictim();
-
- //replace with spell cast 31903 once implicitTarget 73 implemented
- SummonDoomfire(temp);
-
- //supposedly three doomfire can be up at the same time
- DoomfireTimer = 20000;
- } else DoomfireTimer -= diff;
-
- if (MeleeRangeCheckTimer <= diff)
- {
- if (CanUseFingerOfDeath())
- {
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
- MeleeRangeCheckTimer = 1000;
- }
-
- MeleeRangeCheckTimer = 5000;
- } else MeleeRangeCheckTimer -= diff;
+ OnEffectHitTarget += SpellEffectFn(spell_archimonde_drain_world_tree_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
- DoMeleeAttackIfReady();
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_archimonde_drain_world_tree_dummy_SpellScript();
}
- void WaypointReached(uint32 /*waypointId*/) override { }
- };
};
void AddSC_boss_archimonde()
@@ -660,4 +575,5 @@ void AddSC_boss_archimonde()
new npc_doomfire();
new npc_doomfire_targetting();
new npc_ancient_wisp();
+ new spell_archimonde_drain_world_tree_dummy();
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
index c5f4d4ae679..54a763573ed 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
@@ -44,7 +44,8 @@ enum DataTypes
DATA_HORDE_RETREAT = 17,
DATA_RAIDDAMAGE = 18,
DATA_RESET_RAIDDAMAGE = 19,
- TYPE_RETREAT = 20
+ TYPE_RETREAT = 20,
+ DATA_CHANNEL_TARGET = 21
};
enum WorldStateIds
@@ -77,7 +78,8 @@ enum CreaturesIds
KAZROGAL = 17888,
AZGALOR = 17842,
ARCHIMONDE = 17968,
- NPC_WORLD_TRIGGER_TINY = 21987
+ NPC_WORLD_TRIGGER_TINY = 21987,
+ NPC_CHANNEL_TARGET = 22418
};
enum GameobjectIds
@@ -89,5 +91,6 @@ enum GameobjectIds
GO_ROARING_FLAME = 182592
};
-#endif
+#define MINRAIDDAMAGE 700000 // minimal damage before trash can drop loot and reputation, resets if faction leader dies
+#endif
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index c6adbd58c4a..d4b4061aaa8 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -26,7 +26,6 @@ enum Spells
SPELL_METEOR = 33814, //infernal visual
SPELL_IMMOLATION = 37059,
SPELL_FLAME_BUFFET = 31724,
- NPC_TRIGGER = 21987, //World Trigger (Tiny)
MODEL_INVIS = 11686, //invisible model
SPELL_DISEASE_CLOUD = 31607,
SPELL_KNOCKDOWN = 31610,
@@ -465,10 +464,7 @@ public:
}
if (!meteor)
{
- float x, y, z;
- me->GetPosition(x, y, z);
- Creature* trigger = me->SummonCreature(NPC_TRIGGER, x + 8, y + 8, z + 25 + rand32() % 10, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1000);
- if (trigger)
+ if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_TINY, me->GetPositionWithOffset({ 8.0f, 8.0f, frand(25.0f, 35.0f), 0.0f }), TEMPSUMMON_TIMED_DESPAWN, 1000))
{
trigger->SetVisible(false);
trigger->setFaction(me->getFaction());
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
index 18122ba2b0c..62f82ebcee1 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
@@ -21,8 +21,6 @@
#include "hyjal.h"
#include "ScriptedEscortAI.h"
-#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
-
struct hyjal_trashAI : public npc_escortAI
{
hyjal_trashAI(Creature* creature);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
index 1d4a728b08b..99b8515c6e8 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
@@ -26,10 +26,7 @@ EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
-#include "hyjal_trash.h"
-#include "Player.h"
-#include "WorldPacket.h"
-#include "Chat.h"
+#include "hyjal.h"
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
@@ -39,8 +36,16 @@ EndScriptData */
4 - Archimonde event
*/
-#define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."
-#define YELL_EFFORTS_NAME "Archimonde"
+enum Yells
+{
+ YELL_ARCHIMONDE_INTRO = 8
+};
+
+ObjectData const creatureData[] =
+{
+ { NPC_CHANNEL_TARGET, DATA_CHANNEL_TARGET },
+ { 0, 0 } // END
+};
class instance_hyjal : public InstanceMapScript
{
@@ -57,6 +62,7 @@ public:
instance_mount_hyjal_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
+ LoadObjectData(creatureData, nullptr);
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
RaidDamage = 0;
@@ -104,15 +110,35 @@ public:
{
switch (creature->GetEntry())
{
- case RAGE_WINTERCHILL: RageWinterchill = creature->GetGUID(); break;
- case ANETHERON: Anetheron = creature->GetGUID(); break;
- case KAZROGAL: Kazrogal = creature->GetGUID(); break;
- case AZGALOR: Azgalor = creature->GetGUID(); break;
- case ARCHIMONDE: Archimonde = creature->GetGUID(); break;
- case JAINA: JainaProudmoore = creature->GetGUID(); break;
- case THRALL: Thrall = creature->GetGUID(); break;
- case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break;
+ case RAGE_WINTERCHILL:
+ RageWinterchill = creature->GetGUID();
+ break;
+ case ANETHERON:
+ Anetheron = creature->GetGUID();
+ break;
+ case KAZROGAL:
+ Kazrogal = creature->GetGUID();
+ break;
+ case AZGALOR:
+ Azgalor = creature->GetGUID();
+ break;
+ case ARCHIMONDE:
+ Archimonde = creature->GetGUID();
+ if (GetData(DATA_AZGALOREVENT) != DONE)
+ creature->SetVisible(false);
+ break;
+ case JAINA:
+ JainaProudmoore = creature->GetGUID();
+ break;
+ case THRALL:
+ Thrall = creature->GetGUID();
+ break;
+ case TYRANDE:
+ TyrandeWhisperwind = creature->GetGUID();
+ break;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
ObjectGuid GetGuidData(uint32 identifier) const override
@@ -146,39 +172,18 @@ public:
m_auiEncounter[2] = data;
break;
case DATA_AZGALOREVENT:
+ m_auiEncounter[3] = data;
+ if (data == DONE)
{
- m_auiEncounter[3] = data;
- if (data == DONE)
+ instance->LoadGrid(5581.49f, -3445.63f);
+ if (Creature* archimonde = instance->GetCreature(Archimonde))
{
- if (ArchiYell)
- break;
-
- ArchiYell = true;
+ archimonde->SetVisible(true);
- Creature* creature = instance->GetCreature(Azgalor);
- if (creature)
+ if (!ArchiYell)
{
- Creature* unit = creature->SummonCreature(NPC_WORLD_TRIGGER_TINY, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
-
- Map* map = creature->GetMap();
- if (map->IsDungeon() && unit)
- {
- unit->SetVisible(false);
- Map::PlayerList const &PlayerList = map->GetPlayers();
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (Player* player = i->GetSource())
- {
- WorldPacket packet;
- ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS);
- player->SendDirectMessage(&packet);
- player->PlayDirectSound(10986, player);
- }
- }
- }
+ ArchiYell = true;
+ archimonde->AI()->Talk(YELL_ARCHIMONDE_INTRO);
}
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
index b84d24d66d3..794496382c2 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
@@ -292,6 +292,7 @@ public:
break;
}
player->CLOSE_GOSSIP_MENU();
+ ai->SetDespawnAtFar(false);
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
return true;
}
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index 9f5e7bdf29d..d254cbe08fb 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -19,12 +19,11 @@
/* ScriptData
SDName: Dustwallow_Marsh
SD%Complete: 95
-SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle
+SDComment: Quest support: 558, 11126, 11142, 11174, Vendor Nat Pagle
SDCategory: Dustwallow Marsh
EndScriptData */
/* ContentData
-npc_risen_husk_spirit
npc_lady_jaina_proudmoore
npc_nat_pagle
npc_private_hendel
@@ -40,99 +39,6 @@ EndContentData */
#include "WorldSession.h"
/*######
-## npc_risen_husk_spirit
-######*/
-
-enum HauntingWitchHill
-{
- // Quest
- QUEST_WHATS_HAUNTING_WITCH_HILL = 11180,
-
- // General spells
- SPELL_SUMMON_RESTLESS_APPARITION = 42511,
- SPELL_WITCH_HILL_INFORMATION_CREDIT = 42512,
-
- // Risen Husk specific
- SPELL_CONSUME_FLESH = 37933,
- NPC_RISEN_HUSK = 23555,
-
- // Risen Spirit specific
- SPELL_INTANGIBLE_PRESENCE = 43127,
- NPC_RISEN_SPIRIT = 23554,
-
- // Events
- EVENT_CONSUME_FLESH = 1,
- EVENT_INTANGIBLE_PRESENCE = 2,
-};
-
-class npc_risen_husk_spirit : public CreatureScript
-{
- public:
- npc_risen_husk_spirit() : CreatureScript("npc_risen_husk_spirit") { }
-
- struct npc_risen_husk_spiritAI : public ScriptedAI
- {
- npc_risen_husk_spiritAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- events.Reset();
- if (me->GetEntry() == NPC_RISEN_HUSK)
- events.ScheduleEvent(EVENT_CONSUME_FLESH, 5000);
- else if (me->GetEntry() == NPC_RISEN_SPIRIT)
- events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 5000);
- }
-
- void JustDied(Unit* killer) override
- {
- if (killer->GetTypeId() == TYPEID_PLAYER)
- {
- if (killer->ToPlayer()->GetQuestStatus(QUEST_WHATS_HAUNTING_WITCH_HILL) == QUEST_STATUS_INCOMPLETE)
- {
- DoCast(me, SPELL_SUMMON_RESTLESS_APPARITION, true);
- DoCast(killer, SPELL_WITCH_HILL_INFORMATION_CREDIT, true);
- }
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_CONSUME_FLESH:
- DoCastVictim(SPELL_CONSUME_FLESH);
- events.ScheduleEvent(EVENT_CONSUME_FLESH, 15000);
- break;
- case EVENT_INTANGIBLE_PRESENCE:
- DoCastVictim(SPELL_INTANGIBLE_PRESENCE);
- events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 15000);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_risen_husk_spiritAI(creature);
- }
-};
-
-/*######
## npc_lady_jaina_proudmoore
######*/
@@ -369,131 +275,6 @@ public:
};
-/*######
-## npc_stinky
-######*/
-
-enum Stinky
-{
- QUEST_STINKYS_ESCAPE_H = 1270,
- QUEST_STINKYS_ESCAPE_A = 1222,
- SAY_QUEST_ACCEPTED = 0,
- SAY_STAY_1 = 1,
- SAY_STAY_2 = 2,
- SAY_STAY_3 = 3,
- SAY_STAY_4 = 4,
- SAY_STAY_5 = 5,
- SAY_STAY_6 = 6,
- SAY_QUEST_COMPLETE = 7,
- SAY_ATTACKED_1 = 8,
- EMOTE_DISAPPEAR = 9
-};
-
-class npc_stinky : public CreatureScript
-{
-public:
- npc_stinky() : CreatureScript("npc_stinky") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_stinkyAI(creature);
- }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
- {
- if (quest->GetQuestId() == QUEST_STINKYS_ESCAPE_H || quest->GetQuestId() == QUEST_STINKYS_ESCAPE_A)
- {
- if (npc_stinkyAI* pEscortAI = CAST_AI(npc_stinky::npc_stinkyAI, creature->AI()))
- {
- creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
- creature->SetStandState(UNIT_STAND_STATE_STAND);
- creature->AI()->Talk(SAY_QUEST_ACCEPTED);
- pEscortAI->Start(false, false, player->GetGUID());
- }
- }
- return true;
- }
-
- struct npc_stinkyAI : public npc_escortAI
- {
- npc_stinkyAI(Creature* creature) : npc_escortAI(creature) { }
-
- void WaypointReached(uint32 waypointId) override
- {
- Player* player = GetPlayerForEscort();
- if (!player)
- return;
-
- switch (waypointId)
- {
- case 7:
- Talk(SAY_STAY_1, player);
- break;
- case 11:
- Talk(SAY_STAY_2, player);
- break;
- case 25:
- Talk(SAY_STAY_3, player);
- break;
- case 26:
- Talk(SAY_STAY_4, player);
- break;
- case 27:
- Talk(SAY_STAY_5, player);
- break;
- case 28:
- Talk(SAY_STAY_6, player);
- me->SetStandState(UNIT_STAND_STATE_KNEEL);
- break;
- case 29:
- me->SetStandState(UNIT_STAND_STATE_STAND);
- break;
- case 37:
- Talk(SAY_QUEST_COMPLETE, player);
- me->SetSpeed(MOVE_RUN, 1.2f, true);
- me->SetWalk(false);
- if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H))
- player->GroupEventHappens(QUEST_STINKYS_ESCAPE_H, me);
- if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A))
- player->GroupEventHappens(QUEST_STINKYS_ESCAPE_A, me);
- break;
- case 39:
- Talk(EMOTE_DISAPPEAR);
- break;
- }
- }
-
- void EnterCombat(Unit* who) override
- {
- Talk(SAY_ATTACKED_1, who);
- }
-
- void Reset() override { }
-
- void JustDied(Unit* /*killer*/) override
- {
- Player* player = GetPlayerForEscort();
- if (player && HasEscortState(STATE_ESCORT_ESCORTING))
- {
- if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H))
- player->FailQuest(QUEST_STINKYS_ESCAPE_H);
-
- if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A))
- player->FailQuest(QUEST_STINKYS_ESCAPE_A);
- }
- }
-
- void UpdateAI(uint32 uiDiff) override
- {
- npc_escortAI::UpdateAI(uiDiff);
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-};
enum SpellScripts
{
@@ -634,46 +415,13 @@ class spell_energize_aoe : public SpellScriptLoader
}
};
-/*######
-## go_blackhoof_cage
-######*/
-
-enum PrisonersOfTheGrimTotems
-{
- NPC_THERAMORE_PRISONER = 23720,
- SAY_FREE = 0,
-};
-
-class go_blackhoof_cage : public GameObjectScript
-{
-public:
- go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { }
-
- bool OnGossipHello(Player* player, GameObject* go) override
- {
- go->UseDoorOrButton();
- if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f))
- {
- if (player)
- player->KilledMonsterCredit(NPC_THERAMORE_PRISONER);
-
- prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote)
- prisoner->DespawnOrUnsummon(6000);
- }
- return true;
- }
-};
-
void AddSC_dustwallow_marsh()
{
- new npc_risen_husk_spirit();
new npc_lady_jaina_proudmoore();
new npc_nat_pagle();
new npc_private_hendel();
new npc_zelfrax();
- new npc_stinky();
new spell_ooze_zap();
new spell_ooze_zap_channel_end();
new spell_energize_aoe();
- new go_blackhoof_cage();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index a5978d8f8fa..a3d23108038 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -364,7 +364,7 @@ class NecroticPlagueTargetCheck : public std::unary_function<Unit*, bool>
bool operator()(Unit* unit) const
{
- if (!unit || unit == _sourceObj || !unit->isTargetableForAttack() || unit->IsTotem() || unit->HasAura(SPELL_PLAGUE_AVOIDANCE))
+ if (!unit || unit == _sourceObj || !unit->isTargetableForAttack() || unit->GetTypeId() != TYPEID_PLAYER || unit->HasAura(SPELL_PLAGUE_AVOIDANCE))
return false;
if ((_notAura1 && unit->HasAura(_notAura1)) || (_notAura2 && unit->HasAura(_notAura2)))
return false;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 6fe7bb30056..7292850bef1 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -30,26 +30,23 @@ EndScriptData */
#include "naxxramas.h"
#include "Player.h"
-enum Yells
+enum Texts
{
- //when shappiron dies. dialog between kel and lich king (in this order)
- SAY_SAPP_DIALOG1 = 0, //not used
- SAY_SAPP_DIALOG2_LICH = 1, //not used
- SAY_SAPP_DIALOG3 = 2, //not used
- SAY_SAPP_DIALOG4_LICH = 3, //not used
- SAY_SAPP_DIALOG5 = 4, //not used
- SAY_CAT_DIED = 5, //when cat dies, not used
- //when each of the 4 wing bosses dies
- SAY_TAUNT = 6,
SAY_AGGRO = 7,
SAY_SLAY = 8,
SAY_DEATH = 9,
SAY_CHAIN = 10,
SAY_FROST_BLAST = 11,
SAY_REQUEST_AID = 12, //start of phase 3
- SAY_ANSWER_REQUEST = 13, //lich king answer
+ EMOTE_PHASE_TWO = 13,
SAY_SUMMON_MINIONS = 14, //start of phase 1
- SAY_SPECIAL = 15
+ SAY_SPECIAL = 15,
+
+ // The Lich King
+ SAY_ANSWER_REQUEST = 3,
+
+ // Old World Trigger
+ SAY_GUARDIAN_SPAWNED = 0
};
enum Events
@@ -70,7 +67,10 @@ enum Events
EVENT_TRIGGER,
EVENT_PHASE,
- EVENT_MORTAL_WOUND
+ EVENT_MORTAL_WOUND,
+
+ EVENT_ANSWER_REQUEST,
+ EVENT_SUMMON_GUARDIANS
};
enum Spells
@@ -123,6 +123,13 @@ enum Spells
SPELL_MORTAL_WOUND = 28467
};
+enum Phases
+{
+ PHASE_ONE = 1, // Players move in the circle and Kel'Thuzad spawns his minions.
+ PHASE_TWO = 2, // Starts on a timer.
+ PHASE_THREE = 3 // At 45% health.
+};
+
enum Creatures
{
NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
@@ -270,15 +277,11 @@ public:
void Initialize()
{
nGuardiansOfIcecrownCount = 0;
- uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3
- Phase = 0;
nAbomination = 0;
nWeaver = 0;
}
- uint32 Phase;
- uint32 uiGuardiansOfIcecrownTimer;
uint32 uiFaction;
uint8 nGuardiansOfIcecrownCount;
@@ -345,7 +348,6 @@ public:
void EnterCombat(Unit* /*who*/) override
{
me->setFaction(uiFaction);
-
_EnterCombat();
for (uint8 i = 0; i <= 3; ++i)
{
@@ -354,10 +356,10 @@ public:
}
DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
Talk(SAY_SUMMON_MINIONS);
- Phase = 1;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4);
me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4);
+ events.SetPhase(PHASE_ONE);
events.ScheduleEvent(EVENT_TRIGGER, 5000);
events.ScheduleEvent(EVENT_WASTE, 15000);
events.ScheduleEvent(EVENT_ABOMIN, 30000);
@@ -365,6 +367,23 @@ public:
events.ScheduleEvent(EVENT_PHASE, 228000);
}
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (events.IsInPhase(PHASE_TWO) && me->HealthBelowPctDamaged(45, damage))
+ {
+ Talk(SAY_REQUEST_AID);
+ events.SetPhase(PHASE_THREE);
+ events.ScheduleEvent(EVENT_ANSWER_REQUEST, 4000);
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
+ if (portal->getLootState() == GO_READY)
+ portal->UseDoorOrButton();
+ }
+ }
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -372,7 +391,7 @@ public:
events.Update(diff);
- if (Phase == 1)
+ if (events.IsInPhase(PHASE_ONE))
{
while (uint32 eventId = events.ExecuteEvent())
{
@@ -405,6 +424,7 @@ public:
case EVENT_PHASE:
events.Reset();
Talk(SAY_AGGRO);
+ Talk(EMOTE_PHASE_TWO);
spawns.DespawnAll();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->CastStop();
@@ -417,7 +437,7 @@ public:
events.ScheduleEvent(EVENT_BLAST, urand(60000, 120000));
if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
events.ScheduleEvent(EVENT_CHAIN, urand(30000, 60000));
- Phase = 2;
+ events.SetPhase(PHASE_TWO);
break;
default:
break;
@@ -426,38 +446,6 @@ public:
}
else
{
- //start phase 3 when we are 45% health
- if (Phase != 3)
- {
- if (HealthBelowPct(45))
- {
- Phase = 3;
- Talk(SAY_REQUEST_AID);
- //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
- //so for now just make Kelthuzad says it.
- Talk(SAY_ANSWER_REQUEST);
-
- for (uint8 i = 0; i <= 3; ++i)
- {
- if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
- if (portal->getLootState() == GO_READY)
- portal->UseDoorOrButton();
- }
- }
- }
- else if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
- {
- if (uiGuardiansOfIcecrownTimer <= diff)
- {
- /// @todo Add missing text
- if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
- guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
- ++nGuardiansOfIcecrownCount;
- uiGuardiansOfIcecrownTimer = 5000;
- }
- else uiGuardiansOfIcecrownTimer -= diff;
- }
-
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
@@ -609,6 +597,18 @@ public:
Talk(SAY_FROST_BLAST);
events.Repeat(30000, 90000);
break;
+ case EVENT_ANSWER_REQUEST:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_LICH_KING)))
+ lichKing->AI()->Talk(SAY_ANSWER_REQUEST);
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
+ case EVENT_SUMMON_GUARDIANS:
+ if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
+ guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ ++nGuardiansOfIcecrownCount;
+ if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
default:
break;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 4151c4a85a7..e5895d78ab3 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -69,6 +69,15 @@ MinionData const minionData[] =
{ 0, 0, }
};
+ObjectData const objectData[] =
+{
+ { GO_NAXX_PORTAL_ARACHNID, DATA_NAXX_PORTAL_ARACHNID },
+ { GO_NAXX_PORTAL_CONSTRUCT, DATA_NAXX_PORTAL_CONSTRUCT },
+ { GO_NAXX_PORTAL_PLAGUE, DATA_NAXX_PORTAL_PLAGUE },
+ { GO_NAXX_PORTAL_MILITARY, DATA_NAXX_PORTAL_MILITARY },
+ { 0, 0, }
+};
+
float const HeiganPos[2] = { 2796.0f, -3707.0f };
float const HeiganEruptionSlope[3] =
{
@@ -111,10 +120,12 @@ class instance_naxxramas : public InstanceMapScript
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
LoadMinionData(minionData);
+ LoadObjectData(nullptr, objectData);
minHorsemenDiedTime = 0;
maxHorsemenDiedTime = 0;
AbominationCount = 0;
+ CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT;
playerDied = 0;
}
@@ -156,6 +167,9 @@ class instance_naxxramas : public InstanceMapScript
case NPC_KEL_THUZAD:
KelthuzadGUID = creature->GetGUID();
break;
+ case NPC_LICH_KING:
+ LichKingGUID = creature->GetGUID();
+ break;
default:
break;
}
@@ -201,11 +215,30 @@ class instance_naxxramas : public InstanceMapScript
case GO_KELTHUZAD_TRIGGER:
KelthuzadTriggerGUID = go->GetGUID();
break;
+ case GO_ROOM_KELTHUZAD:
+ KelthuzadDoorGUID = go->GetGUID();
+ break;
+ case GO_NAXX_PORTAL_ARACHNID:
+ if (GetBossState(BOSS_MAEXXNA) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_NAXX_PORTAL_CONSTRUCT:
+ if (GetBossState(BOSS_THADDIUS) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_NAXX_PORTAL_PLAGUE:
+ if (GetBossState(BOSS_LOATHEB) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_NAXX_PORTAL_MILITARY:
+ if (GetBossState(BOSS_HORSEMEN) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
default:
break;
}
- AddDoor(go, true);
+ InstanceScript::OnGameObjectCreate(go);
}
void OnGameObjectRemove(GameObject* go) override
@@ -232,7 +265,7 @@ class instance_naxxramas : public InstanceMapScript
break;
}
- AddDoor(go, false);
+ InstanceScript::OnGameObjectRemove(go);
}
void OnUnitDeath(Unit* unit) override
@@ -242,6 +275,15 @@ class instance_naxxramas : public InstanceMapScript
playerDied = 1;
SaveToDB();
}
+
+ if (Creature* creature = unit->ToCreature())
+ if (creature->GetEntry() == NPC_BIGGLESWORTH)
+ {
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_KELTHUZAD_CAT_DIED);
+ }
}
void SetData(uint32 id, uint32 value) override
@@ -327,6 +369,8 @@ class instance_naxxramas : public InstanceMapScript
return PortalsGUID[3];
case DATA_KELTHUZAD_TRIGGER:
return KelthuzadTriggerGUID;
+ case DATA_LICH_KING:
+ return LichKingGUID;
}
return ObjectGuid::Empty;
@@ -337,18 +381,156 @@ class instance_naxxramas : public InstanceMapScript
if (!InstanceScript::SetBossState(id, state))
return false;
- if (id == BOSS_HORSEMEN && state == DONE)
+ switch (id)
{
- if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
- {
- horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
- horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
+ case BOSS_MAEXXNA:
+ if (state == DONE)
+ {
+ if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_ARACHNID))
+ teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_LOATHEB:
+ if (state == DONE)
+ {
+ if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_PLAGUE))
+ teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_THADDIUS:
+ if (state == DONE)
+ {
+ if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_CONSTRUCT))
+ teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_GOTHIK:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, 10000);
+ break;
+ case BOSS_HORSEMEN:
+ if (state == DONE)
+ {
+ if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
+ {
+ horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
+ horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+
+ if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_MILITARY))
+ teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_SAPPHIRON:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, 6000);
+ break;
+ default:
+ break;
}
return true;
}
+ void Update(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, 5000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX2:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK2:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ2:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE2:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ break;
+ case EVENT_KELTHUZAD_WING_TAUNT:
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(CurrentWingTaunt);
+ ++CurrentWingTaunt;
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD);
+ HandleGameObject(KelthuzadDoorGUID, false);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, 16000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, 9000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING2:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, 12000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4);
+ HandleGameObject(KelthuzadDoorGUID, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void HeiganErupt(uint32 section)
{
for (uint32 i = 0; i < 4; ++i)
@@ -450,10 +632,15 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid KelthuzadGUID;
ObjectGuid KelthuzadTriggerGUID;
ObjectGuid PortalsGUID[4];
+ ObjectGuid KelthuzadDoorGUID;
+ ObjectGuid LichKingGUID;
uint8 AbominationCount;
+ uint8 CurrentWingTaunt;
/* The Immortal / The Undying */
uint32 playerDied;
+
+ EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 8325271a403..0f710a66bbe 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -52,6 +52,11 @@ enum Data
DATA_HORSEMEN2,
DATA_HORSEMEN3,
DATA_ABOMINATION_KILLED,
+
+ DATA_NAXX_PORTAL_ARACHNID,
+ DATA_NAXX_PORTAL_CONSTRUCT,
+ DATA_NAXX_PORTAL_PLAGUE,
+ DATA_NAXX_PORTAL_MILITARY
};
enum Data64
@@ -71,6 +76,7 @@ enum Data64
DATA_KELTHUZAD_PORTAL03,
DATA_KELTHUZAD_PORTAL04,
DATA_KELTHUZAD_TRIGGER,
+ DATA_LICH_KING
};
enum CreaturesIds
@@ -89,7 +95,10 @@ enum CreaturesIds
NPC_CRYPT_GUARD = 16573,
NPC_NAXXRAMAS_FOLLOWER = 16505,
NPC_FOLLOWER_WORSHIPPER = 16506,
- NPC_DK_UNDERSTUDY = 16803
+ NPC_DK_UNDERSTUDY = 16803,
+ NPC_BIGGLESWORTH = 16998,
+ NPC_LICH_KING = 16980,
+ NPC_OLD_WORLD_TRIGGER = 15384
};
enum GameObjectsIds
@@ -133,7 +142,13 @@ enum GameObjectsIds
GO_CONS_EYE_RAMP_BOSS = 181232,
GO_CONS_NOX_TESLA_FEUGEN = 181477,
GO_CONS_NOX_TESLA_STALAGG = 181478,
- GO_BIRTH = 181356
+ GO_BIRTH = 181356,
+
+ // Teleporting pads spawned by the end of every quarter.
+ GO_NAXX_PORTAL_ARACHNID = 181575,
+ GO_NAXX_PORTAL_CONSTRUCT = 181576,
+ GO_NAXX_PORTAL_PLAGUE = 181577,
+ GO_NAXX_PORTAL_MILITARY = 181578
};
enum SpellIds
@@ -142,6 +157,50 @@ enum SpellIds
SPELL_SLIME = 28801
};
+enum InstanceEvents
+{
+ // Dialogue that happens after Gothik's death.
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ = 1,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX2,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK2,
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ2,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE2,
+
+ // Dialogue that happens after each wing.
+ EVENT_KELTHUZAD_WING_TAUNT,
+
+ // Dialogue that happens after Sapphiron's death.
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING2,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4
+};
+
+enum InstanceTexts
+{
+ // The Four Horsemen
+ SAY_DIALOGUE_GOTHIK_HORSEMAN = 5,
+ SAY_DIALOGUE_GOTHIK_HORSEMAN2 = 6,
+
+ // Kel'Thuzad
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD = 0,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2 = 2,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3 = 4,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4 = 20,
+
+ SAY_KELTHUZAD_CAT_DIED = 5,
+ SAY_KELTHUZAD_FIRST_WING_TAUNT = 16,
+
+ // Lich King
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING = 1,
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING2 = 2
+};
+
/*
template<class AI>
CreatureAI* GetNaxxramasAI(Creature* creature)
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp
index ed08296acd8..dac06186dff 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp
@@ -100,21 +100,21 @@ class boss_anomalus : public CreatureScript
{
Initialize();
- instance->SetData(DATA_ANOMALUS_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_ANOMALUS, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
- instance->SetData(DATA_ANOMALUS_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_ANOMALUS, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
- instance->SetData(DATA_ANOMALUS_EVENT, DONE);
+ instance->SetBossState(DATA_ANOMALUS, DONE);
}
uint32 GetData(uint32 type) const override
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
index 6b3df5ef665..a8ffb1d542e 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
@@ -101,7 +101,7 @@ public:
RemovePrison(CheckContainmentSpheres());
- instance->SetData(DATA_KERISTRASZA_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_KERISTRASZA, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
@@ -109,14 +109,14 @@ public:
Talk(SAY_AGGRO);
DoCastAOE(SPELL_INTENSE_COLD);
- instance->SetData(DATA_KERISTRASZA_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_KERISTRASZA, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
- instance->SetData(DATA_KERISTRASZA_EVENT, DONE);
+ instance->SetBossState(DATA_KERISTRASZA, DONE);
}
void KilledUnit(Unit* who) override
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
index 8c58a65cdbe..1df5f5eac8f 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
@@ -31,7 +31,9 @@ enum Spells
SPELL_FIRE_MAGUS_VISUAL = 47705,
SPELL_FROST_MAGUS_VISUAL = 47706,
- SPELL_ARCANE_MAGUS_VISUAL = 47704
+ SPELL_ARCANE_MAGUS_VISUAL = 47704,
+
+ SPELL_WEAR_CHRISTMAS_HAT = 61400
};
enum Creatures
@@ -53,7 +55,9 @@ enum Yells
enum Misc
{
ACTION_MAGUS_DEAD = 1,
- DATA_SPLIT_PERSONALITY = 2
+ DATA_SPLIT_PERSONALITY = 2,
+
+ GAME_EVENT_WINTER_VEIL = 2,
};
const Position CenterOfRoom = {504.80f, 89.07f, -16.12f, 6.27f};
@@ -128,21 +132,24 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetVisible(true);
- instance->SetData(DATA_MAGUS_TELESTRA_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_MAGUS_TELESTRA, NOT_STARTED);
+
+ if (IsHeroic() && sGameEventMgr->IsActiveEvent(GAME_EVENT_WINTER_VEIL) && !me->HasAura(SPELL_WEAR_CHRISTMAS_HAT))
+ me->AddAura(SPELL_WEAR_CHRISTMAS_HAT, me);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
- instance->SetData(DATA_MAGUS_TELESTRA_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_MAGUS_TELESTRA, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
- instance->SetData(DATA_MAGUS_TELESTRA_EVENT, DONE);
+ instance->SetBossState(DATA_MAGUS_TELESTRA, DONE);
}
void KilledUnit(Unit* who) override
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp
index 84523c1864d..f065f0679fc 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp
@@ -68,7 +68,7 @@ public:
struct boss_ormorokAI : public BossAI
{
- boss_ormorokAI(Creature* creature) : BossAI(creature, DATA_ORMOROK_EVENT)
+ boss_ormorokAI(Creature* creature) : BossAI(creature, DATA_ORMOROK)
{
Initialize();
}
@@ -95,8 +95,6 @@ public:
events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000);
Talk(SAY_AGGRO);
-
- instance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS);
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
@@ -112,10 +110,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
_JustDied();
-
Talk(SAY_DEATH);
-
- instance->SetData(DATA_ORMOROK_EVENT, DONE);
}
void KilledUnit(Unit* who) override
@@ -138,27 +133,27 @@ public:
{
switch (eventId)
{
- case EVENT_TRAMPLE:
- DoCast(me, SPELL_TRAMPLE);
- events.ScheduleEvent(EVENT_TRAMPLE, 10000);
- break;
- case EVENT_SPELL_REFLECTION:
- Talk(SAY_REFLECT);
- DoCast(me, SPELL_SPELL_REFLECTION);
- events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000);
- break;
- case EVENT_CRYSTAL_SPIKES:
- Talk(SAY_CRYSTAL_SPIKES);
- DoCast(SPELL_CRYSTAL_SPIKES);
- events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000);
- break;
- case EVENT_CRYSTALLINE_TANGLER:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, OrmorokTanglerPredicate(me)))
- DoCast(target, SPELL_SUMMON_CRYSTALLINE_TANGLER);
- events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000);
- break;
- default:
- break;
+ case EVENT_TRAMPLE:
+ DoCast(me, SPELL_TRAMPLE);
+ events.ScheduleEvent(EVENT_TRAMPLE, 10000);
+ break;
+ case EVENT_SPELL_REFLECTION:
+ Talk(SAY_REFLECT);
+ DoCast(me, SPELL_SPELL_REFLECTION);
+ events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000);
+ break;
+ case EVENT_CRYSTAL_SPIKES:
+ Talk(SAY_CRYSTAL_SPIKES);
+ DoCast(SPELL_CRYSTAL_SPIKES);
+ events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000);
+ break;
+ case EVENT_CRYSTALLINE_TANGLER:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, OrmorokTanglerPredicate(me)))
+ DoCast(target, SPELL_SUMMON_CRYSTALLINE_TANGLER);
+ events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000);
+ break;
+ default:
+ break;
}
}
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
index b7f2e23616b..b3b2cdd540f 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
@@ -18,10 +18,8 @@
#include "ScriptMgr.h"
#include "InstanceScript.h"
-#include "nexus.h"
#include "Player.h"
-
-#define NUMBER_OF_ENCOUNTERS 4
+#include "nexus.h"
enum Factions
{
@@ -30,229 +28,163 @@ enum Factions
class instance_nexus : public InstanceMapScript
{
-public:
- instance_nexus() : InstanceMapScript("instance_nexus", 576) { }
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const override
- {
- return new instance_nexus_InstanceMapScript(map);
- }
+ public:
+ instance_nexus() : InstanceMapScript(NexusScriptName, 576) { }
- struct instance_nexus_InstanceMapScript : public InstanceScript
- {
- instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map)
+ struct instance_nexus_InstanceMapScript : public InstanceScript
{
- SetHeaders(DataHeader);
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
- }
-
- uint32 m_auiEncounter[NUMBER_OF_ENCOUNTERS];
-
- ObjectGuid Anomalus;
- ObjectGuid Keristrasza;
-
- ObjectGuid AnomalusContainmentSphere;
- ObjectGuid OrmoroksContainmentSphere;
- ObjectGuid TelestrasContainmentSphere;
-
- std::string strInstData;
-
- void OnCreatureCreate(Creature* creature) override
- {
- Map::PlayerList const &players = instance->GetPlayers();
- uint32 TeamInInstance = 0;
-
- if (!players.isEmpty())
+ instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map)
{
- if (Player* player = players.begin()->GetSource())
- TeamInInstance = player->GetTeam();
+ SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ _teamInInstance = 0;
}
- switch (creature->GetEntry())
+
+ void OnPlayerEnter(Player* player) override
{
- case 26763:
- Anomalus = creature->GetGUID();
- break;
- case 26723:
- Keristrasza = creature->GetGUID();
- break;
- // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
- case 26800:
- {
- if (ServerAllowsTwoSideGroups())
- creature->setFaction(FACTION_HOSTILE_FOR_ALL);
- if (TeamInInstance == ALLIANCE)
- creature->UpdateEntry(26799);
- break;
- }
- case 26802:
- {
- if (ServerAllowsTwoSideGroups())
- creature->setFaction(FACTION_HOSTILE_FOR_ALL);
- if (TeamInInstance == ALLIANCE)
- creature->UpdateEntry(26801);
- break;
- }
- case 26805:
- {
- if (ServerAllowsTwoSideGroups())
- creature->setFaction(FACTION_HOSTILE_FOR_ALL);
- if (TeamInInstance == ALLIANCE)
- creature->UpdateEntry(26803);
- break;
- }
- case 27949:
- {
- if (ServerAllowsTwoSideGroups())
- creature->setFaction(FACTION_HOSTILE_FOR_ALL);
- if (TeamInInstance == ALLIANCE)
- creature->UpdateEntry(27947);
- break;
- }
- case 26796:
- {
- if (ServerAllowsTwoSideGroups())
- creature->setFaction(FACTION_HOSTILE_FOR_ALL);
- if (TeamInInstance == ALLIANCE)
- creature->UpdateEntry(26798);
- break;
- }
+ if (!_teamInInstance)
+ _teamInInstance = player->GetTeam();
}
- }
- void OnGameObjectCreate(GameObject* go) override
- {
- switch (go->GetEntry())
+ void OnCreatureCreate(Creature* creature) override
{
- case 188527:
- {
- AnomalusContainmentSphere = go->GetGUID();
- if (m_auiEncounter[1] == DONE)
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- break;
- }
- case 188528:
- {
- OrmoroksContainmentSphere = go->GetGUID();
- if (m_auiEncounter[2] == DONE)
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- break;
- }
- case 188526:
+ switch (creature->GetEntry())
{
- TelestrasContainmentSphere = go->GetGUID();
- if (m_auiEncounter[0] == DONE)
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- break;
+ case NPC_ANOMALUS:
+ AnomalusGUID = creature->GetGUID();
+ break;
+ case NPC_KERISTRASZA:
+ KeristraszaGUID = creature->GetGUID();
+ break;
+ // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
+ case NPC_ALLIANCE_BERSERKER:
+ if (ServerAllowsTwoSideGroups())
+ creature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_HORDE_BERSERKER);
+ break;
+ case NPC_ALLIANCE_RANGER:
+ if (ServerAllowsTwoSideGroups())
+ creature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_HORDE_RANGER);
+ break;
+ case NPC_ALLIANCE_CLERIC:
+ if (ServerAllowsTwoSideGroups())
+ creature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_HORDE_CLERIC);
+ break;
+ case NPC_ALLIANCE_COMMANDER:
+ if (ServerAllowsTwoSideGroups())
+ creature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_HORDE_COMMANDER);
+ break;
+ case NPC_COMMANDER_STOUTBEARD:
+ if (ServerAllowsTwoSideGroups())
+ creature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_COMMANDER_KOLURG);
+ break;
+ default:
+ break;
}
}
- }
-
- uint32 GetData(uint32 identifier) const override
- {
- switch (identifier)
- {
- case DATA_MAGUS_TELESTRA_EVENT: return m_auiEncounter[0];
- case DATA_ANOMALUS_EVENT: return m_auiEncounter[1];
- case DATA_ORMOROK_EVENT: return m_auiEncounter[2];
- case DATA_KERISTRASZA_EVENT: return m_auiEncounter[3];
- }
- return 0;
- }
- void SetData(uint32 identifier, uint32 data) override
- {
- switch (identifier)
+ void OnGameObjectCreate(GameObject* go) override
{
- case DATA_MAGUS_TELESTRA_EVENT:
+ switch (go->GetEntry())
{
- if (data == DONE)
- {
- GameObject* Sphere = instance->GetGameObject(TelestrasContainmentSphere);
- if (Sphere)
- Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
- m_auiEncounter[0] = data;
- break;
+ case GO_ANOMALUS_CONTAINMET_SPHERE:
+ AnomalusContainmentSphere = go->GetGUID();
+ if (GetBossState(DATA_ANOMALUS) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_ORMOROKS_CONTAINMET_SPHERE:
+ OrmoroksContainmentSphere = go->GetGUID();
+ if (GetBossState(DATA_ORMOROK) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_TELESTRAS_CONTAINMET_SPHERE:
+ TelestrasContainmentSphere = go->GetGUID();
+ if (GetBossState(DATA_MAGUS_TELESTRA) == DONE)
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ break;
+ default:
+ break;
}
- case DATA_ANOMALUS_EVENT:
- {
- if (data == DONE)
- {
- if (GameObject* Sphere = instance->GetGameObject(AnomalusContainmentSphere))
- Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
- m_auiEncounter[1] = data;
- break;
- }
- case DATA_ORMOROK_EVENT:
- {
- if (data == DONE)
- {
- if (GameObject* Sphere = instance->GetGameObject(OrmoroksContainmentSphere))
- Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
- m_auiEncounter[2] = data;
- break;
- }
- case DATA_KERISTRASZA_EVENT:
- m_auiEncounter[3] = data;
- break;
}
- if (data == DONE)
+ bool SetBossState(uint32 type, EncounterState state) override
{
- OUT_SAVE_INST_DATA;
-
- std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' '
- << m_auiEncounter[3];
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
- strInstData = saveStream.str();
+ switch (type)
+ {
+ case DATA_MAGUS_TELESTRA:
+ if (state == DONE)
+ {
+ if (GameObject* sphere = instance->GetGameObject(TelestrasContainmentSphere))
+ sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ case DATA_ANOMALUS:
+ if (state == DONE)
+ {
+ if (GameObject* sphere = instance->GetGameObject(AnomalusContainmentSphere))
+ sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ case DATA_ORMOROK:
+ if (state == DONE)
+ {
+ if (GameObject* sphere = instance->GetGameObject(OrmoroksContainmentSphere))
+ sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ default:
+ break;
+ }
- SaveToDB();
- OUT_SAVE_INST_DATA_COMPLETE;
+ return true;
}
- }
- ObjectGuid GetGuidData(uint32 uiIdentifier) const override
- {
- switch (uiIdentifier)
+ ObjectGuid GetGuidData(uint32 type) const override
{
- case DATA_ANOMALUS: return Anomalus;
- case DATA_KERISTRASZA: return Keristrasza;
- case ANOMALUS_CONTAINMET_SPHERE: return AnomalusContainmentSphere;
- case ORMOROKS_CONTAINMET_SPHERE: return OrmoroksContainmentSphere;
- case TELESTRAS_CONTAINMET_SPHERE: return TelestrasContainmentSphere;
- }
- return ObjectGuid::Empty;
- }
-
- std::string GetSaveData() override
- {
- return strInstData;
- }
+ switch (type)
+ {
+ case DATA_ANOMALUS:
+ return AnomalusGUID;
+ case DATA_KERISTRASZA:
+ return KeristraszaGUID;
+ case ANOMALUS_CONTAINMET_SPHERE:
+ return AnomalusContainmentSphere;
+ case ORMOROKS_CONTAINMET_SPHERE:
+ return OrmoroksContainmentSphere;
+ case TELESTRAS_CONTAINMET_SPHERE:
+ return TelestrasContainmentSphere;
+ default:
+ break;
+ }
- void Load(const char *chrIn)
- {
- if (!chrIn)
- {
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ return ObjectGuid::Empty;
}
- OUT_LOAD_INST_DATA(chrIn);
-
- std::istringstream loadStream(chrIn);
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
+ private:
+ ObjectGuid AnomalusGUID;
+ ObjectGuid KeristraszaGUID;
+ ObjectGuid AnomalusContainmentSphere;
+ ObjectGuid OrmoroksContainmentSphere;
+ ObjectGuid TelestrasContainmentSphere;
+ uint32 _teamInInstance;
+ };
- for (uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
-
- OUT_LOAD_INST_DATA_COMPLETE;
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
+ {
+ return new instance_nexus_InstanceMapScript(map);
}
- };
-
};
void AddSC_instance_nexus()
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h
index c9f5d44c932..9962b0c884d 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h
+++ b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h
@@ -18,21 +18,48 @@
#ifndef DEF_NEXUS_H
#define DEF_NEXUS_H
+#define NexusScriptName "instance_nexus"
#define DataHeader "NEX"
+uint32 const EncounterCount = 4;
+
enum DataTypes
{
- DATA_MAGUS_TELESTRA_EVENT,
- DATA_ANOMALUS_EVENT,
- DATA_ORMOROK_EVENT,
- DATA_KERISTRASZA_EVENT,
+ DATA_MAGUS_TELESTRA = 0,
+ DATA_ANOMALUS = 1,
+ DATA_ORMOROK = 2,
+ DATA_KERISTRASZA = 3,
+
+ ANOMALUS_CONTAINMET_SPHERE = 4,
+ ORMOROKS_CONTAINMET_SPHERE = 5,
+ TELESTRAS_CONTAINMET_SPHERE = 6
+};
- DATA_ANOMALUS,
- DATA_KERISTRASZA,
+enum CreatureIds
+{
+ NPC_ANOMALUS = 26763,
+ NPC_KERISTRASZA = 26723,
+
+ // Alliance
+ NPC_ALLIANCE_BERSERKER = 26800,
+ NPC_ALLIANCE_RANGER = 26802,
+ NPC_ALLIANCE_CLERIC = 26805,
+ NPC_ALLIANCE_COMMANDER = 27949,
+ NPC_COMMANDER_STOUTBEARD = 26796,
+
+ // Horde
+ NPC_HORDE_BERSERKER = 26799,
+ NPC_HORDE_RANGER = 26801,
+ NPC_HORDE_CLERIC = 26803,
+ NPC_HORDE_COMMANDER = 27947,
+ NPC_COMMANDER_KOLURG = 26798
+};
- ANOMALUS_CONTAINMET_SPHERE,
- ORMOROKS_CONTAINMET_SPHERE,
- TELESTRAS_CONTAINMET_SPHERE
+enum GameObjectIds
+{
+ GO_ANOMALUS_CONTAINMET_SPHERE = 188527,
+ GO_ORMOROKS_CONTAINMET_SPHERE = 188528,
+ GO_TELESTRAS_CONTAINMET_SPHERE = 188526
};
#endif
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
index 1c5aadc3581..24a712d9d38 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
@@ -192,6 +192,7 @@ class instance_oculus : public InstanceMapScript
FreeDragons();
if (Creature* varos = instance->GetCreature(VarosGUID))
varos->SetPhaseMask(1, true);
+ events.ScheduleEvent(EVENT_VAROS_INTRO, 15000);
}
break;
case DATA_VAROS:
@@ -209,6 +210,7 @@ class instance_oculus : public InstanceMapScript
{
eregos->SetPhaseMask(1, true);
GreaterWhelps();
+ events.ScheduleEvent(EVENT_EREGOS_INTRO, 5000);
}
}
break;
@@ -267,6 +269,28 @@ class instance_oculus : public InstanceMapScript
}
}
+ void Update(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_VAROS_INTRO:
+ if (Creature* varos = instance->GetCreature(VarosGUID))
+ varos->AI()->Talk(SAY_VAROS_INTRO_TEXT);
+ break;
+ case EVENT_EREGOS_INTRO:
+ if (Creature* eregos = instance->GetCreature(EregosGUID))
+ eregos->AI()->Talk(SAY_EREGOS_INTRO_TEXT);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void GreaterWhelps()
{
for (ObjectGuid guid : GreaterWhelpList)
@@ -289,6 +313,8 @@ class instance_oculus : public InstanceMapScript
ObjectGuid EregosCacheGUID;
GuidList GreaterWhelpList;
+
+ EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
index 268cdb54e3e..d1144df9486 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
@@ -79,6 +79,18 @@ enum OculusSpells
SPELL_DEATH_SPELL = 50415
};
+enum InstanceTexts
+{
+ SAY_EREGOS_INTRO_TEXT = 0,
+ SAY_VAROS_INTRO_TEXT = 4
+};
+
+enum InstanceEvents
+{
+ EVENT_VAROS_INTRO = 1,
+ EVENT_EREGOS_INTRO
+};
+
enum Misc
{
POINT_MOVE_OUT = 1
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index fc29369c28f..8c7d0c2797f 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -28,7 +28,7 @@ EndScriptData */
#include "SpellScript.h"
#include "halls_of_lightning.h"
-enum Yells
+enum Texts
{
SAY_INTRO_1 = 0,
SAY_INTRO_2 = 1,
@@ -51,6 +51,21 @@ enum Spells
SPELL_PULSING_SHOCKWAVE_AURA = 59414
};
+enum Events
+{
+ EVENT_ARC_LIGHTNING = 1,
+ EVENT_LIGHTNING_NOVA,
+ EVENT_RESUME_PULSING_SHOCKWAVE,
+ EVENT_INTRO_DIALOGUE
+};
+
+enum Phases
+{
+ // Phases are used to allow executing the intro event while UpdateVictim() returns false and convenience.
+ PHASE_INTRO = 1,
+ PHASE_NORMAL
+};
+
enum Misc
{
ACHIEV_TIMELY_DEATH_START_EVENT = 20384
@@ -65,57 +80,41 @@ class boss_loken : public CreatureScript
public:
boss_loken() : CreatureScript("boss_loken") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_lokenAI>(creature);
- }
-
- struct boss_lokenAI : public ScriptedAI
+ struct boss_lokenAI : public BossAI
{
- boss_lokenAI(Creature* creature) : ScriptedAI(creature)
+ boss_lokenAI(Creature* creature) : BossAI(creature, DATA_LOKEN)
{
Initialize();
- instance = creature->GetInstanceScript();
+ _isIntroDone = false;
}
void Initialize()
{
- m_uiArcLightning_Timer = 15000;
- m_uiLightningNova_Timer = 20000;
- m_uiResumePulsingShockwave_Timer = 1000;
-
- m_uiHealthAmountModifier = 1;
+ _healthAmountModifier = 1;
}
- InstanceScript* instance;
-
- uint32 m_uiArcLightning_Timer;
- uint32 m_uiLightningNova_Timer;
- uint32 m_uiResumePulsingShockwave_Timer;
-
- uint32 m_uiHealthAmountModifier;
-
void Reset() override
{
Initialize();
-
- instance->SetBossState(DATA_LOKEN, NOT_STARTED);
+ _Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void EnterCombat(Unit* /*who*/) override
{
+ _EnterCombat();
Talk(SAY_AGGRO);
-
- instance->SetBossState(DATA_LOKEN, IN_PROGRESS);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, 15000);
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 20000);
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, 1000);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
-
- instance->SetBossState(DATA_LOKEN, DONE);
+ _JustDied();
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA);
}
@@ -125,66 +124,89 @@ public:
Talk(SAY_SLAY);
}
- void UpdateAI(uint32 uiDiff) override
+ void MoveInLineOfSight(Unit* who) override
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- if (m_uiResumePulsingShockwave_Timer)
+ if (!_isIntroDone && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40.0f))
{
- if (m_uiResumePulsingShockwave_Timer <= uiDiff)
- {
- DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
- me->ClearUnitState(UNIT_STATE_CASTING); // this flag breaks movement
-
- DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
- m_uiResumePulsingShockwave_Timer = 0;
- }
- else
- m_uiResumePulsingShockwave_Timer -= uiDiff;
+ _isIntroDone = true;
+ Talk(SAY_INTRO_1);
+ events.ScheduleEvent(EVENT_INTRO_DIALOGUE, 20000, 0, PHASE_INTRO);
}
+ BossAI::MoveInLineOfSight(who);
+ }
- if (m_uiArcLightning_Timer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARC_LIGHTNING);
+ void UpdateAI(uint32 diff) override
+ {
+ if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim())
+ return;
- m_uiArcLightning_Timer = urand(15000, 16000);
- }
- else
- m_uiArcLightning_Timer -= uiDiff;
+ events.Update(diff);
- if (m_uiLightningNova_Timer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- Talk(SAY_NOVA);
- Talk(EMOTE_NOVA);
- DoCast(me, SPELL_LIGHTNING_NOVA);
-
- me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me));
- m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
- m_uiLightningNova_Timer = urand(20000, 21000);
+ switch (eventId)
+ {
+ case EVENT_ARC_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ARC_LIGHTNING);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, urand(15000, 16000));
+ break;
+ case EVENT_LIGHTNING_NOVA:
+ Talk(SAY_NOVA);
+ Talk(EMOTE_NOVA);
+ DoCastAOE(SPELL_LIGHTNING_NOVA);
+ me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me));
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, DUNGEON_MODE(5000, 4000)); // Pause Pulsing Shockwave aura
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, urand(20000, 21000));
+ break;
+ case EVENT_RESUME_PULSING_SHOCKWAVE:
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
+ me->ClearUnitState(UNIT_STATE_CASTING); // This flag breaks movement.
+ DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
+ break;
+ case EVENT_INTRO_DIALOGUE:
+ Talk(SAY_INTRO_2);
+ events.SetPhase(PHASE_NORMAL);
+ break;
+ default:
+ break;
+ }
}
- else
- m_uiLightningNova_Timer -= uiDiff;
- // Health check
- if (HealthBelowPct(100 - 25 * m_uiHealthAmountModifier))
+ DoMeleeAttackIfReady();
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (me->HealthBelowPctDamaged(100 - 25 * _healthAmountModifier, damage))
{
- switch (m_uiHealthAmountModifier)
+ switch (_healthAmountModifier)
{
- case 1: Talk(SAY_75HEALTH); break;
- case 2: Talk(SAY_50HEALTH); break;
- case 3: Talk(SAY_25HEALTH); break;
+ case 1:
+ Talk(SAY_75HEALTH);
+ break;
+ case 2:
+ Talk(SAY_50HEALTH);
+ break;
+ case 3:
+ Talk(SAY_25HEALTH);
+ break;
+ default:
+ break;
}
-
- ++m_uiHealthAmountModifier;
+ ++_healthAmountModifier;
}
-
- DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 _healthAmountModifier;
+ bool _isIntroDone;
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_lokenAI>(creature);
+ }
};
class spell_loken_pulsing_shockwave : public SpellScriptLoader
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index eff84365f63..b949c43b64d 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -366,48 +366,6 @@ class npc_commander_eligor_dawnbringer : public CreatureScript
}
};
-enum AlexstraszaWrGate
-{
- // Quest
- QUEST_RETURN_TO_AG_A = 12499,
- QUEST_RETURN_TO_AG_H = 12500,
-
- // Movie
- MOVIE_ID_GATES = 14
-};
-
-#define GOSSIP_ITEM_WHAT_HAPPENED "Alexstrasza, can you show me what happened here?"
-
-class npc_alexstrasza_wr_gate : public CreatureScript
-{
-public:
- npc_alexstrasza_wr_gate() : CreatureScript("npc_alexstrasza_wr_gate") { }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_A) || player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_H))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WHAT_HAPPENED, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- player->SendMovieStart(MOVIE_ID_GATES);
- }
-
- return true;
- }
-};
-
/*######
## Quest Strengthen the Ancients (12096|12092)
######*/
@@ -746,7 +704,6 @@ class npc_torturer_lecraft : public CreatureScript
void AddSC_dragonblight()
{
new npc_commander_eligor_dawnbringer();
- new npc_alexstrasza_wr_gate();
new spell_q12096_q12092_dummy();
new spell_q12096_q12092_bark();
new npc_wyrmrest_defender();
diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp
index 7436ac8400f..2b317453992 100644
--- a/src/server/scripts/Northrend/zone_icecrown.cpp
+++ b/src/server/scripts/Northrend/zone_icecrown.cpp
@@ -210,52 +210,6 @@ public:
};
/*######
-## npc_vereth_the_cunning
-######*/
-
-enum VerethTheCunning
-{
- NPC_GEIST_RETURN_BUNNY_KC = 31049,
- NPC_LITHE_STALKER = 30894,
- SPELL_SUBDUED_LITHE_STALKER = 58151,
-};
-
-class npc_vereth_the_cunning : public CreatureScript
-{
-public:
- npc_vereth_the_cunning() : CreatureScript("npc_vereth_the_cunning") { }
-
- struct npc_vereth_the_cunningAI : public ScriptedAI
- {
- npc_vereth_the_cunningAI(Creature* creature) : ScriptedAI(creature) { }
-
- void MoveInLineOfSight(Unit* who) override
-
- {
- ScriptedAI::MoveInLineOfSight(who);
-
- if (who->GetEntry() == NPC_LITHE_STALKER && me->IsWithinDistInMap(who, 10.0f))
- {
- if (Unit* owner = who->GetCharmer())
- {
- if (who->HasAura(SPELL_SUBDUED_LITHE_STALKER))
- {
- owner->ToPlayer()->KilledMonsterCredit(NPC_GEIST_RETURN_BUNNY_KC);
- who->ToCreature()->DisappearAndDie();
-
- }
- }
- }
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_vereth_the_cunningAI(creature);
- }
-};
-
-/*######
* npc_tournament_training_dummy
######*/
enum TournamentDummy
@@ -881,207 +835,12 @@ class npc_frostbrood_skytalon : public CreatureScript
}
};
-/*######
-## The Flesh Giant Champion - Id: 13235
-######*/
-enum FleshGiant
-{
- QUEST_FLESH_GIANT_CHAMPION = 13235,
-
- NPC_MORBIDUS = 30698,
- NPC_LICH_KING = 31301,
- NPC_OLAKIN = 31428,
- NPC_DHAKAR = 31306,
-
- FACTION_HOSTILE = 14,
- FACTION_BASIC = 2102,
-
- EVENT_INTRO = 1,
- EVENT_LK_SAY_1 = 2,
- EVENT_LK_SAY_2 = 3,
- EVENT_LK_SAY_3 = 4,
- EVENT_LK_SAY_4 = 5,
- EVENT_LK_SAY_5 = 6,
- EVENT_OUTRO = 7,
- EVENT_START = 8,
-
- SPELL_SIMPLE_TELEPORT = 64195,
-
- SAY_DHAKAR_START = 0,
- SAY_LK_1 = 0,
- SAY_LK_2 = 1,
- SAY_LK_3 = 2,
- SAY_LK_4 = 3,
- SAY_LK_5 = 4,
- SAY_OLAKIN_PAY = 0
-};
-
-class npc_margrave_dhakar : public CreatureScript
-{
- public:
- npc_margrave_dhakar() : CreatureScript("npc_margrave_dhakar") { }
-
- struct npc_margrave_dhakarAI : public ScriptedAI
- {
- npc_margrave_dhakarAI(Creature* creature) : ScriptedAI(creature) , _summons(me) { }
-
- void Reset() override
- {
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
-
- _events.Reset();
- _summons.DespawnAll();
- }
-
- void sGossipSelect(Player* player, uint32 sender, uint32 action) override
- {
- if (player->GetQuestStatus(QUEST_FLESH_GIANT_CHAMPION) == QUEST_STATUS_INCOMPLETE && !player->IsInCombat())
- {
- if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
- {
- _events.ScheduleEvent(EVENT_INTRO, 1000);
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_INTRO:
- {
- Talk(SAY_DHAKAR_START);
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
-
- if (Creature* morbidus = me->FindNearestCreature(NPC_MORBIDUS, 50.0f, true))
- {
- if (Creature* lichKing = me->SummonCreature(NPC_LICH_KING, morbidus->GetPositionX() + 10.0f, morbidus->GetPositionY(), morbidus->GetPositionZ()))
- {
- _lichKingGuid = lichKing->GetGUID();
- lichKing->SetFacingTo(morbidus->GetOrientation());
- lichKing->CastSpell(lichKing, SPELL_SIMPLE_TELEPORT, true);
- }
- }
-
- _events.ScheduleEvent(EVENT_LK_SAY_1, 5000);
- break;
- }
- case EVENT_LK_SAY_1:
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->AI()->Talk(SAY_LK_1);
- _events.ScheduleEvent(EVENT_LK_SAY_2, 5000);
- break;
- }
- case EVENT_LK_SAY_2:
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->AI()->Talk(SAY_LK_2);
- _events.ScheduleEvent(EVENT_LK_SAY_3, 5000);
- break;
- }
- case EVENT_LK_SAY_3:
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->AI()->Talk(SAY_LK_3);
- _events.ScheduleEvent(EVENT_LK_SAY_4, 5000);
- break;
- }
- case EVENT_LK_SAY_4:
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->AI()->Talk(SAY_LK_4);
- _events.ScheduleEvent(EVENT_OUTRO, 12000);
- break;
- }
- case EVENT_LK_SAY_5:
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->AI()->Talk(SAY_LK_5);
- _events.ScheduleEvent(EVENT_OUTRO, 8000);
- break;
- }
- case EVENT_OUTRO:
- {
- if (Creature* olakin = me->FindNearestCreature(NPC_OLAKIN, 50.0f, true))
- olakin->AI()->Talk(SAY_OLAKIN_PAY);
-
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid))
- lichKing->DespawnOrUnsummon(0);
-
- _events.ScheduleEvent(EVENT_START, 5000);
- break;
- }
- case EVENT_START:
- {
- if (Creature* morbidus = me->FindNearestCreature(NPC_MORBIDUS, 50.0f, true))
- {
- morbidus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_DISABLE_MOVE);
- morbidus->setFaction(FACTION_HOSTILE);
- }
-
- break;
- }
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- SummonList _summons;
- ObjectGuid _lichKingGuid;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_margrave_dhakarAI(creature);
- }
-};
-
-class npc_morbidus : public CreatureScript
-{
- public:
- npc_morbidus() : CreatureScript("npc_morbidus") { }
-
- struct npc_morbidusAI : public ScriptedAI
- {
- npc_morbidusAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- if (Creature* dhakar = me->FindNearestCreature(NPC_DHAKAR, 50.0f, true))
- dhakar->AI()->Reset();
-
- // this will prevent the event to start without morbidus being alive
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_PASSIVE);
- me->setFaction(FACTION_BASIC);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_morbidusAI(creature);
- }
-};
-
void AddSC_icecrown()
{
new npc_squire_david;
new npc_argent_valiant;
new npc_guardian_pavilion;
- new npc_vereth_the_cunning;
new npc_tournament_training_dummy;
new npc_blessed_banner();
new npc_frostbrood_skytalon();
- new npc_margrave_dhakar();
- new npc_morbidus();
}
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
index 53fbf8f0cf7..1f55abf8a11 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
@@ -21,8 +21,14 @@
DoorData const doorData[] =
{
- { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+};
+
+ObjectData const gameObjectData[] =
+{
+ { GO_TALON_KING_COFFER, DATA_TALON_KING_COFFER },
+ { 0, 0 } // END
};
class instance_sethekk_halls : public InstanceMapScript
@@ -37,6 +43,7 @@ class instance_sethekk_halls : public InstanceMapScript
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
+ LoadObjectData(nullptr, gameObjectData);
}
void OnCreatureCreate(Creature* creature) override
@@ -50,16 +57,27 @@ class instance_sethekk_halls : public InstanceMapScript
}
}
- void OnGameObjectCreate(GameObject* go) override
+ bool SetBossState(uint32 type, EncounterState state) override
{
- if (go->GetEntry() == GO_IKISS_DOOR)
- AddDoor(go, true);
- }
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
- void OnGameObjectRemove(GameObject* go) override
- {
- if (go->GetEntry() == GO_IKISS_DOOR)
- AddDoor(go, false);
+ switch (type)
+ {
+ case DATA_TALON_KING_IKISS:
+ if (state == DONE)
+ {
+ /// @workaround: GO_FLAG_INTERACT_COND remains on the gob, but it is not handled correctly in this case
+ /// gameobject should have GO_DYNFLAG_LO_ACTIVATE too, which makes gobs interactable with GO_FLAG_INTERACT_COND
+ /// so just removed GO_FLAG_INTERACT_COND
+ if (GameObject* coffer = GetGameObject(DATA_TALON_KING_COFFER))
+ coffer->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
}
};
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
index 4b6bfab46cb..8cf01fb4635 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
@@ -28,7 +28,10 @@ enum DataTypes
// Encounter States/Boss GUIDs
DATA_DARKWEAVER_SYTH = 0,
DATA_TALON_KING_IKISS = 1,
- DATA_ANZU = 2
+ DATA_ANZU = 2,
+
+ // Additional Data
+ DATA_TALON_KING_COFFER = 3
};
enum CreatureIds
@@ -39,7 +42,8 @@ enum CreatureIds
enum GameObjectIds
{
- GO_IKISS_DOOR = 177203
+ GO_IKISS_DOOR = 177203,
+ GO_TALON_KING_COFFER = 187372
};
template<class AI>
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
index f0884e83baa..794d3a490f6 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
@@ -31,21 +31,25 @@ class go_main_chambers_access_panel : public GameObjectScript
return false;
if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO && (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE || instance->GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL))
- {
instance->SetBossState(DATA_HYDROMANCER_THESPIA, SPECIAL);
- go->SetGoState(GO_STATE_ACTIVE);
- }
if (go->GetEntry() == GO_ACCESS_PANEL_MEK && (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE || instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL))
- {
instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, SPECIAL);
- go->SetGoState(GO_STATE_ACTIVE);
- }
+
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ go->SetGoState(GO_STATE_ACTIVE);
return true;
}
};
+ObjectData const gameObjectData[] =
+{
+ { GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDRO },
+ { GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEK },
+ { 0, 0 } // END
+};
+
class instance_steam_vault : public InstanceMapScript
{
public:
@@ -57,6 +61,7 @@ class instance_steam_vault : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadObjectData(nullptr, gameObjectData);
DistillerState = 0;
}
@@ -89,6 +94,8 @@ class instance_steam_vault : public InstanceMapScript
default:
break;
}
+
+ InstanceScript::OnGameObjectCreate(go);
}
ObjectGuid GetGuidData(uint32 type) const override
@@ -128,6 +135,9 @@ class instance_steam_vault : public InstanceMapScript
switch (type)
{
case DATA_HYDROMANCER_THESPIA:
+ if (state == DONE)
+ if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_HYDRO))
+ panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (state == SPECIAL)
{
if (GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL)
@@ -137,6 +147,9 @@ class instance_steam_vault : public InstanceMapScript
}
break;
case DATA_MEKGINEER_STEAMRIGGER:
+ if (state == DONE)
+ if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_MEK))
+ panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (state == SPECIAL)
{
if (GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL)
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
index 58f71b047ef..d18d0406dea 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
+++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
@@ -28,7 +28,11 @@ enum DataTypes
DATA_HYDROMANCER_THESPIA = 0,
DATA_MEKGINEER_STEAMRIGGER = 1,
DATA_WARLORD_KALITHRESH = 2,
- DATA_DISTILLER = 3
+ DATA_DISTILLER = 3,
+
+ // Additional Data
+ DATA_ACCESS_PANEL_HYDRO = 4,
+ DATA_ACCESS_PANEL_MEK = 5
};
enum CreatureIds
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 22968d70ff1..6717bec109f 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -69,7 +69,7 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader
bool Load() override
{
- return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ return GetOwner()->GetTypeId() == TYPEID_PLAYER;
}
bool Validate(SpellInfo const* /*spellInfo*/) override
@@ -81,16 +81,16 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (Player* caster = GetCaster()->ToPlayer())
- if (Pet* pet = caster->GetPet())
- pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET);
+ Player* player = GetTarget()->ToPlayer();
+ if (Pet* pet = player->GetPet())
+ pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET);
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (Player* caster = GetCaster()->ToPlayer())
- if (caster->GetPet())
- caster->CastSpell(caster, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true);
+ Player* player = GetTarget()->ToPlayer();
+ if (player->GetPet())
+ player->CastSpell(player, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true);
}
void Register() override
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index e35f7c9b70e..28680c9d1ce 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -40,8 +40,6 @@ go_dragonflayer_cage
go_tadpole_cage
go_amberpine_outhouse
go_hive_pod
-go_gjalerbron_cage
-go_large_gjalerbron_cage
go_veil_skith_cage
EndContentData */
@@ -1111,69 +1109,6 @@ class go_massive_seaforium_charge : public GameObjectScript
};
/*######
-## go_gjalerbron_cage
-######*/
-
-enum OfKeysAndCages
-{
- QUEST_ALLIANCE_OF_KEYS_AND_CAGES = 11231,
- QUEST_HORDE_OF_KEYS_AND_CAGES = 11265,
- NPC_GJALERBRON_PRISONER = 24035,
- SAY_FREE = 0,
-};
-
-class go_gjalerbron_cage : public GameObjectScript
-{
- public:
- go_gjalerbron_cage() : GameObjectScript("go_gjalerbron_cage") { }
-
- bool OnGossipHello(Player* player, GameObject* go) override
- {
- go->UseDoorOrButton();
- if ((player->GetTeamId() == TEAM_ALLIANCE && player->GetQuestStatus(QUEST_ALLIANCE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE) ||
- (player->GetTeamId() == TEAM_HORDE && player->GetQuestStatus(QUEST_HORDE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE))
- {
- if (Creature* prisoner = go->FindNearestCreature(NPC_GJALERBRON_PRISONER, 5.0f))
- {
- player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER);
-
- prisoner->AI()->Talk(SAY_FREE);
- prisoner->DespawnOrUnsummon(6000);
- }
- }
- return true;
- }
-};
-
-/*########
-## go_large_gjalerbron_cage
-#####*/
-
-class go_large_gjalerbron_cage : public GameObjectScript
-{
- public:
- go_large_gjalerbron_cage() : GameObjectScript("go_large_gjalerbron_cage") { }
-
- bool OnGossipHello(Player* player, GameObject* go) override
- {
- go->UseDoorOrButton();
- if ((player->GetTeamId() == TEAM_ALLIANCE && player->GetQuestStatus(QUEST_ALLIANCE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE) ||
- (player->GetTeamId() == TEAM_HORDE && player->GetQuestStatus(QUEST_HORDE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE))
- {
- std::list<Creature*> prisonerList;
- GetCreatureListWithEntryInGrid(prisonerList, go, NPC_GJALERBRON_PRISONER, INTERACTION_DISTANCE);
- for (std::list<Creature*>::const_iterator itr = prisonerList.begin(); itr != prisonerList.end(); ++itr)
- {
- player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER, (*itr)->GetGUID());
- (*itr)->DespawnOrUnsummon(6000);
- (*itr)->AI()->Talk(SAY_FREE);
- }
- }
- return false;
- }
-};
-
-/*########
#### go_veil_skith_cage
#####*/
@@ -1293,8 +1228,6 @@ void AddSC_go_scripts()
new go_amberpine_outhouse();
new go_hive_pod();
new go_massive_seaforium_charge();
- new go_gjalerbron_cage();
- new go_large_gjalerbron_cage();
new go_veil_skith_cage();
new go_frostblade_shrine();
new go_midsummer_bonfire();
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
index 27e6cb63514..8ffb138379a 100644
--- a/src/server/shared/Common.h
+++ b/src/server/shared/Common.h
@@ -79,6 +79,9 @@
inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; }
+inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); }
+inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 10); }
+
#define STRINGIZE(a) #a
enum TimeConstants
diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h
index 2dcd4fbc161..a214af9d127 100644
--- a/src/server/shared/Networking/MessageBuffer.h
+++ b/src/server/shared/Networking/MessageBuffer.h
@@ -81,6 +81,14 @@ public:
}
}
+ // Ensures there's "some" free space, make sure to call Normalize() before this
+ void EnsureFreeSpace()
+ {
+ // Double the size of the buffer if it's already full
+ if (GetRemainingSpace() == 0)
+ _storage.resize(_storage.size() * 2);
+ }
+
void Write(void const* data, std::size_t size)
{
if (size)
diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h
index d3e29ceaaea..b4f1692aeb2 100644
--- a/src/server/shared/Networking/Socket.h
+++ b/src/server/shared/Networking/Socket.h
@@ -90,7 +90,8 @@ public:
return;
_readBuffer.Normalize();
- _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), READ_BLOCK_SIZE),
+ _readBuffer.EnsureFreeSpace();
+ _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h
index dbe2b8ec902..a62fe973dfa 100644
--- a/src/server/shared/Networking/SocketMgr.h
+++ b/src/server/shared/Networking/SocketMgr.h
@@ -46,7 +46,16 @@ public:
return false;
}
- _acceptor = new AsyncAcceptor(service, bindIp, port);
+ try
+ {
+ _acceptor = new AsyncAcceptor(service, bindIp, port);
+ }
+ catch (boost::system::system_error const& err)
+ {
+ TC_LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork (%s:%u): %s", bindIp.c_str(), port, err.what());
+ return false;
+ }
+
_threads = CreateThreads();
ASSERT(_threads);
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index faf6441fd72..6a1d9706b30 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -581,6 +581,22 @@ MinCharterName = 2
MinPetName = 2
#
+# Guild.CharterCost
+# ArenaTeam.CharterCost.2v2
+# ArenaTeam.CharterCost.3v3
+# ArenaTeam.CharterCost.5v5
+# Description: Amount of money (in Copper) the petitions costs.
+# Default: 1000 - (10 Silver)
+# 800000 - (80 Gold)
+# 1200000 - (120 Gold)
+# 2000000 - (200 Gold)
+
+Guild.CharterCost = 1000
+ArenaTeam.CharterCost.2v2 = 800000
+ArenaTeam.CharterCost.3v3 = 1200000
+ArenaTeam.CharterCost.5v5 = 2000000
+
+#
# MaxWhoListReturns
# Description: Set the max number of players returned in the /who list and interface.
# Default: 49 - (stable)
@@ -3028,7 +3044,7 @@ AuctionHouseBot.Buyer.Neutral.Chance.Ratio = 3
###################################################################################################
###################################################################################################
-# LOGGING SYSTEM SETTINGS
+# LOGGING SYSTEM SETTINGS
#
# Appender config values: Given a appender "name"
# Appender.name