aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp15
-rw-r--r--src/server/game/Instances/InstanceScript.cpp140
-rw-r--r--src/server/game/Instances/InstanceScript.h15
-rw-r--r--src/server/game/Maps/Map.cpp3
-rw-r--r--src/server/game/Server/Packets/InstancePackets.cpp41
-rw-r--r--src/server/game/Server/Packets/InstancePackets.h72
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp24
-rw-r--r--src/server/game/Spells/SpellInfo.cpp8
8 files changed, 287 insertions, 31 deletions
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index a9db9d52572..a43ec6c2202 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -47,6 +47,7 @@
#include "AchievementPackets.h"
#include "WhoPackets.h"
#include "InstancePackets.h"
+#include "InstanceScript.h"
void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& /*packet*/)
{
@@ -449,6 +450,20 @@ void WorldSession::HandleResurrectResponse(WorldPackets::Misc::ResurrectResponse
if (!GetPlayer()->IsResurrectRequestedBy(packet.Resurrecter))
return;
+ if (Player* ressPlayer = ObjectAccessor::GetPlayer(*GetPlayer(), packet.Resurrecter))
+ {
+ if (InstanceScript* instance = ressPlayer->GetInstanceScript())
+ {
+ if (instance->IsEncounterInProgress())
+ {
+ if (!instance->GetCombatResurrectionCharges())
+ return;
+ else
+ instance->UseCombatResurrection();
+ }
+ }
+ }
+
GetPlayer()->ResurrectUsingRequestData();
}
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index b4c56c32394..2969d5666ac 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -22,6 +22,7 @@
#include "GameObject.h"
#include "Group.h"
#include "InstanceScript.h"
+#include "InstancePackets.h"
#include "LFGMgr.h"
#include "Log.h"
#include "Map.h"
@@ -38,7 +39,8 @@ BossBoundaryData::~BossBoundaryData()
delete it->Boundary;
}
-InstanceScript::InstanceScript(Map* map) : instance(map), completedEncounters(0)
+InstanceScript::InstanceScript(Map* map) : instance(map), completedEncounters(0),
+_combatResurrectionTimer(0), _combatResurrectionCharges(0), _combatResurrectionTimerStarted(false)
{
#ifdef TRINITY_API_USE_DYNAMIC_LINKING
uint32 scriptId = sObjectMgr->GetInstanceTemplate(map->GetId())->ScriptId;
@@ -306,6 +308,24 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
if (minion->isWorldBoss() && minion->IsAlive())
return false;
+ switch (state)
+ {
+ case IN_PROGRESS:
+ {
+ uint32 resInterval = GetCombatResurrectionChargeInterval();
+ InitializeCombatResurrections(1, resInterval);
+ SendEncounterStart(1, 9, resInterval, resInterval);
+ break;
+ }
+ case FAIL:
+ case DONE:
+ ResetCombatResurrections();
+ SendEncounterEnd();
+ break;
+ default:
+ break;
+ }
+
bossInfo->state = state;
SaveToDB();
}
@@ -586,36 +606,62 @@ bool InstanceScript::CheckAchievementCriteriaMeet(uint32 criteria_id, Player con
return false;
}
-void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 param1 /*= 0*/, uint8 param2 /*= 0*/)
+void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 priority)
{
- // size of this packet is at most 15 (usually less)
- WorldPacket data(SMSG_INSTANCE_ENCOUNTER_ENGAGE_UNIT, 15);
- data << uint32(type);
-
switch (type)
{
case ENCOUNTER_FRAME_ENGAGE: // SMSG_INSTANCE_ENCOUNTER_ENGAGE_UNIT
- case ENCOUNTER_FRAME_DISENGAGE: // SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT
- case ENCOUNTER_FRAME_UPDATE_PRIORITY: // SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY
+ {
if (!unit)
return;
- data << unit->GetPackGUID();
- data << uint8(param1);
+
+ WorldPackets::Instance::InstanceEncounterEngageUnit encounterEngageMessage;
+ encounterEngageMessage.Unit = unit->GetGUID();
+ encounterEngageMessage.TargetFramePriority = priority;
+ instance->SendToPlayers(encounterEngageMessage.Write());
break;
- case ENCOUNTER_FRAME_ADD_TIMER: // SMSG_INSTANCE_ENCOUNTER_TIMER_START
- case ENCOUNTER_FRAME_ENABLE_OBJECTIVE: // SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_START
- case ENCOUNTER_FRAME_DISABLE_OBJECTIVE: // SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_COMPLETE
- data << uint8(param1);
+ }
+ case ENCOUNTER_FRAME_DISENGAGE: // SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT
+ {
+ if (!unit)
+ return;
+
+ WorldPackets::Instance::InstanceEncounterDisengageUnit encounterDisengageMessage;
+ encounterDisengageMessage.Unit = unit->GetGUID();
+ instance->SendToPlayers(encounterDisengageMessage.Write());
break;
- case ENCOUNTER_FRAME_UPDATE_OBJECTIVE: // SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_UPDATE
- data << uint8(param1);
- data << uint8(param2);
+ }
+ case ENCOUNTER_FRAME_UPDATE_PRIORITY: // SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY
+ {
+ if (!unit)
+ return;
+
+ WorldPackets::Instance::InstanceEncounterChangePriority encounterChangePriorityMessage;
+ encounterChangePriorityMessage.Unit = unit->GetGUID();
+ encounterChangePriorityMessage.TargetFramePriority = priority;
+ instance->SendToPlayers(encounterChangePriorityMessage.Write());
break;
+ }
default:
break;
}
+}
+
+void InstanceScript::SendEncounterStart(uint32 inCombatResCount /*= 0*/, uint32 maxInCombatResCount /*= 0*/, uint32 inCombatResChargeRecovery /*= 0*/, uint32 nextCombatResChargeTime /*= 0*/)
+{
+ WorldPackets::Instance::InstanceEncounterStart encounterStartMessage;
+ encounterStartMessage.InCombatResCount = inCombatResCount;
+ encounterStartMessage.MaxInCombatResCount = maxInCombatResCount;
+ encounterStartMessage.CombatResChargeRecovery = inCombatResChargeRecovery;
+ encounterStartMessage.NextCombatResChargeTime = nextCombatResChargeTime;
- instance->SendToPlayers(&data);
+ instance->SendToPlayers(encounterStartMessage.Write());
+}
+
+void InstanceScript::SendEncounterEnd()
+{
+ WorldPackets::Instance::InstanceEncounterEnd encounterEndMessage;
+ instance->SendToPlayers(encounterEndMessage.Write());
}
void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* /*source*/)
@@ -686,3 +732,61 @@ std::string InstanceScript::GetBossStateName(uint8 state)
return "INVALID";
}
}
+
+void InstanceScript::UpdateCombatResurrection(uint32 diff)
+{
+ if (!_combatResurrectionTimerStarted)
+ return;
+
+ _combatResurrectionTimer -= diff;
+ if (_combatResurrectionTimer <= 0)
+ {
+ AddCombatResurrectionCharge();
+ _combatResurrectionTimerStarted = false;
+ }
+}
+
+void InstanceScript::InitializeCombatResurrections(uint8 charges /*= 1*/, uint32 interval /*= 0*/)
+{
+ _combatResurrectionCharges = charges;
+ if (!interval)
+ return;
+
+ _combatResurrectionTimer = interval;
+ _combatResurrectionTimerStarted = true;
+}
+
+void InstanceScript::AddCombatResurrectionCharge()
+{
+ ++_combatResurrectionCharges;
+ _combatResurrectionTimer = GetCombatResurrectionChargeInterval();
+ _combatResurrectionTimerStarted = true;
+
+ WorldPackets::Instance::InstanceEncounterGainCombatResurrectionCharge gainCombatResurrectionCharge;
+ gainCombatResurrectionCharge.InCombatResCount = _combatResurrectionCharges;
+ gainCombatResurrectionCharge.CombatResChargeRecovery = _combatResurrectionTimer;
+ instance->SendToPlayers(gainCombatResurrectionCharge.Write());
+}
+
+void InstanceScript::UseCombatResurrection()
+{
+ --_combatResurrectionCharges;
+
+ instance->SendToPlayers(WorldPackets::Instance::InstanceEncounterInCombatResurrection().Write());
+}
+
+void InstanceScript::ResetCombatResurrections()
+{
+ _combatResurrectionCharges = 0;
+ _combatResurrectionTimer = 0;
+ _combatResurrectionTimerStarted = 0;
+}
+
+uint32 InstanceScript::GetCombatResurrectionChargeInterval() const
+{
+ uint32 interval = 0;
+ if (uint32 playerCount = instance->GetPlayers().getSize())
+ interval = 90 * MINUTE * IN_MILLISECONDS / playerCount;
+
+ return interval;
+}
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index 1611f3c290f..7a2daaaecf8 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -162,6 +162,7 @@ class TC_GAME_API InstanceScript : public ZoneScript
void SaveToDB();
virtual void Update(uint32 /*diff*/) { }
+ void UpdateCombatResurrection(uint32 /*diff*/);
// Used by the map's CannotEnter function.
// This is to prevent players from entering during boss encounters.
@@ -245,7 +246,9 @@ class TC_GAME_API InstanceScript : public ZoneScript
// Returns completed encounters mask for packets
uint32 GetCompletedEncounterMask() const { return completedEncounters; }
- void SendEncounterUnit(uint32 type, Unit* unit = NULL, uint8 param1 = 0, uint8 param2 = 0);
+ void SendEncounterUnit(uint32 type, Unit* unit = NULL, uint8 priority = 0);
+ void SendEncounterStart(uint32 inCombatResCount = 0, uint32 maxInCombatResCount = 0, uint32 inCombatResChargeRecovery = 0, uint32 nextCombatResChargeTime = 0);
+ void SendEncounterEnd();
virtual void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& /*packet*/) { }
@@ -254,6 +257,13 @@ class TC_GAME_API InstanceScript : public ZoneScript
uint32 GetEncounterCount() const { return uint32(bosses.size()); }
+ void InitializeCombatResurrections(uint8 charges = 1, uint32 interval = 0);
+ void AddCombatResurrectionCharge();
+ void UseCombatResurrection();
+ void ResetCombatResurrections();
+ uint8 GetCombatResurrectionCharges() const { return _combatResurrectionCharges; }
+ uint32 GetCombatResurrectionChargeInterval() const;
+
protected:
void SetHeaders(std::string const& dataHeaders);
void SetBossNumber(uint32 number) { bosses.resize(number); }
@@ -297,6 +307,9 @@ class TC_GAME_API InstanceScript : public ZoneScript
ObjectInfoMap _gameObjectInfo;
ObjectGuidMap _objectGuids;
uint32 completedEncounters; // completed encounter mask, bit indexes are DungeonEncounter.dbc boss numbers, used for packets
+ uint32 _combatResurrectionTimer;
+ uint8 _combatResurrectionCharges; // the counter for available battle resurrections
+ bool _combatResurrectionTimerStarted;
#ifdef TRINITY_API_USE_DYNAMIC_LINKING
// Strong reference to the associated script module
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index cfb7288c43b..2389d8e0fc1 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3230,7 +3230,10 @@ void InstanceMap::Update(const uint32 t_diff)
Map::Update(t_diff);
if (i_data)
+ {
i_data->Update(t_diff);
+ i_data->UpdateCombatResurrection(t_diff);
+ }
}
void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp
index 2f5b8579a00..a6278c315e2 100644
--- a/src/server/game/Server/Packets/InstancePackets.cpp
+++ b/src/server/game/Server/Packets/InstancePackets.cpp
@@ -117,3 +117,44 @@ WorldPacket const* WorldPackets::Instance::RaidInstanceMessage::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Instance::InstanceEncounterEngageUnit::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << uint8(TargetFramePriority);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Instance::InstanceEncounterDisengageUnit::Write()
+{
+ _worldPacket << Unit;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Instance::InstanceEncounterChangePriority::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << uint8(TargetFramePriority);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Instance::InstanceEncounterStart::Write()
+{
+ _worldPacket << uint32(InCombatResCount);
+ _worldPacket << uint32(MaxInCombatResCount);
+ _worldPacket << uint32(CombatResChargeRecovery);
+ _worldPacket << uint32(NextCombatResChargeTime);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Instance::InstanceEncounterGainCombatResurrectionCharge::Write()
+{
+ _worldPacket << int32(InCombatResCount);
+ _worldPacket << uint32(CombatResChargeRecovery);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h
index 0600c425058..137984d8396 100644
--- a/src/server/game/Server/Packets/InstancePackets.h
+++ b/src/server/game/Server/Packets/InstancePackets.h
@@ -164,6 +164,78 @@ namespace WorldPackets
bool Locked = false;
bool Extended = false;
};
+
+ class InstanceEncounterEngageUnit final : public ServerPacket
+ {
+ public:
+ InstanceEncounterEngageUnit() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_ENGAGE_UNIT, 15) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ uint8 TargetFramePriority = 0; // used to set the initial position of the frame if multiple frames are sent
+ };
+
+ class InstanceEncounterDisengageUnit final : public ServerPacket
+ {
+ public:
+ InstanceEncounterDisengageUnit() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT, 15) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ };
+
+ class InstanceEncounterChangePriority final : public ServerPacket
+ {
+ public:
+ InstanceEncounterChangePriority() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY, 15) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ uint8 TargetFramePriority = 0; // used to update the position of the unit's current frame
+ };
+
+ class InstanceEncounterStart final : public ServerPacket
+ {
+ public:
+ InstanceEncounterStart() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_START, 16) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 InCombatResCount = 0; // amount of usable battle ressurections
+ uint32 MaxInCombatResCount = 0;
+ uint32 CombatResChargeRecovery = 0;
+ uint32 NextCombatResChargeTime = 0;
+ };
+
+ class InstanceEncounterEnd final : public ServerPacket
+ {
+ public:
+ InstanceEncounterEnd() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_END, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class InstanceEncounterInCombatResurrection final : public ServerPacket
+ {
+ public:
+ InstanceEncounterInCombatResurrection() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_IN_COMBAT_RESURRECTION, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class InstanceEncounterGainCombatResurrectionCharge final : public ServerPacket
+ {
+ public:
+ InstanceEncounterGainCombatResurrectionCharge() : ServerPacket(SMSG_INSTANCE_ENCOUNTER_GAIN_COMBAT_RESURRECTION_CHARGE, 0) { }
+
+ WorldPacket const* Write() override;
+
+ int32 InCombatResCount = 0;
+ uint32 CombatResChargeRecovery = 0;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 3463421a2ea..5af870900a1 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1200,18 +1200,18 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_PVP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_END, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_ENGAGE_UNIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_GAIN_COMBAT_RESURRECTION_CHARGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_IN_COMBAT_RESURRECTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_PHASE_SHIFT_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_TIMER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_END, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_ENGAGE_UNIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_GAIN_COMBAT_RESURRECTION_CHARGE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_IN_COMBAT_RESURRECTION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_START, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_OBJECTIVE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_PHASE_SHIFT_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_START, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_TIMER_START, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_GROUP_SIZE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_NEVER, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index ae361883ed7..5e0c70e855e 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -26,6 +26,7 @@
#include "Battleground.h"
#include "Vehicle.h"
#include "Pet.h"
+#include "InstanceScript.h"
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
{
@@ -2021,6 +2022,13 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
if (HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_SELF_RESURRECT) || HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_RESURRECT) || HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_RESURRECT_NEW))
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
+ if (HasAttribute(SPELL_ATTR8_BATTLE_RESURRECTION))
+ if (Map* map = caster->GetMap())
+ if (InstanceMap* iMap = map->ToInstanceMap())
+ if (InstanceScript* instance = iMap->GetInstanceScript())
+ if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
+ return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
+
return SPELL_CAST_OK;
}