aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp10
-rw-r--r--src/server/collision/Models/GameObjectModel.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp6
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp5
-rw-r--r--src/server/game/Entities/Player/Player.cpp25
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp14
-rw-r--r--src/server/game/Groups/Group.cpp18
-rw-r--r--src/server/game/Groups/GroupMgr.cpp2
-rw-r--r--src/server/game/Handlers/LootHandler.cpp2
-rw-r--r--src/server/game/Loot/LootMgr.cpp10
-rw-r--r--src/server/game/Miscellaneous/Language.h4
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp15
-rw-r--r--src/server/game/Spells/SpellInfo.cpp1
-rw-r--r--src/server/game/Tickets/TicketMgr.cpp4
-rw-r--r--src/server/game/Tools/CharacterDatabaseCleaner.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp187
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp15
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp34
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.h11
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_erekem.cpp271
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp389
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp97
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_moragg.cpp211
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp297
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp114
-rw-r--r--src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp34
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.cpp195
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.h4
-rw-r--r--src/server/scripts/Northrend/isle_of_conquest.cpp13
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp56
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp46
-rw-r--r--src/server/shared/Threading/Callback.h2
-rw-r--r--src/tools/map_extractor/adt.h8
34 files changed, 1462 insertions, 646 deletions
diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp
index 0355d2e848c..dd1502c45b0 100644
--- a/src/server/collision/Models/GameObjectModel.cpp
+++ b/src/server/collision/Models/GameObjectModel.cpp
@@ -186,12 +186,12 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
return hit;
}
-bool GameObjectModel::Relocate(const GameObject& go)
+bool GameObjectModel::UpdatePosition()
{
if (!iModel)
return false;
- ModelList::const_iterator it = model_list.find(go.GetDisplayId());
+ ModelList::const_iterator it = model_list.find(owner->GetDisplayId());
if (it == model_list.end())
return false;
@@ -203,9 +203,9 @@ bool GameObjectModel::Relocate(const GameObject& go)
return false;
}
- iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ());
+ iPos = Vector3(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ());
- G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0);
+ G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0);
iInvRot = iRotation.inverse();
// transform bounding box:
mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
@@ -219,7 +219,7 @@ bool GameObjectModel::Relocate(const GameObject& go)
for (int i = 0; i < 8; ++i)
{
Vector3 pos(iBound.corner(i));
- go.SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN);
+ owner->SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN);
}
#endif
diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h
index 232ebbee5e9..43d299d6d8f 100644
--- a/src/server/collision/Models/GameObjectModel.h
+++ b/src/server/collision/Models/GameObjectModel.h
@@ -68,7 +68,7 @@ public:
static GameObjectModel* Create(const GameObject& go);
- bool Relocate(GameObject const& go);
+ bool UpdatePosition();
};
#endif // _GAMEOBJECT_MODEL_H
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index a91bbf00735..3b9b6d9dfe8 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1370,6 +1370,12 @@ bool Creature::CanStartAttack(Unit const* who, bool force) const
if (IsCivilian())
return false;
+ // This set of checks is should be done only for creatures
+ if ((HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC) && who->GetTypeId() != TYPEID_PLAYER) // flag is valid only for non player characters
+ || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) && who->GetTypeId() == TYPEID_PLAYER) // immune to PC and target is a player, return false
+ || (who->GetOwner() && who->GetOwner()->GetTypeId() == TYPEID_PLAYER) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) // player pets are immune to pc as well
+ return false;
+
// Do not attack non-combat pets
if (who->GetTypeId() == TYPEID_UNIT && who->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
return false;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index a4b140b9878..50981a163be 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1757,6 +1757,9 @@ void GameObject::Use(Unit* user)
return;
}
+ if (Player* player = user->ToPlayer())
+ sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this);
+
if (spellCaster)
spellCaster->CastSpell(user, spellInfo, triggered);
else
@@ -2314,7 +2317,7 @@ void GameObject::UpdateModelPosition()
if (GetMap()->ContainsGameObjectModel(*m_model))
{
GetMap()->RemoveGameObjectModel(*m_model);
- m_model->Relocate(*this);
+ m_model->UpdatePosition();
GetMap()->InsertGameObjectModel(*m_model);
}
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 275dbf92dca..55d882c65d3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -9616,13 +9616,9 @@ void Player::SendBattlefieldWorldStates()
{
if (BattlefieldWG* wg = (BattlefieldWG*)sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
{
- if (wg->IsWarTime())
- SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL)));
- else // Time to next battle
- {
- uint32 timer = wg->GetTimer() / 1000;
- SendUpdateWorldState(ClockWorldState[1], time(NULL) + timer);
- }
+ SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, wg->IsWarTime() ? 0 : 1);
+ uint32 timer = wg->IsWarTime() ? 0 : (wg->GetTimer() / 1000); // 0 - Time to next battle
+ SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL) + timer));
}
}
}
@@ -17052,8 +17048,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
//"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
// 39 40 41 42 43 44 45 46 47 48 49
//"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
- // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
- //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
+ // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
+ //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
{
@@ -17812,9 +17808,9 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
TC_LOG_DEBUG("entities.player.loading", "Loading auras for player %u", GetGUIDLow());
/* 0 1 2 3 4 5 6 7 8 9 10
- QueryResult* result = CharacterDatabase.PQuery("SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
+ QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
11 12 13
- maxduration, remaintime, remaincharges FROM character_aura WHERE guid = '%u'", GetGUIDLow());
+ maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUIDLow());
*/
if (result)
@@ -23657,6 +23653,9 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
if (player->GetMapId() != pRewardSource->GetMapId() || player->GetInstanceId() != pRewardSource->GetInstanceId())
return false;
+ if (player->GetMap()->IsDungeon())
+ return true;
+
return pRewardSource->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE);
}
@@ -25621,7 +25620,7 @@ void Player::SetMap(Map* map)
void Player::_LoadGlyphs(PreparedQueryResult result)
{
- // SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 from character_glyphs WHERE guid = '%u'
+ // SELECT talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 from character_glyphs WHERE guid = '%u'
if (!result)
return;
@@ -25668,7 +25667,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans)
void Player::_LoadTalents(PreparedQueryResult result)
{
- // SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, spec FROM character_talent WHERE guid = '%u'", GUID_LOPART(m_guid));
+ // SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, talentGroup FROM character_talent WHERE guid = '%u'", GUID_LOPART(m_guid));
if (result)
{
do
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9b0da57fa31..b9d4650de47 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12322,15 +12322,15 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
// Apply strongest slow aura mod to speed
int32 slow = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
if (slow)
- {
AddPct(speed, slow);
- if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
- {
- float min_speed = minSpeedMod / 100.0f;
- if (speed < min_speed)
- speed = min_speed;
- }
+
+ if (float minSpeedMod = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED))
+ {
+ float min_speed = minSpeedMod / 100.0f;
+ if (speed < min_speed)
+ speed = min_speed;
}
+
SetSpeed(mtype, speed, forced);
}
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 2e81bdd1af8..f89c0e73008 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -936,7 +936,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
continue;
if (i->AllowedForPlayer(member))
{
- if (member->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (member->IsAtGroupRewardDistance(pLootedObject))
{
r->totalPlayersRolling++;
@@ -1021,7 +1021,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
if (i->AllowedForPlayer(member))
{
- if (member->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (member->IsAtGroupRewardDistance(pLootedObject))
{
r->totalPlayersRolling++;
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
@@ -1080,7 +1080,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
- if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
if (playerToRoll->GetPassOnGroupLoot())
@@ -1155,7 +1155,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
- if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
@@ -1231,7 +1231,7 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
if (!looter->IsInWorld())
continue;
- if (looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (looter->IsAtGroupRewardDistance(pLootedObject))
{
data << uint64(looter->GetGUID());
++real_count;
@@ -1243,7 +1243,7 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* looter = itr->GetSource();
- if (looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (looter->IsAtGroupRewardDistance(pLootedObject))
looter->GetSession()->SendPacket(&data);
}
}
@@ -1743,7 +1743,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
{
// not update if only update if need and ok
Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
- if (looter && looter->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (looter && looter->IsAtGroupRewardDistance(pLootedObject))
return;
}
++guid_itr;
@@ -1754,7 +1754,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
{
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
- if (player->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (player->IsAtGroupRewardDistance(pLootedObject))
{
pNewLooter = player;
break;
@@ -1767,7 +1767,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
{
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
- if (player->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (player->IsAtGroupRewardDistance(pLootedObject))
{
pNewLooter = player;
break;
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 771fcb17b32..ab80a208765 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -124,7 +124,7 @@ void GroupMgr::LoadGroups()
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = CharacterDatabase.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6"
// 10 11 12 13 14 15 16 17 18
- ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
+ ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raidDifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `groups` is empty!");
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index b4f19234df9..26d1737257e 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -176,7 +176,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
if (!member)
continue;
- if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ if (player->IsAtGroupRewardDistance(member))
playersNear.push_back(member);
}
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index ba4e4713458..c825db1e1eb 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -151,14 +151,8 @@ uint32 LootStore::LoadLootTable()
bool needsquest = fields[4].GetBool();
uint16 lootmode = fields[5].GetUInt16();
uint8 groupid = fields[6].GetUInt8();
- int32 mincount = fields[7].GetUInt8();
- int32 maxcount = fields[8].GetUInt8();
-
- if (maxcount > std::numeric_limits<uint8>::max())
- {
- TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d Item %d: MaxCount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount, std::numeric_limits<uint8>::max());
- continue; // error already printed to log/console.
- }
+ uint8 mincount = fields[7].GetUInt8();
+ uint8 maxcount = fields[8].GetUInt8();
if (groupid >= 1 << 7) // it stored in 7 bit field
{
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 9bae8fbdfae..63390ad61da 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -971,15 +971,15 @@ enum TrinityStrings
LANG_GUILD_INFO_BANK_GOLD = 1181,
LANG_GUILD_INFO_MOTD = 1182,
LANG_GUILD_INFO_EXTRA_INFO = 1183,
- // Room for more level 3 1184-1199 not used
+ // Room for more level 3 1184-1198 not used
// Debug commands
+ LANG_DO_NOT_USE_6X_DEBUG_AREATRIGGER_LEFT = 1999,
LANG_CINEMATIC_NOT_EXIST = 1200,
LANG_MOVIE_NOT_EXIST = 1201,
LANG_DEBUG_AREATRIGGER_ON = 1202,
LANG_DEBUG_AREATRIGGER_OFF = 1203,
LANG_DEBUG_AREATRIGGER_REACHED = 1204,
- // Room for more debug 1205-1299 not used
// Isle of Conquest
LANG_BG_IC_START_TWO_MINUTES = 1205,
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index afd1f73c785..2aebac6beb4 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -116,7 +116,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32
}
if (distance)
- *distance = dtSqrt(minDist3d);
+ *distance = dtMathSqrtf(minDist3d);
return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF;
}
@@ -799,7 +799,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
// Find movement delta.
float delta[VERTEX_SIZE];
dtVsub(delta, steerPos, iterPos);
- float len = dtSqrt(dtVdot(delta, delta));
+ float len = dtMathSqrtf(dtVdot(delta, delta));
// If the steer target is end of path or off-mesh link, do not move past the location.
if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE)
len = 1.0f;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3829e12b790..965b2463139 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3100,19 +3100,18 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
if (m_spellInfo->Id == 62124)
m_caster->CastSpell(unitTarget, 67485, true);
- // Also use this effect to set the taunter's threat to the taunted creature's highest value
- if (unitTarget->getThreatManager().getCurrentVictim())
+ if (!unitTarget->getThreatManager().getOnlineContainer().empty())
{
+ // Also use this effect to set the taunter's threat to the taunted creature's highest value
float myThreat = unitTarget->getThreatManager().getThreat(m_caster);
- float itsThreat = unitTarget->getThreatManager().getCurrentVictim()->getThreat();
- if (itsThreat > myThreat)
- unitTarget->getThreatManager().addThreat(m_caster, itsThreat - myThreat);
- }
+ float topThreat = unitTarget->getThreatManager().getOnlineContainer().getMostHated()->getThreat();
+ if (topThreat > myThreat)
+ unitTarget->getThreatManager().doAddThreat(m_caster, topThreat - myThreat);
- //Set aggro victim to caster
- if (!unitTarget->getThreatManager().getOnlineContainer().empty())
+ //Set aggro victim to caster
if (HostileReference* forcedVictim = unitTarget->getThreatManager().getOnlineContainer().getReferenceByTarget(m_caster))
unitTarget->getThreatManager().setCurrentVictim(forcedVictim);
+ }
if (unitTarget->ToCreature()->IsAIEnabled && !unitTarget->ToCreature()->HasReactState(REACT_PASSIVE))
unitTarget->ToCreature()->AI()->AttackStart(m_caster);
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 789b95e3e14..ea5e4c8df0b 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1489,6 +1489,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
if (player && !player->CanFlyInZone(map_id, zone_id))
return SPELL_FAILED_INCORRECT_AREA;
}
+ break;
}
}
}
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index db37989bfc3..3d26f349ca5 100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -296,7 +296,7 @@ void TicketMgr::LoadTickets()
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
{
- TC_LOG_INFO("server.loading", ">> Loaded 0 GM tickets. DB table `gm_tickets` is empty!");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 GM tickets. DB table `gm_ticket` is empty!");
return;
}
@@ -333,7 +333,7 @@ void TicketMgr::LoadSurveys()
_lastSurveyId = 0;
uint32 oldMSTime = getMSTime();
- if (QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyId) FROM gm_surveys"))
+ if (QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyId) FROM gm_survey"))
_lastSurveyId = (*result)[0].GetUInt32();
TC_LOG_INFO("server.loading", ">> Loaded GM Survey count from database in %u ms", GetMSTimeDiffToNow(oldMSTime));
diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
index 78bc1b799de..815212aa53d 100644
--- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp
+++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
@@ -147,7 +147,7 @@ bool CharacterDatabaseCleaner::TalentCheck(uint32 talent_id)
void CharacterDatabaseCleaner::CleanCharacterTalent()
{
- CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE spec > %u", MAX_TALENT_SPECS);
+ CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE talentGroup > %u", MAX_TALENT_SPECS);
CheckUnique("spell", "character_talent", &TalentCheck);
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index ad510682e15..04ea31bd1dd 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -26,14 +26,6 @@
#include "ruby_sanctum.h"
#include "Player.h"
-/* ScriptData
-SDName: ruby_sanctum
-SDAuthors: Kaelima, Warpten
-SD%Complete: 90%
-SDComment: Based on Kaelima's initial work (half of it). Corporeality handling is a pure guess, we lack info.
-SDCategory: Chamber of Aspects
-EndScriptData */
-
enum Texts
{
// Shared
@@ -87,6 +79,8 @@ enum Spells
// Living Inferno
SPELL_BLAZING_AURA = 75885,
+ SPELL_SPAWN_LIVING_EMBERS = 75880,
+ SPELL_SUMMON_LIVING_EMBER = 75881,
// Halion Controller
SPELL_COSMETIC_FIRE_PILLAR = 76006,
@@ -143,7 +137,7 @@ enum Events
EVENT_CHECK_CORPOREALITY = 14,
EVENT_SHADOW_PULSARS_SHOOT = 15,
EVENT_TRIGGER_BERSERK = 16,
- EVENT_TWILIGHT_MENDING = 17
+ EVENT_TWILIGHT_MENDING = 17,
};
enum Actions
@@ -156,7 +150,13 @@ enum Actions
ACTION_MONITOR_CORPOREALITY = 3,
// Orb Carrier
- ACTION_SHOOT = 4
+ ACTION_SHOOT = 4,
+
+ // Living Inferno
+ ACTION_SUMMON_LIVING_EMBERS = 5,
+
+ // Meteor Flame
+ ACTION_SUMMON_FLAME = 6
};
enum Phases
@@ -174,7 +174,8 @@ enum Misc
DATA_MATERIAL_DAMAGE_TAKEN = 2,
DATA_STACKS_DISPELLED = 3,
DATA_FIGHT_PHASE = 4,
- DATA_EVADE_METHOD = 5
+ DATA_EVADE_METHOD = 5,
+ DATA_SPAWNED_FLAMES = 6,
};
enum OrbCarrierSeats
@@ -703,7 +704,7 @@ class npc_halion_controller : public CreatureScript
// The IsInCombat() check is needed because that check should be false when Halion is
// not engaged, while it would return true without as UpdateVictim() checks for
// combat state.
- if (!(_events.IsInPhase(PHASE_INTRO)) && me->IsInCombat() && !UpdateVictim())
+ if (!_events.IsInPhase(PHASE_INTRO) && me->IsInCombat() && !UpdateVictim())
{
EnterEvadeMode();
return;
@@ -894,8 +895,6 @@ class npc_halion_controller : public CreatureScript
}
};
-typedef npc_halion_controller::npc_halion_controllerAI controllerAI;
-
class npc_orb_carrier : public CreatureScript
{
public:
@@ -997,7 +996,7 @@ class npc_meteor_strike_initial : public CreatureScript
if (!owner)
return;
- // Let Halion Controller count as summoner
+ // Let Controller count as summoner
if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
controller->AI()->JustSummoned(me);
@@ -1007,11 +1006,13 @@ class npc_meteor_strike_initial : public CreatureScript
if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
{
Position const* ownerPos = halionAI->GetMeteorStrikePosition();
+ // Adjust randomness between 0 and pi.
+ float randomAdjustment = frand(static_cast<float>(M_PI / 14), static_cast<float>(13 * M_PI / 14));
float angle[4];
angle[0] = me->GetAngle(ownerPos);
- angle[1] = me->GetAngle(ownerPos) - static_cast<float>(M_PI/2);
- angle[2] = me->GetAngle(ownerPos) - static_cast<float>(-M_PI/2);
- angle[3] = me->GetAngle(ownerPos) - static_cast<float>(M_PI);
+ angle[1] = angle[0] + randomAdjustment;
+ angle[2] = angle[0] + static_cast<float>(M_PI);
+ angle[3] = angle[2] + randomAdjustment;
_meteorList.clear();
for (uint8 i = 0; i < 4; i++)
@@ -1020,7 +1021,10 @@ class npc_meteor_strike_initial : public CreatureScript
me->SetOrientation(angle[i]);
Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30000))
+ {
+ meteor->SetOrientation(angle[i]);
_meteorList.push_back(meteor);
+ }
}
}
}
@@ -1046,11 +1050,8 @@ class npc_meteor_strike : public CreatureScript
struct npc_meteor_strikeAI : public ScriptedAI
{
npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
+ _instance(creature->GetInstanceScript()), _spawnCount(0)
{
- _range = 5.0f;
- _spawnCount = 0;
-
SetCombatMovement(false);
}
@@ -1071,34 +1072,38 @@ class npc_meteor_strike : public CreatureScript
controller->AI()->JustSummoned(me);
}
- void UpdateAI(uint32 diff) override
+ void SetData(uint32 dataType, uint32 dataCount) override
{
- if (_spawnCount > 5)
- return;
+ if (dataType == DATA_SPAWNED_FLAMES)
+ _spawnCount += dataCount;
+ }
- _events.Update(diff);
+ uint32 GetData(uint32 dataType) const override
+ {
+ if (dataType == DATA_SPAWNED_FLAMES)
+ return _spawnCount;
+ return 0;
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME)
{
- Position pos = me->GetNearPosition( _range, 0.0f);
-
+ Position pos = me->GetNearPosition(5.0f, 0.0f);
if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000))
{
- if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
- controller->AI()->JustSummoned(flame);
+ flame->SetOrientation(me->GetOrientation());
- flame->CastSpell(flame, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
- ++_spawnCount;
+ flame->AI()->SetGUID(GetGUID());
+ flame->AI()->DoAction(ACTION_SUMMON_FLAME);
}
- _range += 5.0f;
- _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800);
}
}
private:
InstanceScript* _instance;
EventMap _events;
- float _range;
uint8 _spawnCount;
};
@@ -1108,6 +1113,67 @@ class npc_meteor_strike : public CreatureScript
}
};
+class npc_meteor_strike_flame : public CreatureScript
+{
+ public:
+ npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { }
+
+ struct npc_meteor_strike_flameAI : public ScriptedAI
+ {
+ npc_meteor_strike_flameAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
+ }
+
+ void SetGUID(ObjectGuid guid, int32 id /* = 0 */) override
+ {
+ _rootOwnerGuid = guid;
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action != ACTION_SUMMON_FLAME || _rootOwnerGuid.IsEmpty())
+ return;
+
+ me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
+
+ Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid);
+ if (!meteorStrike || meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
+ return;
+
+ me->SetOrientation(me->GetOrientation() + frand(static_cast<float>(-M_PI / 16), static_cast<float>(M_PI / 16)));
+ Position pos = me->GetNearPosition(5.0f, 0.0f);
+
+ if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000))
+ {
+ flame->AI()->SetGUID(_rootOwnerGuid);
+ meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
+ }
+ }
+
+ void IsSummonedBy(Unit* /*summoner*/) override
+ {
+ // Let Halion Controller count as summoner.
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER)))
+ controller->AI()->JustSummoned(me);
+ }
+
+ void UpdateAI(uint32 diff) override { }
+ void EnterEvadeMode() override { }
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ ObjectGuid _rootOwnerGuid = ObjectGuid::Empty;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature);
+ }
+};
+
class npc_combustion_consumption : public CreatureScript
{
public:
@@ -1120,26 +1186,23 @@ class npc_combustion_consumption : public CreatureScript
{
SetCombatMovement(false);
- switch (me->GetEntry())
+ switch (creature->GetEntry())
{
case NPC_COMBUSTION:
_explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION;
_damageSpell = SPELL_COMBUSTION_DAMAGE_AURA;
- me->SetPhaseMask(0x01, true);
+ creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true);
break;
case NPC_CONSUMPTION:
_explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION;
_damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA;
- me->SetPhaseMask(0x20, true);
+ creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true);
break;
default: // Should never happen
_explosionSpell = 0;
_damageSpell = 0;
break;
}
-
- if (IsHeroic())
- me->SetPhaseMask(0x01 | 0x20, true);
}
void IsSummonedBy(Unit* summoner) override
@@ -1161,7 +1224,7 @@ class npc_combustion_consumption : public CreatureScript
me->CastCustomSpell(SPELL_SCALE_AURA, SPELLVALUE_AURA_STACK, stackAmount, me);
DoCast(me, _damageSpell);
- int32 damage = 1200 + (stackAmount * 1290); // Needs more researches.
+ int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
summoner->CastCustomSpell(_explosionSpell, SPELLVALUE_BASE_POINT0, damage, summoner);
}
@@ -1194,6 +1257,10 @@ class npc_living_inferno : public CreatureScript
me->SetInCombatWithZone();
me->CastSpell(me, SPELL_BLAZING_AURA, true);
+ // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
+ if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
+ me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true);
+
if (InstanceScript* instance = me->GetInstanceScript())
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER)))
controller->AI()->JustSummoned(me);
@@ -1211,7 +1278,6 @@ class npc_living_inferno : public CreatureScript
}
};
-//! Need sniff data
class npc_living_ember : public CreatureScript
{
public:
@@ -1739,12 +1805,46 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader
}
};
+class spell_halion_spawn_living_embers : public SpellScriptLoader
+{
+ public:
+ spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { }
+
+ class spell_halion_spawn_living_embers_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_halion_spawn_living_embers_SpellScript);
+
+ void SelectMeteorFlames(std::list<WorldObject*>& unitList)
+ {
+ if (!unitList.empty())
+ Trinity::Containers::RandomResizeList(unitList, 10);
+ }
+
+ void HandleScript(SpellEffIndex /* effIndex */)
+ {
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers_SpellScript::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_halion_spawn_living_embers_SpellScript();
+ }
+};
+
void AddSC_boss_halion()
{
new boss_halion();
new boss_twilight_halion();
new npc_halion_controller();
+ new npc_meteor_strike_flame();
new npc_meteor_strike_initial();
new npc_meteor_strike();
new npc_combustion_consumption();
@@ -1766,4 +1866,5 @@ void AddSC_boss_halion()
new spell_halion_twilight_phasing();
new spell_halion_twilight_cutter();
new spell_halion_clear_debuffs();
+ new spell_halion_spawn_living_embers();
}
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
index c3f5c75e059..737a5d5c982 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
@@ -229,6 +229,21 @@ class instance_oculus : public InstanceMapScript
return true;
}
+ uint32 GetData(uint32 type) const override
+ {
+ if (type == DATA_CONSTRUCTS)
+ {
+ if (CentrifugueConstructCounter == 0)
+ return KILL_NO_CONSTRUCT;
+ else if (CentrifugueConstructCounter == 1)
+ return KILL_ONE_CONSTRUCT;
+ else if (CentrifugueConstructCounter > 1)
+ return KILL_MORE_CONSTRUCT;
+ }
+
+ return KILL_NO_CONSTRUCT;
+ }
+
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index 450f97cb9b7..3ab9814b5b5 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -20,6 +20,7 @@
#include "ScriptedGossip.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellInfo.h"
#include "CombatAI.h"
#include "Player.h"
#include "Vehicle.h"
@@ -76,6 +77,11 @@ enum Drakes
SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, // (60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25, 000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
// you do not have access to until you kill the Mage-Lord Urom
SPELL_EMERALD_DREAM_FUNNEL = 50344, // (60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
+/*
+ * All Drakes
+ * GPS System
+ */
+ SPELL_GPS = 53389,
// Misc
POINT_LAND = 2,
@@ -101,7 +107,13 @@ enum Says
WHISPER_DRAKES_WELCOME = 1,
WHISPER_DRAKES_ABILITIES = 2,
WHISPER_DRAKES_SPECIAL = 3,
- WHISPER_DRAKES_LOWHEALTH = 4
+ WHISPER_DRAKES_LOWHEALTH = 4,
+ WHISPER_GPS_10_CONSTRUCTS = 5,
+ WHISPER_GPS_1_CONSTRUCT = 6,
+ WHISPER_GPS_VAROS = 7,
+ WHISPER_GPS_UROM = 8,
+ WHISPER_GPS_EREGOS = 9,
+ WHISPER_GPS_END = 10
};
class npc_verdisa_beglaristrasz_eternos : public CreatureScript
@@ -250,6 +262,26 @@ class npc_ruby_emerald_amber_drake : public CreatureScript
Initialize();
}
+ void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
+ {
+ if (Unit* creator = ObjectAccessor::GetUnit(*me, me->GetCreatorGUID()))
+ if (spell->Id == SPELL_GPS)
+ {
+ if (_instance->GetBossState(DATA_EREGOS) == DONE)
+ Talk(WHISPER_GPS_END, creator);
+ else if (_instance->GetBossState(DATA_UROM) == DONE)
+ Talk(WHISPER_GPS_EREGOS, creator);
+ else if (_instance->GetBossState(DATA_VAROS) == DONE)
+ Talk(WHISPER_GPS_UROM, creator);
+ else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_NO_CONSTRUCT)
+ Talk(WHISPER_GPS_VAROS, creator);
+ else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_ONE_CONSTRUCT)
+ Talk(WHISPER_GPS_1_CONSTRUCT, creator);
+ else if (_instance->GetData(DATA_CONSTRUCTS) == KILL_MORE_CONSTRUCT)
+ Talk(WHISPER_GPS_10_CONSTRUCTS, creator);
+ }
+ }
+
void IsSummonedBy(Unit* summoner) override
{
if (_instance->GetBossState(DATA_EREGOS) == IN_PROGRESS)
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
index fd46f0a6bcc..08fc15c5752 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
@@ -29,7 +29,9 @@ enum DataTypes
DATA_DRAKOS = 0,
DATA_VAROS = 1,
DATA_UROM = 2,
- DATA_EREGOS = 3
+ DATA_EREGOS = 3,
+ // GPS System
+ DATA_CONSTRUCTS = 4
};
enum CreatureIds
@@ -91,6 +93,13 @@ enum InstanceEvents
EVENT_EREGOS_INTRO
};
+enum ConstructKillState
+{
+ KILL_NO_CONSTRUCT = 0,
+ KILL_ONE_CONSTRUCT = 1,
+ KILL_MORE_CONSTRUCT = 2
+};
+
enum Misc
{
POINT_MOVE_OUT = 1
diff --git a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
index 5c8d4b8691a..1f9fc6d7981 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
@@ -27,7 +27,8 @@ enum Spells
SPELL_EARTH_SHIELD = 54479,
SPELL_EARTH_SHOCK = 54511,
SPELL_LIGHTNING_BOLT = 53044,
- SPELL_STORMSTRIKE = 51876
+ SPELL_STORMSTRIKE = 51876,
+ SPELL_WINDFURY = 54493
};
enum Yells
@@ -40,11 +41,27 @@ enum Yells
SAY_BOTH_ADDS_KILLED = 5
};
+enum ErekemEvents
+{
+ EVENT_EARTH_SHIELD = 1,
+ EVENT_CHAIN_HEAL,
+ EVENT_BLOODLUST,
+ EVENT_LIGHTNING_BOLT,
+ EVENT_EARTH_SHOCK,
+ EVENT_WINDFURY,
+ EVENT_STORMSTRIKE
+};
+
class boss_erekem : public CreatureScript
{
public:
boss_erekem() : CreatureScript("boss_erekem") { }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_erekemAI>(creature);
+ }
+
struct boss_erekemAI : public ScriptedAI
{
boss_erekemAI(Creature* creature) : ScriptedAI(creature)
@@ -55,39 +72,50 @@ public:
void Initialize()
{
- uiBloodlustTimer = 15000;
- uiChainHealTimer = 0;
- uiEarthShockTimer = urand(2000, 8000);
- uiLightningBoltTimer = urand(5000, 10000);
- uiEarthShieldTimer = 20000;
+ phase = 0;
+ breakBondsCd = 0;
}
- uint32 uiBloodlustTimer;
- uint32 uiChainHealTimer;
- uint32 uiEarthShockTimer;
- uint32 uiLightningBoltTimer;
- uint32 uiEarthShieldTimer;
-
- InstanceScript* instance;
-
void Reset() override
{
Initialize();
+
if (instance->GetData(DATA_WAVE_COUNT) == 6)
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
{
- if (!pGuard1->IsAlive())
- pGuard1->Respawn();
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ pGuard1->DespawnOrUnsummon();
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ pGuard2->DespawnOrUnsummon();
}
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ else
{
- if (!pGuard2->IsAlive())
- pGuard2->Respawn();
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ {
+ if (!pGuard1->IsAlive())
+ pGuard1->Respawn();
+ }
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ {
+ if (!pGuard2->IsAlive())
+ pGuard2->Respawn();
+ }
}
+
+ events.Reset();
+ }
+
+ void JustReachedHome() override
+ {
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ pGuard1->Respawn();
+
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ pGuard2->Respawn();
}
void AttackStart(Unit* who) override
@@ -104,13 +132,13 @@ public:
if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
{
- pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
+ pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
if (!pGuard1->GetVictim() && pGuard1->AI())
pGuard1->AI()->AttackStart(who);
}
if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
{
- pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
+ pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
if (!pGuard2->GetVictim() && pGuard2->AI())
pGuard2->AI()->AttackStart(who);
}
@@ -133,68 +161,13 @@ public:
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
- }
-
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- //spam stormstrike in hc mode if spawns are dead
- if (IsHeroic())
- {
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
- {
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- {
- if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
- DoCastVictim(SPELL_STORMSTRIKE);
- }
- }
- }
-
- if (uiEarthShieldTimer <= diff)
- {
- DoCast(me, SPELL_EARTH_SHIELD);
- uiEarthShieldTimer = 20000;
- } else uiEarthShieldTimer -= diff;
-
- if (uiChainHealTimer <= diff)
- {
- if (ObjectGuid TargetGUID = GetChainHealTargetGUID())
- {
- if (Creature* target = ObjectAccessor::GetCreature(*me, TargetGUID))
- DoCast(target, SPELL_CHAIN_HEAL);
-
- //If one of the adds is dead spawn heals faster
- Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
- Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
- uiChainHealTimer = ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000) + rand32() % 3000;
- }
- } else uiChainHealTimer -= diff;
-
- if (uiBloodlustTimer <= diff)
- {
- DoCast(me, SPELL_BLOODLUST);
- uiBloodlustTimer = urand(35000, 45000);
- } else uiBloodlustTimer -= diff;
- if (uiEarthShockTimer <= diff)
- {
- DoCastVictim(SPELL_EARTH_SHOCK);
- uiEarthShockTimer = urand(8000, 13000);
- } else uiEarthShockTimer -= diff;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_NPC);
- if (uiLightningBoltTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_LIGHTNING_BOLT);
- uiLightningBoltTimer = urand(18000, 24000);
- } else uiLightningBoltTimer -= diff;
-
- DoMeleeAttackIfReady();
+ events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
+ events.ScheduleEvent(EVENT_BLOODLUST, 15000);
+ events.ScheduleEvent(EVENT_CHAIN_HEAL, 10000);
+ events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2000);
}
void JustDied(Unit* /*killer*/) override
@@ -219,27 +192,118 @@ public:
Talk(SAY_SLAY);
}
- ObjectGuid GetChainHealTargetGUID()
+ void UpdateAI(uint32 diff) override
{
- if (HealthBelowPct(85))
- return me->GetGUID();
+ if (!UpdateVictim())
+ return;
- Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
- if (pGuard1 && pGuard1->IsAlive() && !pGuard1->HealthAbovePct(75))
- return pGuard1->GetGUID();
+ if (phase == 0)
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ {
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ {
+ if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
+ {
+ phase = 1;
+ DoCastVictim(SPELL_STORMSTRIKE);
+ DoCast(SPELL_WINDFURY);
+ events.Reset();
+ events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(2000, 8000));
+ events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
+ events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
+ }
+ }
+ }
- Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
- if (pGuard2 && pGuard2->IsAlive() && !pGuard2->HealthAbovePct(75))
- return pGuard2->GetGUID();
+ events.Update(diff);
- return ObjectGuid::Empty;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ if (breakBondsCd <= 0)
+ {
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ {
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
+ {
+ if (pGuard1->IsAlive())
+ {
+ if (pGuard1->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard1->HasAuraType(SPELL_AURA_MOD_ROOT)
+ || pGuard1->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard1->HasAuraType(SPELL_AURA_MOD_PACIFY)
+ || pGuard1->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
+ {
+ DoCast(SPELL_BREAK_BONDS);
+ breakBondsCd = 10000;
+ return;
+ }
+ }
+ if (pGuard2->IsAlive())
+ {
+ if (pGuard2->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard2->HasAuraType(SPELL_AURA_MOD_ROOT)
+ || pGuard2->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard2->HasAuraType(SPELL_AURA_MOD_PACIFY)
+ || pGuard2->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
+ {
+ DoCast(SPELL_BREAK_BONDS);
+ breakBondsCd = 10000;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ breakBondsCd -= diff;
+
+ switch (uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_EARTH_SHIELD:
+ if (Unit* ally = DoSelectLowestHpFriendly(30.0f))
+ DoCast(ally, SPELL_EARTH_SHIELD);
+ events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
+ break;
+ case EVENT_BLOODLUST:
+ DoCast(SPELL_BLOODLUST);
+ events.ScheduleEvent(EVENT_BLOODLUST, urand(35000, 45000));
+ break;
+ case EVENT_LIGHTNING_BOLT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_LIGHTNING_BOLT);
+ events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2500);
+ break;
+ case EVENT_CHAIN_HEAL:
+ if (Unit* ally = DoSelectLowestHpFriendly(40.0f))
+ DoCast(ally, SPELL_CHAIN_HEAL);
+ {
+ Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
+ Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
+ events.ScheduleEvent(EVENT_CHAIN_HEAL, ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000 + rand() % 3000));
+ }
+ break;
+ case EVENT_EARTH_SHOCK:
+ DoCastVictim(SPELL_EARTH_SHOCK);
+ events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(8000, 13000));
+ break;
+ case EVENT_WINDFURY:
+ DoCast(SPELL_WINDFURY);
+ events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
+ break;
+ case EVENT_STORMSTRIKE:
+ DoCastVictim(SPELL_STORMSTRIKE);
+ events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
+ break;
+ default:
+ break;
+ }
+
+ DoMeleeAttackIfReady();
}
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_erekemAI>(creature);
- }
+ private:
+ EventMap events;
+ InstanceScript* instance;
+ uint8 phase;
+ int32 breakBondsCd;
+ };
};
enum GuardSpells
@@ -254,6 +318,11 @@ class npc_erekem_guard : public CreatureScript
public:
npc_erekem_guard() : CreatureScript("npc_erekem_guard") { }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_erekem_guardAI>(creature);
+ }
+
struct npc_erekem_guardAI : public ScriptedAI
{
npc_erekem_guardAI(Creature* creature) : ScriptedAI(creature)
@@ -278,6 +347,9 @@ public:
void Reset() override
{
Initialize();
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
}
void AttackStart(Unit* who) override
@@ -322,11 +394,6 @@ public:
} else uiGushingWoundTimer -= diff;
}
};
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_erekem_guardAI>(creature);
- }
};
void AddSC_boss_erekem()
diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
index 9be73febd52..137f63a381d 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
@@ -27,12 +27,16 @@ enum Spells
SPELL_WATER_BLAST = 54237,
SPELL_WATER_BOLT_VOLLEY = 54241,
SPELL_SPLASH = 59516,
- SPELL_WATER_GLOBULE = 54268
+ SPELL_BURST = 54379,
+ SPELL_WATER_GLOBULE = 54268,
+ SPELL_MERGE = 54269,
+ SPELL_WATER_GLOBULE_VISUAL = 54260
};
enum IchoronCreatures
{
- NPC_ICHOR_GLOBULE = 29321
+ NPC_ICHOR_GLOBULE = 29321,
+ NPC_ICHORON_SUMMON_TARGET = 29326
};
enum Yells
@@ -48,26 +52,48 @@ enum Yells
enum Actions
{
- ACTION_WATER_ELEMENT_HIT = 1,
- ACTION_WATER_ELEMENT_KILLED = 2
+ ACTION_WATER_ELEMENT_HIT = 1
};
-/// @todo get those positions from spawn of creature 29326
-#define MAX_SPAWN_LOC 5
-static Position const SpawnLoc[MAX_SPAWN_LOC]=
+enum IchoronEvents
{
- {1840.64f, 795.407f, 44.079f, 1.676f},
- {1886.24f, 757.733f, 47.750f, 5.201f},
- {1877.91f, 845.915f, 43.417f, 3.560f},
- {1918.97f, 850.645f, 47.225f, 4.136f},
- {1935.50f, 796.224f, 52.492f, 4.224f}
+ EVENT_WATER_BLAST = 1,
+ EVENT_WATER_BOLT_VOLLEY
+};
+
+enum GlobuleEvents
+{
+ EVENT_GLOBULE_MOVE = 1
};
enum Misc
{
+ DATA_GLOBULE_PATH = 0,
DATA_DEHYDRATION = 1
};
+
+#define MAX_GLOBULE_PATHS 10
+
+Position const globulePaths[MAX_GLOBULE_PATHS] =
+{
+ // first target
+ { 1861.357f, 804.039f, 44.008f, 6.268f },
+ { 1869.375f, 803.976f, 38.781f, 0.009f },
+ // second target
+ { 1888.063f, 763.488f, 47.667f, 1.744f },
+ { 1882.865f, 776.385f, 38.824f, 1.882f },
+ // third target
+ { 1935.140f, 817.752f, 52.181f, 1.885f },
+ { 1916.642f, 826.337f, 39.139f, 2.851f },
+ // fourth target
+ { 1930.257f, 833.053f, 46.906f, 4.579f },
+ { 1916.642f, 826.337f, 39.139f, 2.851f },
+ // fifth target
+ { 1878.248f, 841.883f, 43.334f, 4.717f },
+ { 1879.438f, 834.443f, 38.699f, 4.831f }
+};
+
class boss_ichoron : public CreatureScript
{
public:
@@ -78,33 +104,24 @@ public:
boss_ichoronAI(Creature* creature) : ScriptedAI(creature), m_waterElements(creature)
{
Initialize();
- instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
void Initialize()
{
bIsExploded = false;
bIsFrenzy = false;
+ bIsDrained = false;
dehydration = true;
- uiBubbleCheckerTimer = 1000;
- uiWaterBoltVolleyTimer = urand(10000, 15000);
+ drainedTimer = 50;
+ burstTimer = 15000;
}
- bool bIsExploded;
- bool bIsFrenzy;
- bool dehydration;
-
- uint32 uiBubbleCheckerTimer;
- uint32 uiWaterBoltVolleyTimer;
-
- InstanceScript* instance;
-
- SummonList m_waterElements;
-
void Reset() override
{
Initialize();
+ events.Reset();
me->SetVisible(true);
DespawnWaterElements();
@@ -131,6 +148,9 @@ public:
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
+ events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
}
void AttackStart(Unit* who) override
@@ -155,18 +175,14 @@ public:
switch (param)
{
case ACTION_WATER_ELEMENT_HIT:
- me->ModifyHealth(int32(me->CountPctFromMaxHealth(1)));
-
+ {
if (bIsExploded)
DoExplodeCompleted();
+ me->SetHealth(me->GetHealth() + me->CountPctFromMaxHealth(3));
dehydration = false;
- break;
- case ACTION_WATER_ELEMENT_KILLED:
- uint32 damage = me->CountPctFromMaxHealth(3);
- me->ModifyHealth(-int32(damage));
- me->LowerPlayerDamageReq(damage);
- break;
+ }
+ break;
}
}
@@ -180,6 +196,7 @@ public:
void DoExplodeCompleted()
{
bIsExploded = false;
+ bIsDrained = false;
if (!HealthBelowPct(25))
{
@@ -199,74 +216,24 @@ public:
return 0;
}
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
- void UpdateAI(uint32 uiDiff) override
+ void MoveInLineOfSight(Unit* who) override
{
- if (!UpdateVictim())
+ if (!who->ToCreature())
return;
- if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
- {
- Talk(SAY_ENRAGE);
- DoCast(me, SPELL_FRENZY, true);
- bIsFrenzy = true;
- }
-
- if (!bIsFrenzy)
- {
- if (uiBubbleCheckerTimer <= uiDiff)
- {
- if (!bIsExploded)
- {
- if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE))
- {
- Talk(SAY_SHATTER);
- DoCast(me, SPELL_WATER_BLAST); // wrong target
- DoCast(me, SPELL_DRAINED);
- bIsExploded = true;
- me->AttackStop();
- me->SetVisible(false);
- for (uint8 i = 0; i < 10; i++)
- {
- int tmp = urand(0, MAX_SPAWN_LOC-1);
- me->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN);
- }
- }
- }
- else
- {
- bool bIsWaterElementsAlive = false;
- if (!m_waterElements.empty())
- {
- for (SummonList::const_iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
- if (Creature* temp = ObjectAccessor::GetCreature(*me, *itr))
- if (temp->IsAlive())
- {
- bIsWaterElementsAlive = true;
- break;
- }
- }
+ if (who->GetEntry() != NPC_ICHOR_GLOBULE)
+ return;
- if (!bIsWaterElementsAlive)
- DoExplodeCompleted();
- }
- uiBubbleCheckerTimer = 1000;
- }
- else uiBubbleCheckerTimer -= uiDiff;
- }
+ if (!me->IsWithinDist(who, 4.0f, false))
+ return;
- if (!bIsExploded)
- {
- if (uiWaterBoltVolleyTimer <= uiDiff)
- {
- DoCast(me, SPELL_WATER_BOLT_VOLLEY);
- uiWaterBoltVolleyTimer = urand(10000, 15000);
- }
- else uiWaterBoltVolleyTimer -= uiDiff;
+ if (who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ return;
- DoMeleeAttackIfReady();
- }
+ who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ who->CastSpell(who, SPELL_MERGE);
+ DoAction(ACTION_WATER_ELEMENT_HIT);
+ who->ToCreature()->DespawnOrUnsummon(1000);
}
void JustDied(Unit* /*killer*/) override
@@ -295,22 +262,23 @@ public:
void JustSummoned(Creature* summoned) override
{
- if (summoned)
- {
- summoned->SetSpeed(MOVE_RUN, 0.3f);
- summoned->GetMotionMaster()->MoveFollow(me, 0, 0);
- m_waterElements.Summon(summoned);
- instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
- }
+ summoned->SetSpeed(MOVE_RUN, 0.3f);
+ m_waterElements.Summon(summoned);
+
+ instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
}
void SummonedCreatureDespawn(Creature* summoned) override
{
- if (summoned)
+ m_waterElements.Despawn(summoned);
+
+ if (m_waterElements.empty() && bIsExploded)
{
- m_waterElements.Despawn(summoned);
- instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
+ me->RemoveAllAuras();
+ DoExplodeCompleted();
}
+
+ instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
}
void KilledUnit(Unit* victim) override
@@ -318,6 +286,145 @@ public:
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
+ {
+ Talk(SAY_ENRAGE);
+ DoCast(me, SPELL_FRENZY, true);
+ bIsFrenzy = true;
+ }
+
+ if (!bIsFrenzy)
+ {
+ if (!bIsExploded)
+ {
+ if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE))
+ {
+ bIsExploded = true;
+ Talk(SAY_SHATTER);
+ DoCast(SPELL_BURST);
+ me->RemoveAllAuras();
+ burstTimer = 15000;
+
+ std::list<Creature*> summonTargets;
+ GetCreatureListWithEntryInGrid(summonTargets, me, NPC_ICHORON_SUMMON_TARGET, 200.0f);
+ std::list<Creature*>::iterator itr = summonTargets.begin();
+
+ for (uint8 i = 0; i < MAX_GLOBULE_PATHS; i++)
+ {
+ std::advance(itr, urand(0, summonTargets.size() - 1)); // I take a random minion in the list
+ Position targetPos = (*itr)->GetRandomNearPosition(10.0f);
+ itr = summonTargets.begin();
+ TempSummon* globule = me->SummonCreature(NPC_ICHOR_GLOBULE, targetPos, TEMPSUMMON_CORPSE_DESPAWN);
+ DoCast(globule, SPELL_WATER_GLOBULE_VISUAL);
+
+ float minDistance = 1000.0f;
+ uint8 nextPath = 0;
+ // I move the globules to next position. the 10 positions are in couples, defined in globulePaths, so i have to increase by 2.
+ for (uint8 gpath = 0; gpath < MAX_GLOBULE_PATHS; gpath += 2)
+ {
+ if (globule->GetDistance(globulePaths[gpath]) < minDistance)
+ {
+ minDistance = globule->GetDistance(globulePaths[gpath]);
+ nextPath = gpath;
+ }
+ }
+
+ globule->GetAI()->SetData(DATA_GLOBULE_PATH, nextPath);
+ }
+ return;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ events.Update(diff);
+
+ switch (uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_WATER_BLAST:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_WATER_BLAST);
+ events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
+ break;
+ case EVENT_WATER_BOLT_VOLLEY:
+ DoCast(SPELL_WATER_BOLT_VOLLEY);
+ events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ else if (!bIsDrained)
+ {
+ if (drainedTimer <= 0)
+ {
+ bIsDrained = true;
+ drainedTimer = 50;
+ uint32 damage = me->CountPctFromMaxHealth(30);
+ if (me->GetHealth() < damage)
+ me->SetHealth(me->CountPctFromMaxHealth(1));
+ else
+ {
+ me->SetHealth(me->GetHealth() - damage);
+ me->LowerPlayerDamageReq(damage);
+ }
+ DoCast(SPELL_DRAINED);
+ me->SetVisible(false);
+ me->AttackStop();
+ }
+ else
+ drainedTimer -= diff;
+ }
+ else if (bIsDrained)
+ {
+ if (burstTimer <= 0)
+ {
+ DoExplodeCompleted();
+ }
+ else
+ burstTimer -= diff;
+ }
+ }
+ else
+ {
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ events.Update(diff);
+
+ switch (uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_WATER_BLAST:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_WATER_BLAST);
+ events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
+ break;
+ case EVENT_WATER_BOLT_VOLLEY:
+ DoCast(SPELL_WATER_BOLT_VOLLEY);
+ events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ }
+
+ private:
+ InstanceScript* instance;
+ SummonList m_waterElements;
+ EventMap events;
+ bool bIsExploded;
+ bool bIsFrenzy;
+ bool bIsDrained;
+ bool dehydration;
+ int32 drainedTimer;
+ int32 burstTimer;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -341,48 +448,68 @@ public:
void Initialize()
{
- uiRangeCheck_Timer = 1000;
+ pathId = 0;
}
- InstanceScript* instance;
-
- uint32 uiRangeCheck_Timer;
-
void Reset() override
{
Initialize();
- DoCast(me, SPELL_WATER_GLOBULE);
+ events.Reset();
+ DoCast(SPELL_WATER_GLOBULE);
+ me->SetReactState(REACT_PASSIVE);
}
- void AttackStart(Unit* /*who*/) override
+ void SetData(uint32 id, uint32 data) override
{
+ if (id == DATA_GLOBULE_PATH)
+ {
+ pathId = data;
+ me->GetMotionMaster()->MovePoint(0, globulePaths[pathId]);
+ }
}
- void UpdateAI(uint32 uiDiff) override
+ void MovementInform(uint32 type, uint32 id) override
{
- if (uiRangeCheck_Timer < uiDiff)
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (id)
{
- if (Creature* ichoron = instance->GetCreature(DATA_ICHORON))
- {
- if (me->IsWithinDist(ichoron, 2.0f, false))
- {
- if (ichoron->AI())
- ichoron->AI()->DoAction(ACTION_WATER_ELEMENT_HIT);
- me->DespawnOrUnsummon();
- }
- }
- uiRangeCheck_Timer = 1000;
+ case 0:
+ me->GetMotionMaster()->Clear();
+ events.ScheduleEvent(EVENT_GLOBULE_MOVE, 500);
+ break;
+ case 1:
+ me->GetMotionMaster()->Clear();
+ if (Creature* ichoron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ICHORON)))
+ me->GetMotionMaster()->MoveFollow(ichoron, 0.0f, 0.0f);
+ break;
}
- else uiRangeCheck_Timer -= uiDiff;
}
- void JustDied(Unit* /*killer*/) override
+ // on retail spell casted on a creature's death are not casted after death but keeping mob at 1 health, casting it and then letting the mob die.
+ // this feature should be still implemented
+ void DamageTaken(Unit* attacker, uint32 &damage) override
{
- DoCast(me, SPELL_SPLASH);
- if (Creature* ichoron = instance->GetCreature(DATA_ICHORON))
- if (ichoron->AI())
- ichoron->AI()->DoAction(ACTION_WATER_ELEMENT_KILLED);
+ int32 actualHp = me->GetHealth();
+ actualHp -= damage;
+
+ if (actualHp <= 0)
+ DoCast(SPELL_SPLASH);
}
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_GLOBULE_MOVE)
+ me->GetMotionMaster()->MovePoint(1, globulePaths[pathId + 1]);
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ uint8 pathId;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
index 5040dccfa36..8dc0e32fb31 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
@@ -27,41 +27,39 @@ enum Spells
SPELL_LAVA_BURN = 54249
};
+enum LavanthorEvents
+{
+ EVENT_CAUTERIZING_FLAMES = 1,
+ EVENT_FIREBOLT,
+ EVENT_FLAME_BREATH,
+ EVENT_LAVA_BURN
+};
+
class boss_lavanthor : public CreatureScript
{
public:
boss_lavanthor() : CreatureScript("boss_lavanthor") { }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_lavanthorAI>(creature);
+ }
+
struct boss_lavanthorAI : public ScriptedAI
{
boss_lavanthorAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
instance = creature->GetInstanceScript();
}
- void Initialize()
- {
- uiFireboltTimer = 1000;
- uiFlameBreathTimer = 5000;
- uiLavaBurnTimer = 10000;
- uiCauterizingFlamesTimer = 3000;
- }
-
- uint32 uiFireboltTimer;
- uint32 uiFlameBreathTimer;
- uint32 uiLavaBurnTimer;
- uint32 uiCauterizingFlamesTimer;
-
- InstanceScript* instance;
-
void Reset() override
{
- Initialize();
if (instance->GetData(DATA_WAVE_COUNT) == 6)
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+
+ events.Reset();
}
void EnterCombat(Unit* /*who*/) override
@@ -72,11 +70,16 @@ public:
EnterEvadeMode();
return;
}
-
if (instance->GetData(DATA_WAVE_COUNT) == 6)
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_FIREBOLT, 1000);
+ events.ScheduleEvent(EVENT_FLAME_BREATH, 5000);
+ events.ScheduleEvent(EVENT_LAVA_BURN, 10000);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, 3000);
}
void AttackStart(Unit* who) override
@@ -93,39 +96,38 @@ public:
}
}
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
- if (uiFireboltTimer <= diff)
- {
- DoCastVictim(SPELL_FIREBOLT);
- uiFireboltTimer = urand(5000, 13000);
- } else uiFireboltTimer -= diff;
-
- if (uiFlameBreathTimer <= diff)
- {
- DoCastVictim(SPELL_FLAME_BREATH);
- uiFlameBreathTimer = urand(10000, 15000);
- } else uiFlameBreathTimer -= diff;
+ events.Update(diff);
- if (uiLavaBurnTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
- DoCast(target, SPELL_LAVA_BURN);
- uiLavaBurnTimer = urand(15000, 23000);
- } else uiLavaBurnTimer -= diff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (IsHeroic())
+ switch (uint32 eventId = events.ExecuteEvent())
{
- if (uiCauterizingFlamesTimer <= diff)
- {
- DoCastVictim(SPELL_CAUTERIZING_FLAMES);
- uiCauterizingFlamesTimer = urand(10000, 16000);
- } else uiCauterizingFlamesTimer -= diff;
+ case EVENT_FIREBOLT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_FIREBOLT);
+ events.ScheduleEvent(EVENT_FIREBOLT, urand(5000, 13000));
+ break;
+ case EVENT_FLAME_BREATH:
+ DoCast(SPELL_FLAME_BREATH);
+ events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 15000));
+ break;
+ case EVENT_LAVA_BURN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_LAVA_BURN);
+ events.ScheduleEvent(EVENT_LAVA_BURN, urand(15000, 23000));
+ break;
+ case EVENT_CAUTERIZING_FLAMES:
+ DoCast(SPELL_CAUTERIZING_FLAMES);
+ events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, urand(10000, 16000));
+ break;
+ default:
+ break;
}
DoMeleeAttackIfReady();
@@ -144,12 +146,11 @@ public:
instance->SetData(DATA_WAVE_COUNT, 13);
}
}
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_lavanthorAI>(creature);
- }
+ private:
+ EventMap events;
+ InstanceScript* instance;
+ };
};
void AddSC_boss_lavanthor()
diff --git a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
index 1c98806b127..f9e223d3bab 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
@@ -17,6 +17,8 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "violet_hold.h"
enum Spells
@@ -24,7 +26,18 @@ enum Spells
SPELL_CORROSIVE_SALIVA = 54527,
SPELL_OPTIC_LINK = 54396,
SPELL_RAY_OF_PAIN = 54438, // NYI missing spelldifficulty
- SPELL_RAY_OF_SUFFERING = 54442 // NYI missing spelldifficulty
+ SPELL_RAY_OF_SUFFERING = 54442, // NYI missing spelldifficulty
+
+ // Visual
+ SPELL_OPTIC_LINK_LEVEL_1 = 54393,
+ SPELL_OPTIC_LINK_LEVEL_2 = 54394,
+ SPELL_OPTIC_LINK_LEVEL_3 = 54395
+};
+
+enum MoraggEvents
+{
+ EVENT_CORROSIVE_SALIVA = 1,
+ EVENT_OPTIC_LINK
};
class boss_moragg : public CreatureScript
@@ -36,24 +49,12 @@ public:
{
boss_moraggAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
instance = creature->GetInstanceScript();
}
- void Initialize()
- {
- uiOpticLinkTimer = 10000;
- uiCorrosiveSalivaTimer = 5000;
- }
-
- uint32 uiOpticLinkTimer;
- uint32 uiCorrosiveSalivaTimer;
-
- InstanceScript* instance;
-
void Reset() override
{
- Initialize();
+ events.Reset();
if (instance->GetData(DATA_WAVE_COUNT) == 6)
instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
@@ -74,6 +75,13 @@ public:
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+
+ me->SetInCombatWithZone();
+
+ DoCast(SPELL_RAY_OF_PAIN);
+ DoCast(SPELL_RAY_OF_SUFFERING);
+ events.ScheduleEvent(EVENT_OPTIC_LINK, 15000);
+ events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 5000);
}
void AttackStart(Unit* who) override
@@ -90,25 +98,30 @@ public:
}
}
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
- if (uiOpticLinkTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_OPTIC_LINK);
- uiOpticLinkTimer = 15000;
- } else uiOpticLinkTimer -= diff;
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (uiCorrosiveSalivaTimer <= diff)
+ switch (uint32 eventId = events.ExecuteEvent())
{
- DoCastVictim(SPELL_CORROSIVE_SALIVA);
- uiCorrosiveSalivaTimer = 10000;
- } else uiCorrosiveSalivaTimer -= diff;
+ case EVENT_OPTIC_LINK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_OPTIC_LINK);
+ events.ScheduleEvent(EVENT_OPTIC_LINK, 25000);
+ break;
+ case EVENT_CORROSIVE_SALIVA:
+ DoCastVictim(SPELL_CORROSIVE_SALIVA);
+ events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 10000);
+ break;
+ default:
+ break;
+ }
DoMeleeAttackIfReady();
}
@@ -126,6 +139,10 @@ public:
instance->SetData(DATA_WAVE_COUNT, 13);
}
}
+
+ private:
+ EventMap events;
+ InstanceScript* instance;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -134,7 +151,149 @@ public:
}
};
+class spell_moragg_ray_of_suffering : public SpellScriptLoader
+{
+public:
+ spell_moragg_ray_of_suffering() : SpellScriptLoader("spell_moragg_ray_of_suffering") { }
+
+ class spell_moragg_ray_of_suffering_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_moragg_ray_of_suffering_AuraScript);
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
+ if (!players.empty())
+ {
+ std::list<HostileReference*>::iterator itr = players.begin();
+ std::advance(itr, urand(0, players.size() - 1));
+
+ uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
+ GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_suffering_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_moragg_ray_of_suffering_AuraScript();
+ }
+};
+
+class spell_moragg_ray_of_pain : public SpellScriptLoader
+{
+public:
+ spell_moragg_ray_of_pain() : SpellScriptLoader("spell_moragg_ray_of_pain") { }
+
+ class spell_moragg_ray_of_pain_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_moragg_ray_of_pain_AuraScript);
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
+ if (!players.empty())
+ {
+ std::list<HostileReference*>::iterator itr = players.begin();
+ std::advance(itr, urand(0, players.size() - 1));
+
+ uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
+ GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_pain_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_moragg_ray_of_pain_AuraScript();
+ }
+};
+
+class spell_moragg_optic_link : public SpellScriptLoader
+{
+public:
+ spell_moragg_optic_link() : SpellScriptLoader("spell_moragg_optic_link") { }
+
+ class spell_moragg_optic_link_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_moragg_optic_link_AuraScript);
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ switch (aurEff->GetTickNumber()) // Different visual based on tick
+ {
+ case 1:
+ case 2:
+ case 3:
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_3, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnUpdate(AuraEffect* aurEff)
+ {
+ switch (aurEff->GetTickNumber())
+ {
+ case 1:
+ aurEff->SetAmount(aurEff->GetAmount() + 250); // base amount is 500
+ break;
+ case 4:
+ aurEff->SetAmount(aurEff->GetAmount() * 2); // goes to 1500
+ break;
+ case 8:
+ aurEff->SetAmount(aurEff->GetAmount() * 2); // goes to 3000
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_optic_link_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_moragg_optic_link_AuraScript::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_moragg_optic_link_AuraScript();
+ }
+};
+
void AddSC_boss_moragg()
{
new boss_moragg();
+ new spell_moragg_ray_of_suffering();
+ new spell_moragg_ray_of_pain();
+ new spell_moragg_optic_link();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
index d1efcb8ca7a..4fb7646558d 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
@@ -17,29 +17,33 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "violet_hold.h"
+#include "SpellInfo.h"
+#include "SpellScript.h"
#include "Player.h"
+#include "violet_hold.h"
enum Spells
{
SPELL_ARCANE_BARRAGE_VOLLEY = 54202,
SPELL_ARCANE_BUFFET = 54226,
SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102,
- SPELL_SUMMON_ETHEREAL_SPHERE_2 = 54137,
+ SPELL_SUMMON_ETHEREAL_SPHERE_2 = 61337,
SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138
};
enum NPCs
{
NPC_ETHEREAL_SPHERE = 29271,
- //NPC_ETHEREAL_SPHERE2 = 32582, // heroic only?
+ NPC_ETHEREAL_SPHERE2 = 32582
};
enum CreatureSpells
{
SPELL_ARCANE_POWER = 54160,
+ H_SPELL_ARCANE_POWER = 59474,
SPELL_SUMMON_PLAYERS = 54164,
- SPELL_POWER_BALL_VISUAL = 54141
+ SPELL_POWER_BALL_VISUAL = 54141,
+ SPELL_POWER_BALL_DAMAGE_TRIGGER = 54207
};
enum Yells
@@ -53,6 +57,22 @@ enum Yells
SAY_SUMMON_ENERGY = 6
};
+enum XevozzEvents
+{
+ EVENT_ARCANE_BARRAGE = 1,
+ EVENT_ARCANE_BUFFET,
+ EVENT_SUMMON_SPHERE,
+ EVENT_SUMMON_SPHERE_2,
+ EVENT_RANGE_CHECK,
+ EVENT_SUMMON_PLAYERS,
+ EVENT_DESPAWN_SPHERE
+};
+
+enum SphereActions
+{
+ ACTION_SUMMON = 1,
+};
+
class boss_xevozz : public CreatureScript
{
public:
@@ -62,23 +82,9 @@ public:
{
boss_xevozzAI(Creature* creature) : ScriptedAI(creature)
{
- Initialize();
- instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- void Initialize()
- {
- uiSummonEtherealSphere_Timer = urand(10000, 12000);
- uiArcaneBarrageVolley_Timer = urand(20000, 22000);
- uiArcaneBuffet_Timer = uiSummonEtherealSphere_Timer + urand(5000, 6000);
- }
-
- InstanceScript* instance;
-
- uint32 uiSummonEtherealSphere_Timer;
- uint32 uiArcaneBarrageVolley_Timer;
- uint32 uiArcaneBuffet_Timer;
-
void Reset() override
{
if (instance->GetData(DATA_WAVE_COUNT) == 6)
@@ -86,14 +92,15 @@ public:
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- Initialize();
DespawnSphere();
+ events.Reset();
}
void DespawnSphere()
{
std::list<Creature*> assistList;
GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE, 150.0f);
+ GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE2, 150.0f);
if (assistList.empty())
return;
@@ -108,11 +115,7 @@ public:
void JustSummoned(Creature* summoned) override
{
summoned->SetSpeed(MOVE_RUN, 0.5f);
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- summoned->AddThreat(target, 0.00f);
- summoned->AI()->AttackStart(target);
- }
+ summoned->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f);
}
void AttackStart(Unit* who) override
@@ -144,45 +147,10 @@ public:
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
- }
-
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- if (uiArcaneBarrageVolley_Timer < diff)
- {
- DoCast(me, SPELL_ARCANE_BARRAGE_VOLLEY);
- uiArcaneBarrageVolley_Timer = urand(20000, 22000);
- }
- else uiArcaneBarrageVolley_Timer -= diff;
- if (uiArcaneBuffet_Timer)
- {
- if (uiArcaneBuffet_Timer < diff)
- {
- DoCastVictim(SPELL_ARCANE_BUFFET);
- uiArcaneBuffet_Timer = 0;
- }
- else uiArcaneBuffet_Timer -= diff;
- }
-
- if (uiSummonEtherealSphere_Timer < diff)
- {
- Talk(SAY_SPAWN);
- DoCast(me, SPELL_SUMMON_ETHEREAL_SPHERE_1);
- if (IsHeroic()) // extra one for heroic
- me->SummonCreature(NPC_ETHEREAL_SPHERE, me->GetPositionX() - 5 + rand32() % 10, me->GetPositionY() - 5 + rand32() % 10, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 40000);
-
- uiSummonEtherealSphere_Timer = urand(45000, 47000);
- uiArcaneBuffet_Timer = urand(5000, 6000);
- }
- else uiSummonEtherealSphere_Timer -= diff;
-
- DoMeleeAttackIfReady();
+ events.ScheduleEvent(EVENT_SUMMON_SPHERE, 5000);
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
+ events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(10000, 11000));
}
void JustDied(Unit* /*killer*/) override
@@ -208,6 +176,65 @@ public:
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
+
+ void SpellHit(Unit* who, const SpellInfo* spell) override
+ {
+ if (!who->ToCreature())
+ return;
+
+ if ((spell->Id == SPELL_ARCANE_POWER) || (spell->Id == H_SPELL_ARCANE_POWER))
+ Talk(SAY_SUMMON_ENERGY);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ switch (uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_ARCANE_BARRAGE:
+ DoCast(SPELL_ARCANE_BARRAGE_VOLLEY);
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
+ break;
+ case EVENT_ARCANE_BUFFET:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ARCANE_BUFFET);
+ events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(15000, 20000));
+ break;
+ case EVENT_SUMMON_SPHERE:
+ Talk(SAY_REPEAT_SUMMON);
+ DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_1);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_SUMMON_SPHERE_2, 2500);
+ events.ScheduleEvent(EVENT_SUMMON_PLAYERS, urand(33000, 35000));
+ events.ScheduleEvent(EVENT_SUMMON_SPHERE, urand(45000, 47000));
+ break;
+ case EVENT_SUMMON_SPHERE_2:
+ Talk(SAY_REPEAT_SUMMON);
+ DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_2);
+ break;
+ case EVENT_SUMMON_PLAYERS:
+ if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE, 150.0f))
+ sphere->GetAI()->DoAction(ACTION_SUMMON);
+ else if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE2, 150.0f))
+ sphere->GetAI()->DoAction(ACTION_SUMMON);
+ break;
+ default:
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -226,71 +253,137 @@ public:
npc_ethereal_sphereAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
- instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
void Initialize()
{
- uiSummonPlayers_Timer = urand(33000, 35000);
- uiRangeCheck_Timer = 1000;
+ arcanePower = false;
}
- InstanceScript* instance;
-
- uint32 uiSummonPlayers_Timer;
- uint32 uiRangeCheck_Timer;
-
void Reset() override
{
Initialize();
+ events.Reset();
+ DoCast(SPELL_POWER_BALL_VISUAL);
+ DoCast(SPELL_POWER_BALL_DAMAGE_TRIGGER);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->setFaction(16);
+ events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 40000);
+ events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_SUMMON)
+ DoCast(SPELL_SUMMON_PLAYERS);
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
- return;
+ events.Update(diff);
- if (!me->HasAura(SPELL_POWER_BALL_VISUAL))
- DoCast(me, SPELL_POWER_BALL_VISUAL);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (uiRangeCheck_Timer < diff)
+ switch (uint32 eventId = events.ExecuteEvent())
{
- if (Creature* pXevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ)))
- {
- float fDistance = me->GetDistance2d(pXevozz);
- if (fDistance <= 3)
- DoCast(pXevozz, SPELL_ARCANE_POWER);
- else
- DoCast(me, 35845); //Is it blizzlike?
- }
- uiRangeCheck_Timer = 1000;
+ case EVENT_RANGE_CHECK:
+ if (Creature* xevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ)))
+ {
+ if (me->IsWithinDist(xevozz, 3.0f) && !arcanePower)
+ {
+ DoCast(SPELL_ARCANE_POWER);
+ arcanePower = true;
+ events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 8000);
+ }
+ }
+ events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
+ break;
+ case EVENT_DESPAWN_SPHERE:
+ me->DespawnOrUnsummon();
+ break;
}
- else uiRangeCheck_Timer -= diff;
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ bool arcanePower;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<npc_ethereal_sphereAI>(creature);
+ }
+};
+
+class spell_xevozz_summon_players : public SpellScriptLoader
+{
+public:
+ spell_xevozz_summon_players() : SpellScriptLoader("spell_xevozz_summon_players") { }
+
+ class spell_xevozz_summon_players_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_xevozz_summon_players_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* target = GetHitUnit();
- if (uiSummonPlayers_Timer < diff)
+ if (target)
{
- DoCast(me, SPELL_SUMMON_PLAYERS); // not working right
+ Position pos = GetOriginalCaster()->GetPosition();
- Map* map = me->GetMap();
- if (map && map->IsDungeon())
- {
- Map::PlayerList const &PlayerList = map->GetPlayers();
+ target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
+ }
+ }
- if (!PlayerList.isEmpty())
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (i->GetSource()->IsAlive())
- DoTeleportPlayer(i->GetSource(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), i->GetSource()->GetOrientation());
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_xevozz_summon_players_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_xevozz_summon_players_SpellScript();
+ }
+};
- uiSummonPlayers_Timer = urand(33000, 35000);
+class spell_xevozz_summon_ethereal_sphere : public SpellScriptLoader
+{
+public:
+ spell_xevozz_summon_ethereal_sphere() : SpellScriptLoader("spell_xevozz_summon_ethereal_sphere") { }
+
+ class spell_xevozz_summon_ethereal_sphere_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_xevozz_summon_ethereal_sphere_SpellScript);
+
+ void HandleScript(SpellDestination& target)
+ {
+ Unit* caster = GetOriginalCaster();
+ Position pos;
+ float distance = 0.0f;
+
+ while (distance < 20.0f)
+ {
+ pos = caster->GetRandomNearPosition(60.0f);
+ distance = caster->GetDistance(pos);
}
- else uiSummonPlayers_Timer -= diff;
+
+ target.Relocate(pos);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_xevozz_summon_ethereal_sphere_SpellScript::HandleScript, EFFECT_0, TARGET_DEST_DB);
}
};
- CreatureAI* GetAI(Creature* creature) const override
+ SpellScript* GetSpellScript() const override
{
- return GetInstanceAI<npc_ethereal_sphereAI>(creature);
+ return new spell_xevozz_summon_ethereal_sphere_SpellScript();
}
};
@@ -298,4 +391,6 @@ void AddSC_boss_xevozz()
{
new boss_xevozz();
new npc_ethereal_sphere();
+ new spell_xevozz_summon_players();
+ new spell_xevozz_summon_ethereal_sphere();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
index c29861f08a4..02e479a22f4 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
@@ -23,12 +23,8 @@ enum Spells
{
SPELL_SHROUD_OF_DARKNESS = 54524,
SPELL_SUMMON_VOID_SENTRY = 54369,
- SPELL_VOID_SHIFT = 54361
-};
-
-enum Creatures
-{
- NPC_VOID_SENTRY = 29364
+ SPELL_VOID_SHIFT = 54361,
+ SPELL_VOID_SHIFTED = 54343,
};
enum Yells
@@ -46,6 +42,13 @@ enum Misc
DATA_VOID_DANCE = 2153
};
+enum ZuramatEvents
+{
+ EVENT_VOID_SHIFT = 1,
+ EVENT_SUMMON_VOID,
+ EVENT_SHROUD_OF_DARKNESS
+};
+
class boss_zuramat : public CreatureScript
{
public:
@@ -53,7 +56,7 @@ public:
struct boss_zuramatAI : public ScriptedAI
{
- boss_zuramatAI(Creature* creature) : ScriptedAI(creature)
+ boss_zuramatAI(Creature* creature) : ScriptedAI(creature), sentries(me)
{
Initialize();
instance = creature->GetInstanceScript();
@@ -61,18 +64,18 @@ public:
void Initialize()
{
- SpellShroudOfDarknessTimer = 22000;
- SpellVoidShiftTimer = 15000;
- SpellSummonVoidTimer = 12000;
voidDance = true;
}
- InstanceScript* instance;
-
- uint32 SpellVoidShiftTimer;
- uint32 SpellSummonVoidTimer;
- uint32 SpellShroudOfDarknessTimer;
- bool voidDance;
+ void DespawnSentries()
+ {
+ sentries.DespawnAll();
+ std::list<Creature*> sentrylist;
+ GetCreatureListWithEntryInGrid(sentrylist, me, NPC_VOID_SENTRY_BALL, 200.0f);
+ if (!sentrylist.empty())
+ for (std::list<Creature*>::const_iterator itr = sentrylist.begin(); itr != sentrylist.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+ }
void Reset() override
{
@@ -82,6 +85,8 @@ public:
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
Initialize();
+ events.Reset();
+ DespawnSentries();
}
void AttackStart(Unit* who) override
@@ -112,36 +117,17 @@ public:
if (instance->GetData(DATA_WAVE_COUNT) == 6)
instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
- }
+ instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ me->SetInCombatWithZone();
+ events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
+ events.ScheduleEvent(EVENT_VOID_SHIFT, 9000);
+ events.ScheduleEvent(EVENT_SUMMON_VOID, 4000);
+ }
- void UpdateAI(uint32 diff) override
+ void JustSummoned(Creature* summon) override
{
- if (!UpdateVictim())
- return;
-
- if (SpellSummonVoidTimer <= diff)
- {
- DoCastVictim(SPELL_SUMMON_VOID_SENTRY, false);
- SpellSummonVoidTimer = 20000;
- } else SpellSummonVoidTimer -=diff;
-
- if (SpellVoidShiftTimer <= diff)
- {
- if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(unit, SPELL_VOID_SHIFT);
- SpellVoidShiftTimer = 20000;
- } else SpellVoidShiftTimer -=diff;
-
- if (SpellShroudOfDarknessTimer <= diff)
- {
- DoCastVictim(SPELL_SHROUD_OF_DARKNESS);
- SpellShroudOfDarknessTimer = 20000;
- } else SpellShroudOfDarknessTimer -=diff;
-
- DoMeleeAttackIfReady();
+ sentries.Summon(summon);
}
void SummonedCreatureDies(Creature* summoned, Unit* /*who*/) override
@@ -160,8 +146,12 @@ public:
void JustDied(Unit* /*killer*/) override
{
+ instance->SetData(DATA_ZURAMAT, 1);
+
Talk(SAY_DEATH);
+ DespawnSentries();
+
if (instance->GetData(DATA_WAVE_COUNT) == 6)
{
instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
@@ -179,6 +169,44 @@ public:
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ switch (uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_SUMMON_VOID:
+ DoCast(SPELL_SUMMON_VOID_SENTRY);
+ events.ScheduleEvent(EVENT_SUMMON_VOID, urand(7000, 10000));
+ break;
+ case EVENT_VOID_SHIFT:
+ if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(unit, SPELL_VOID_SHIFT);
+ events.ScheduleEvent(EVENT_VOID_SHIFT, 15000);
+ break;
+ case EVENT_SHROUD_OF_DARKNESS:
+ DoCast(SPELL_SHROUD_OF_DARKNESS);
+ events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
+ break;
+ default:
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ SummonList sentries;
+ bool voidDance;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
index 28c56a02255..652b4815be0 100644
--- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
@@ -145,6 +145,7 @@ public:
bCrystalActivated = false;
defenseless = true;
uiMainEventPhase = NOT_STARTED;
+ zuramatDead = false;
}
ObjectGuid uiErekemGuard[2];
@@ -178,6 +179,7 @@ public:
bool bIsDoorSpellCast;
bool bCrystalActivated;
bool defenseless;
+ bool zuramatDead;
std::list<uint8> NpcAtDoorCastingList;
@@ -199,16 +201,20 @@ public:
break;
default:
break;
+ case NPC_VOID_SENTRY:
+ if (zuramatDead)
+ {
+ creature->DespawnOrUnsummon();
+ zuramatDead = false;
+ }
+ break;
}
- /*
- BEWARE - SHIT.
if (creature->GetGUID() == uiFirstBoss || creature->GetGUID() == uiSecondBoss)
{
creature->AllLootRemovedFromCorpse();
creature->RemoveLootMode(1);
}
- */
}
void OnGameObjectCreate(GameObject* go) override
@@ -314,6 +320,9 @@ public:
uiRemoveNpc = 0; // might not have been reset after a wipe on a boss.
}
break;
+ case DATA_ZURAMAT:
+ zuramatDead = true;
+ break;
}
}
@@ -393,19 +402,23 @@ public:
if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
{
if (bForceRespawn)
+ {
pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
+ pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
+ }
else
- pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
+ pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
}
if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
{
if (bForceRespawn)
- pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
+ {
+ pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
+ pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
+ }
else
- pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
+ pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
}
break;
case BOSS_ICHORON:
@@ -448,6 +461,9 @@ public:
boss->Respawn();
boss->RemoveLootMode(1);
}
+ else
+ boss->GetMotionMaster()->MoveTargetedHome();
+
boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
uiWaveCount = 0;
}
@@ -527,6 +543,7 @@ public:
return false;
}
+ zuramatDead = false;
return true;
}
@@ -557,6 +574,7 @@ public:
SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE);
SetData(DATA_WAVE_COUNT, 0);
uiMainEventPhase = NOT_STARTED;
+ uiActivationTimer = 5000;
for (int i = 0; i < 4; ++i)
if (GameObject* crystal = instance->GetGameObject(uiActivationCrystal[i]))
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
index 8bcc80b5a84..b05da4b994c 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
@@ -28,6 +28,7 @@
#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right"
#define GOSSIP_I_WANT_IN "I'm not fighting, so send me in now!"
+#define SAY_EVENT_LOCK "I'm locking the door. Good luck, and thank you for doing this."
#define SPAWN_TIME 20000
enum PortalCreatures
@@ -59,7 +60,7 @@ enum AzureSellbreakerSpells
SPELL_ARCANE_BLAST = 58462,
SPELL_SLOW = 25603,
SPELL_CHAINS_OF_ICE = 58464,
- SPELL_CONE_OF_COLD = 58463
+ SPELL_CONE_OF_COLD = 58463,
};
enum AzureBinderSpells
@@ -67,7 +68,7 @@ enum AzureBinderSpells
SPELL_ARCANE_BARRAGE = 58456,
SPELL_ARCANE_EXPLOSION = 58455,
SPELL_FROST_NOVA = 58458,
- SPELL_FROSTBOLT = 58457
+ SPELL_FROSTBOLT = 58457,
};
enum AzureMageSlayerSpells
@@ -85,7 +86,7 @@ enum AzureCaptainSpells
enum AzureSorcerorSpells
{
SPELL_ARCANE_STREAM = 60181,
- SPELL_MANA_DETONATION = 60182
+ SPELL_MANA_DETONATION = 60182,
};
enum AzureRaiderSpells
@@ -114,7 +115,7 @@ enum TrashDoorSpell
enum Spells
{
SPELL_PORTAL_CHANNEL = 58012,
- SPELL_CRYSTAL_ACTIVATION = 57804,
+ SPELL_CRYSTAL_ACTIVATION = 57804, // visual effect
SPELL_ARCANE_SPHERE_PASSIVE = 44263
};
@@ -242,9 +243,21 @@ const float SaboteurFinalPos6[5][3] =
{1931.063354f, 848.468445f, 47.190434f}
};
-const Position MovePosition = {1806.955566f, 803.851807f, 44.363323f, 0.0f};
-const Position playerTeleportPosition = {1830.531006f, 803.939758f, 44.340508f, 6.281611f};
-const Position sinclariOutsidePosition = {1817.315674f, 804.060608f, 44.363998f, 0.0f};
+const Position PortalLocation[] =
+{
+ { 1877.51f, 850.104f, 44.6599f, 4.7822f }, // WP 1
+ { 1936.07f, 803.198f, 53.3749f, 3.12414f }, // WP 3
+ { 1890.64f, 753.471f, 48.7224f, 1.71042f }, // WP 5
+};
+
+#define MAX_PRE_EVENT_PORTAL 3
+
+ObjectGuid preEventPortalGUID[MAX_PRE_EVENT_PORTAL] = { ObjectGuid::Empty };
+
+const Position MovePosition = { 1806.955566f, 803.851807f, 44.363323f, 0.0f };
+const Position playerTeleportPosition = { 1830.531006f, 803.939758f, 44.340508f, 6.281611f };
+const Position sinclariOutsidePosition = { 1820.429810f, 804.066040f, 44.363998f, 0.0f };
+const Position sinclariCrystalPosition = { 1828.868286f, 798.468811f, 44.363998f, 3.890467f };
class npc_sinclari_vh : public CreatureScript
{
@@ -320,6 +333,9 @@ public:
Initialize();
me->SetReactState(REACT_AGGRESSIVE);
+ for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
+ if (TempSummon* summon = me->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalLocation[i], TEMPSUMMON_MANUAL_DESPAWN))
+ preEventPortalGUID[i] = summon->GetGUID();
std::list<Creature*> GuardList;
me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
@@ -347,25 +363,17 @@ public:
switch (uiPhase)
{
case 1:
- Talk(SAY_SINCLARI_1);
- uiTimer = 4000;
- uiPhase = 2;
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(0, sinclariCrystalPosition);
+ uiTimer = 1000;
+ uiPhase = 6;
break;
case 2:
{
- std::list<Creature*> GuardList;
- me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
- if (!GuardList.empty())
- for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
- {
- if (Creature* pGuard = *itr)
- {
- pGuard->SetWalk(false);
- pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
- }
- }
- uiTimer = 6000;
- uiPhase = 3;
+ me->SetFacingTo(me->GetOrientation() - 3.14f);
+ Talk(SAY_SINCLARI_1);
+ uiTimer = 1500;
+ uiPhase = 7;
break;
}
case 3:
@@ -378,7 +386,6 @@ public:
if (Creature* pGuard = *itr)
{
pGuard->SetVisible(false);
- pGuard->SetReactState(REACT_PASSIVE);
}
}
uiTimer = 2000;
@@ -391,11 +398,58 @@ public:
uiPhase = 5;
break;
case 5:
- instance->SetData(DATA_MAIN_EVENT_PHASE, IN_PROGRESS);
+ me->SetFacingTo(0.006673f);
+ me->Say(SAY_EVENT_LOCK, LANG_UNIVERSAL, me); // need to change to db say
me->SetReactState(REACT_PASSIVE);
+ uiTimer = 3000;
+ uiPhase = 8;
+ break;
+ case 6:
+ me->GetMotionMaster()->MovementExpired();
+ me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING);
+ uiTimer = 2000;
+ uiPhase = 2;
+ break;
+ case 7:
+ {
+ std::list<Creature*> creatures;
+ GetCreatureListWithEntryInGrid(creatures, me, NPC_TELEPORTATION_PORTAL, 200.0f);
+ GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_BINDER_1, 200.0f);
+ GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_MAGE_SLAYER_1, 200.0f);
+ GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_INVADER_1, 200.0f);
+ DoCast(SPELL_CRYSTAL_ACTIVATION);
+ if (!creatures.empty())
+ {
+ for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
+ (*itr)->DisappearAndDie();
+ }
+ uiTimer = 500;
+ uiPhase = 9;
+ }
+ break;
+ case 8:
+ instance->SetData(DATA_MAIN_EVENT_PHASE, IN_PROGRESS);
uiTimer = 0;
uiPhase = 0;
break;
+ case 9:
+ {
+ std::list<Creature*> GuardList;
+ me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
+ if (!GuardList.empty())
+ for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ {
+ if (Creature* pGuard = *itr)
+ {
+ pGuard->SetReactState(REACT_PASSIVE);
+ pGuard->SetWalk(false);
+ pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
+ }
+ }
+ uiTimer = 4000;
+ uiPhase = 3;
+ }
+ break;
}
}
else uiTimer -= uiDiff;
@@ -548,6 +602,9 @@ public:
Initialize();
instance = creature->GetInstanceScript();
uiTypeOfMobsPortal = urand(0, 1); // 0 - elite mobs 1 - portal guardian or portal keeper with regular mobs
+
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
+ uiTypeOfMobsPortal = 2;
}
void Initialize()
@@ -575,10 +632,13 @@ public:
void UpdateAI(uint32 diff) override
{
- if (instance->GetData(DATA_REMOVE_NPC) == 1)
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
{
- me->DespawnOrUnsummon();
- instance->SetData(DATA_REMOVE_NPC, 0);
+ if (instance->GetData(DATA_REMOVE_NPC) == 1)
+ {
+ me->DespawnOrUnsummon();
+ instance->SetData(DATA_REMOVE_NPC, 0);
+ }
}
uint8 uiWaveCount = instance->GetData(DATA_WAVE_COUNT);
@@ -642,24 +702,39 @@ public:
me->RemoveCorpse();
}
break;
+ case 2: // Pre-event
+ if (uiSpawnTimer <= diff)
+ {
+ uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_BINDER_1);
+ DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
+ uiSpawnTimer = SPAWN_TIME;
+ } else uiSpawnTimer -= diff;
+ break;
}
}
void JustDied(Unit* /*killer*/) override
{
- instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT)+1);
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT) + 1);
}
void JustSummoned(Creature* summoned) override
{
- listOfMobs.Summon(summoned);
- instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ {
+ listOfMobs.Summon(summoned);
+ instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
+ }
}
void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) override
{
- listOfMobs.Despawn(summoned);
- instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ {
+ listOfMobs.Despawn(summoned);
+ instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
+ }
}
};
@@ -675,8 +750,23 @@ struct violet_hold_trashAI : public npc_escortAI
{
instance = creature->GetInstanceScript();
bHasGotMovingPoints = false;
- portalLocationID = instance->GetData(DATA_PORTAL_LOCATION);
- secondPortalRouteID = 0;
+
+
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
+ {
+ if (Creature* portal = me->FindNearestCreature(NPC_TELEPORTATION_PORTAL, 10.0f))
+ {
+ ObjectGuid portalGUID = portal->GetGUID();
+ for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
+ if (portalGUID == preEventPortalGUID[i])
+ portalLocationID = i * 2;
+ }
+ }
+ else
+ {
+ portalLocationID = instance->GetData(DATA_PORTAL_LOCATION);
+ Reset();
+ }
}
public:
@@ -691,7 +781,7 @@ struct violet_hold_trashAI : public npc_escortAI
{
case 0:
if (waypointId == 5)
- CreatureStartAttackDoor();
+ CreatureStartAttackDoor();
break;
case 1:
if ((waypointId == 8 && secondPortalRouteID == 0) || (waypointId == 7 && secondPortalRouteID == 1))
@@ -699,7 +789,7 @@ struct violet_hold_trashAI : public npc_escortAI
break;
case 2:
if (waypointId == 7)
- CreatureStartAttackDoor();
+ CreatureStartAttackDoor();
break;
case 3:
if (waypointId == 8)
@@ -1203,7 +1293,7 @@ public:
if (uiConeOfColdTimer <= diff)
{
- DoCast(SPELL_CONE_OF_COLD);
+ DoCast(SPELL_CONE_OF_COLD);
uiConeOfColdTimer = 5000;
} else uiConeOfColdTimer -= diff;
}
@@ -1334,7 +1424,6 @@ public:
}
};
-
class npc_violet_hold_arcane_sphere : public CreatureScript
{
public:
@@ -1391,6 +1480,33 @@ public:
}
};
+class spell_crystal_activation : public SpellScriptLoader
+{
+public:
+ spell_crystal_activation() : SpellScriptLoader("spell_crystal_activation") { }
+
+ class spell_crystal_activation_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_crystal_activation_SpellScript);
+
+ void HandleSendEvent(SpellEffIndex effIndex)
+ {
+ if (GetHitUnit()->GetEntry() == NPC_VIOLET_HOLD_GUARD)
+ PreventHitDefaultEffect(effIndex);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_crystal_activation_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_crystal_activation_SpellScript();
+ }
+};
+
void AddSC_violet_hold()
{
new npc_sinclari_vh();
@@ -1406,4 +1522,5 @@ void AddSC_violet_hold()
new npc_azure_saboteur();
new npc_violet_hold_arcane_sphere();
new go_activation_crystal();
+ new spell_crystal_activation();
}
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h
index 275a7467d83..e8da9576c13 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.h
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h
@@ -101,7 +101,9 @@ enum CreaturesIds
NPC_SINCLARI = 30658,
NPC_SABOTEOUR = 31079,
NPC_VIOLET_HOLD_GUARD = 30659,
- NPC_DEFENSE_SYSTEM = 30837
+ NPC_DEFENSE_SYSTEM = 30837,
+ NPC_VOID_SENTRY = 29364,
+ NPC_VOID_SENTRY_BALL = 29365
};
enum GameObjectIds
diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/isle_of_conquest.cpp
index ba21b60f11d..f5514cc51a5 100644
--- a/src/server/scripts/Northrend/isle_of_conquest.cpp
+++ b/src/server/scripts/Northrend/isle_of_conquest.cpp
@@ -161,19 +161,6 @@ class spell_ioc_gunship_portal : public SpellScriptLoader
* Position: X: 7.305609 Y: -0.095246 Z: 34.51022 O: 0
*/
caster->TeleportTo(GetHitCreature()->GetWorldLocation(), TELE_TO_NOT_LEAVE_TRANSPORT);
- /*
- * HACK: This aura should be added by 20212 and 20213 but can't find any SMSG_SPELL_GO. Could't find their position.
- * ServerToClient: SMSG_AURA_UPDATE (0x0072)
- * [0] CasterGUID: Full: xxxxx Type: Unit Entry: 20212 Low: xxx
- * [0] Flags: None (0)
- * [0] Caster Level: 60
- * [0] Spell ID: 66656
- * [0] Charges: 0
- * [0] Effect Mask: 1
- * [0] Slot: 37
- * Guid: Full: xxxxx Type: Player2 Low: xxxxx
- */
- caster->AddAura(SPELL_PARACHUTE, caster);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index 93e13667cb0..a1b218010aa 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -824,6 +824,60 @@ class spell_brewfest_barker_bunny : public SpellScriptLoader
}
};
+enum TorchSpells
+{
+ SPELL_TORCH_TOSSING_TRAINING = 45716,
+ SPELL_TORCH_TOSSING_PRACTICE = 46630,
+ SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE = 45719,
+ SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE = 46651,
+ SPELL_BRAZIERS_HIT = 45724
+};
+
+// 45724 - Braziers Hit!
+class spell_midsummer_braziers_hit : public SpellScriptLoader
+{
+ public:
+ spell_midsummer_braziers_hit() : SpellScriptLoader("spell_midsummer_braziers_hit") { }
+
+ class spell_midsummer_braziers_hit_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_midsummer_braziers_hit_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TORCH_TOSSING_TRAINING) || !sSpellMgr->GetSpellInfo(SPELL_TORCH_TOSSING_PRACTICE))
+ return false;
+ return true;
+ }
+
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Player* player = GetTarget()->ToPlayer();
+ if (!player)
+ return;
+
+ if ((player->HasAura(SPELL_TORCH_TOSSING_TRAINING) && GetStackAmount() == 8) || (player->HasAura(SPELL_TORCH_TOSSING_PRACTICE) && GetStackAmount() == 20))
+ {
+ if (player->GetTeam() == ALLIANCE)
+ player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_ALLIANCE, true);
+ else if (player->GetTeam() == HORDE)
+ player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_HORDE, true);
+ Remove();
+ }
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_midsummer_braziers_hit_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAPPLY));
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_midsummer_braziers_hit_AuraScript();
+ }
+};
+
void AddSC_holiday_spell_scripts()
{
// Love is in the Air
@@ -850,4 +904,6 @@ void AddSC_holiday_spell_scripts()
new spell_brewfest_relay_race_intro_force_player_to_throw();
new spell_brewfest_dismount_ram();
new spell_brewfest_barker_bunny();
+ // Midsummer Fire Festival
+ new spell_midsummer_braziers_hit();
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 1ca01501d01..1efdb16804f 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -68,13 +68,13 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
- "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels "
+ "health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels "
"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
- "base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, "
+ "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, "
"itemcount1, itemcount2, itemcount3, itemcount4, playercount FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC);
@@ -99,7 +99,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, bag, slot, "
"item, itemEntry FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activespec AND a.guid = ? ORDER BY button", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activeTalentGroup AND a.guid = ? ORDER BY button", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?", CONNECTION_SYNCH);
@@ -116,8 +116,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, "
"item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, spec FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, talentGroup FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC);
@@ -247,7 +247,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC);
// Auras
- PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) "
+ PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// Account data
@@ -336,14 +336,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC);
// GM Tickets
- PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket FROM gm_tickets", CONNECTION_SYNCH);
- PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_tickets (ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_tickets WHERE ticketId = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_tickets WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp FROM gm_ticket", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_ticket (id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_ticket WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_ticket WHERE playerGuid = ?", CONNECTION_ASYNC);
// GM Survey/subsurvey/lag report
- PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurveys (surveyId, subsurveyId, rank, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_survey (guid, surveyId, mainSurvey, comment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurvey (surveyId, questionId, answer, answerComment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ, latency, createTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// LFG Data
@@ -358,13 +358,13 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"extra_flags, stable_slots, at_login, zone, "
"death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, "
"todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, "
- "power4, power5, power6, power7, latency, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES "
+ "power4, power5, power6, power7, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES "
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?,"
"map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?,"
- "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,speccount=?,activespec=?,exploredZones=?,"
+ "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,exploredZones=?,"
"equipmentCache=?,ammoId=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);
@@ -374,7 +374,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
@@ -384,7 +384,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_ticket", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC);
@@ -415,7 +415,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER_POSITION, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remaintime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remainTime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHARACTER_ONLINE, "SELECT name, account, map, zone FROM characters WHERE online > 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH);
@@ -546,8 +546,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? AND spell = ? AND talentGroup = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, talentGroup) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC);
// Items that hold loot or money
@@ -576,7 +576,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_PET_AURA, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
@@ -586,8 +586,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_BOTH);
PrepareStatement(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH);
- PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
- "base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
+ PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, "
+ "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH);
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
index d0c80efb00a..1f4ffc97cfc 100644
--- a/src/server/shared/Threading/Callback.h
+++ b/src/server/shared/Threading/Callback.h
@@ -97,7 +97,7 @@ class QueryCallback
//! Resets all underlying variables (param, result and stage)
void Reset()
{
- SetParam(NULL);
+ SetParam(ParamType());
FreeResult();
ResetStage();
}
diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h
index 9212784ab9e..cad773fbee4 100644
--- a/src/tools/map_extractor/adt.h
+++ b/src/tools/map_extractor/adt.h
@@ -67,8 +67,8 @@ class adt_MCLQ
uint32 fcc;
char fcc_txt[4];
};
- uint32 size;
public:
+ uint32 size;
float height1;
float height2;
struct liquid_data{
@@ -96,8 +96,8 @@ class adt_MCNK
uint32 fcc;
char fcc_txt[4];
};
- uint32 size;
public:
+ uint32 size;
uint32 flags;
uint32 ix;
uint32 iy;
@@ -155,8 +155,8 @@ class adt_MCIN
uint32 fcc;
char fcc_txt[4];
};
- uint32 size;
public:
+ uint32 size;
struct adt_CELLS{
uint32 offsMCNK;
uint32 size;
@@ -271,6 +271,7 @@ class adt_MHDR
uint32 fcc;
char fcc_txt[4];
};
+public:
uint32 size;
uint32 pad;
@@ -289,7 +290,6 @@ class adt_MHDR
uint32 data3;
uint32 data4;
uint32 data5;
-public:
bool prepareLoadedData();
adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);}
adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;}