Core/Instance: implement the combat resurrection limit.
Cherry Pick from https://github.com/TrinityCore/TrinityCore/commit/948146f3ee890b85af50944176877c7d44c0c120 I change this a bit, so that this is works right for 4.3.3 Patch. (Here isn't add charges after a specific time. Groups have from begin 1 or 3 Charges for Resurrection.)
This commit is contained in:
1 parent
0ee051e6af
commit
d4c703a2e2
5 files changed
+126
-11
No files matched your search
@@ -46,6 +46,7 @@
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "DB2Stores.h"
|
||||
#include "WhoListStorage.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData)
|
||||
{
|
||||
@@ -616,6 +617,20 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
|
||||
if (!GetPlayer()->IsResurrectRequestedBy(guid))
|
||||
return;
|
||||
|
||||
if (Player* ressPlayer = ObjectAccessor::GetPlayer(*GetPlayer(), guid))
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
if (instance->IsEncounterInProgress())
|
||||
{
|
||||
if (!instance->GetCombatResurrectionCharges())
|
||||
return;
|
||||
else
|
||||
instance->UseCombatResurrection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetPlayer()->ResurrectUsingRequestData();
|
||||
}
|
||||
|
||||
|
||||
@@ -295,16 +295,41 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
|
||||
//TC_LOG_ERROR("misc", "Inialize boss %u state as %u.", id, (uint32)state);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bossInfo->state == state)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (bossInfo->state == state)
|
||||
return false;
|
||||
|
||||
if (state == DONE)
|
||||
for (GuidSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i)
|
||||
if (Creature* minion = instance->GetCreature(*i))
|
||||
if (minion->isWorldBoss() && minion->IsAlive())
|
||||
return false;
|
||||
if (state == DONE)
|
||||
for (GuidSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i)
|
||||
if (Creature* minion = instance->GetCreature(*i))
|
||||
if (minion->isWorldBoss() && minion->IsAlive())
|
||||
return false;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case IN_PROGRESS:
|
||||
{
|
||||
uint32 resInterval = GetCombatResurrectionChargeInterval();
|
||||
if (instance->Is25ManRaid() || (instance->Is25ManRaid() && instance->IsHeroic()))
|
||||
{
|
||||
InitializeCombatResurrections(3, resInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeCombatResurrections(1, resInterval);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FAIL:
|
||||
case DONE:
|
||||
ResetCombatResurrections();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bossInfo->state = state;
|
||||
SaveToDB();
|
||||
@@ -690,3 +715,56 @@ void InstanceScript::UpdatePhasing()
|
||||
if (Player* player = itr->GetSource())
|
||||
player->SendUpdatePhasing();
|
||||
}
|
||||
|
||||
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; // true;
|
||||
}
|
||||
|
||||
void InstanceScript::AddCombatResurrectionCharge()
|
||||
{
|
||||
// ++_combatResurrectionCharges;
|
||||
_combatResurrectionTimer = GetCombatResurrectionChargeInterval();
|
||||
_combatResurrectionTimerStarted = true;
|
||||
}
|
||||
|
||||
void InstanceScript::UseCombatResurrection()
|
||||
{
|
||||
--_combatResurrectionCharges;
|
||||
}
|
||||
|
||||
void InstanceScript::ResetCombatResurrections()
|
||||
{
|
||||
_combatResurrectionCharges = 0;
|
||||
_combatResurrectionTimer = 0;
|
||||
_combatResurrectionTimerStarted = 0;
|
||||
}
|
||||
|
||||
uint32 InstanceScript::GetCombatResurrectionChargeInterval() const
|
||||
{
|
||||
// This System here is from MoP and not Cataclysm.
|
||||
// In Cataclysm have 10 Man Raids 1 Resurrection and 25 Man Raids 3 Resurrection free.
|
||||
uint32 interval = 0;
|
||||
if (uint32 playerCount = instance->GetPlayers().getSize())
|
||||
interval = 90 * MINUTE * IN_MILLISECONDS / playerCount;
|
||||
|
||||
return interval;
|
||||
}
|
||||
@@ -161,6 +161,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.
|
||||
@@ -253,6 +254,13 @@ class TC_GAME_API InstanceScript : public ZoneScript
|
||||
|
||||
uint32 GetEncounterCount() const { return 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); }
|
||||
@@ -296,6 +304,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
|
||||
|
||||
@@ -3150,8 +3150,11 @@ void InstanceMap::Update(const uint32 t_diff)
|
||||
{
|
||||
Map::Update(t_diff);
|
||||
|
||||
if (i_data)
|
||||
i_data->Update(t_diff);
|
||||
if (i_data)
|
||||
{
|
||||
i_data->Update(t_diff);
|
||||
i_data->UpdateCombatResurrection(t_diff);
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Battleground.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Pet.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
|
||||
{
|
||||
@@ -1878,6 +1879,13 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
|
||||
if (HasEffect(SPELL_EFFECT_SELF_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT) || HasEffect(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->ToInstance())
|
||||
if (InstanceScript* instance = iMap->GetInstanceScript())
|
||||
if (instance->GetCombatResurrectionCharges() == 0 && instance->IsEncounterInProgress())
|
||||
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
|
||||
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user