Core/Battlegrounds: Moved AreaSpiritHealer resurrection handling to respective npc flags

Port From (https://github.com/TrinityCore/TrinityCore/commit/205aba1ff3a6f1ff92a8b26af646fd25f139c697)
This commit is contained in:
hondacrx
2023-05-21 18:38:55 -04:00
parent 3e72da9f1e
commit 35961a0121
17 changed files with 248 additions and 331 deletions
@@ -62,8 +62,10 @@ namespace Framework.Constants
public const sbyte PlayerPositionArenaSlot5 = 6;
//Spells
public const uint SpellSpiritHealChannelAoE = 22011; // used for AoE resurrections
public const uint SpellSpiritHealPlayerAura = 156758; // individual player timers for resurrection
public const uint SpellSpiritHealChannelSelf = 305122; // channel visual for individual area spirit healers
public const uint SpellWaitingForResurrect = 2584; // Waiting To Resurrect
public const uint SpellSpiritHealChannel = 22011; // Spirit Heal Channel
public const uint SpellSpiritHealChannelVisual = 3060;
public const uint SpellSpiritHeal = 22012; // Spirit Heal
public const uint SpellResurrectionVisual = 24171; // Resurrection Impact Visual
@@ -81,6 +83,7 @@ namespace Framework.Constants
public const uint SpellMercenaryAlliance1 = 193863;
public const uint SpellMercenaryAllianceReactions = 195843;
public const uint SpellMercenaryShapeshift = 193970;
public const uint SpellPetSummoned = 6962; // used after resurrection
}
public enum BattlegroundEventFlags
@@ -62,6 +62,8 @@ namespace Framework.Constants
public const uint SpellExperienceEliminated = 206662;
public const uint CurrencyMaxCapAncientMana = 2000;
public const float MaxAreaSpiritHealerRange = 20.0f;
}
public struct MoneyConstants
+4 -132
View File
@@ -31,8 +31,6 @@ namespace Game.BattleFields
m_uiKickDontAcceptTimer = 1000;
m_uiKickAfkPlayersTimer = 1000;
m_LastResurectTimer = 30 * Time.InMilliseconds;
m_Map = map;
m_MapId = map.GetId();
@@ -99,7 +97,6 @@ namespace Game.BattleFields
m_PlayersWillBeKick[player.GetTeamId()].Remove(player.GetGUID());
m_players[player.GetTeamId()].Remove(player.GetGUID());
SendRemoveWorldStates(player);
RemovePlayerFromResurrectQueue(player.GetGUID());
OnPlayerLeaveZone(player);
}
@@ -164,17 +161,6 @@ namespace Game.BattleFields
objective_changed = true;
}
if (m_LastResurectTimer <= diff)
{
for (byte i = 0; i < m_GraveyardList.Count; i++)
if (GetGraveyardById(i) != null)
m_GraveyardList[i].Resurrect();
m_LastResurectTimer = BattlegroundConst.ResurrectionInterval;
}
else
m_LastResurectTimer -= diff;
return objective_changed;
}
@@ -597,45 +583,6 @@ namespace Game.BattleFields
return null;
}
public virtual void AddPlayerToResurrectQueue(ObjectGuid npcGuid, ObjectGuid playerGuid)
{
for (byte i = 0; i < m_GraveyardList.Count; i++)
{
if (m_GraveyardList[i] == null)
continue;
if (m_GraveyardList[i].HasNpc(npcGuid))
{
m_GraveyardList[i].AddPlayer(playerGuid);
break;
}
}
}
public void RemovePlayerFromResurrectQueue(ObjectGuid playerGuid)
{
for (byte i = 0; i < m_GraveyardList.Count; i++)
{
if (m_GraveyardList[i] == null)
continue;
if (m_GraveyardList[i].HasPlayer(playerGuid))
{
m_GraveyardList[i].RemovePlayer(playerGuid);
break;
}
}
}
public void SendAreaSpiritHealerQuery(Player player, ObjectGuid guid)
{
AreaSpiritHealerTime areaSpiritHealerTime = new();
areaSpiritHealerTime.HealerGuid = guid;
areaSpiritHealerTime.TimeLeft = m_LastResurectTimer;// resurrect every 30 seconds
player.SendPacket(areaSpiritHealerTime);
}
public Creature SpawnCreature(uint entry, Position pos)
{
if (Global.ObjectMgr.GetCreatureTemplate(entry) == null)
@@ -810,7 +757,6 @@ namespace Game.BattleFields
// Graveyard variables
protected List<BfGraveyard> m_GraveyardList = new(); // Vector witch contain the different GY of the battle
uint m_LastResurectTimer; // Timer for resurect player every 30 sec
protected uint m_StartGroupingTimer; // Timer for invite players in area 15 minute before start battle
protected bool m_StartGrouping; // bool for know if all players in area has been invited
@@ -856,58 +802,6 @@ namespace Game.BattleFields
return player.GetDistance2d(safeLoc.Loc.GetPositionX(), safeLoc.Loc.GetPositionY());
}
public void AddPlayer(ObjectGuid playerGuid)
{
if (!m_ResurrectQueue.Contains(playerGuid))
{
m_ResurrectQueue.Add(playerGuid);
Player player = Global.ObjAccessor.FindPlayer(playerGuid);
if (player)
player.CastSpell(player, BattlegroundConst.SpellWaitingForResurrect, true);
}
}
public void RemovePlayer(ObjectGuid playerGuid)
{
m_ResurrectQueue.Remove(playerGuid);
Player player = Global.ObjAccessor.FindPlayer(playerGuid);
if (player)
player.RemoveAurasDueToSpell(BattlegroundConst.SpellWaitingForResurrect);
}
public void Resurrect()
{
if (m_ResurrectQueue.Empty())
return;
foreach (var guid in m_ResurrectQueue)
{
// Get player object from his guid
Player player = Global.ObjAccessor.FindPlayer(guid);
if (!player)
continue;
// Check if the player is in world and on the good graveyard
if (player.IsInWorld)
{
Creature spirit = m_Bf.GetCreature(m_SpiritGuide[m_ControlTeam]);
if (spirit)
spirit.CastSpell(spirit, BattlegroundConst.SpellSpiritHeal, true);
}
// Resurect player
player.CastSpell(player, BattlegroundConst.SpellResurrectionVisual, true);
player.ResurrectPlayer(1.0f);
player.CastSpell(player, 6962, true);
player.CastSpell(player, BattlegroundConst.SpellSpiritHealMana, true);
player.SpawnCorpseBones(false);
}
m_ResurrectQueue.Clear();
}
// For changing graveyard control
public void GiveControlTo(uint team)
{
@@ -918,29 +812,11 @@ namespace Game.BattleFields
if (m_SpiritGuide[team])
m_SpiritGuide[team].SetVisible(true);*/
Creature spiritHealer = m_Bf.GetCreature(m_SpiritGuide[team]);
if (spiritHealer != null)
spiritHealer.SummonGraveyardTeleporter();
m_ControlTeam = team;
// Teleport to other graveyard, player witch were on this graveyard
RelocateDeadPlayers();
}
void RelocateDeadPlayers()
{
WorldSafeLocsEntry closestGrave = null;
foreach (var guid in m_ResurrectQueue)
{
Player player = Global.ObjAccessor.FindPlayer(guid);
if (!player)
continue;
if (closestGrave != null)
player.TeleportTo(closestGrave.Loc);
else
{
closestGrave = m_Bf.GetClosestGraveYard(player);
if (closestGrave != null)
player.TeleportTo(closestGrave.Loc);
}
}
}
public bool HasNpc(ObjectGuid guid)
@@ -955,9 +831,6 @@ namespace Game.BattleFields
return (m_SpiritGuide[TeamId.Alliance] == guid || m_SpiritGuide[TeamId.Horde] == guid);
}
// Check if a player is in this graveyard's ressurect queue
public bool HasPlayer(ObjectGuid guid) { return m_ResurrectQueue.Contains(guid); }
// Get the graveyard's ID.
public uint GetGraveyardId() { return m_GraveyardId; }
@@ -966,7 +839,6 @@ namespace Game.BattleFields
uint m_ControlTeam;
uint m_GraveyardId;
ObjectGuid[] m_SpiritGuide = new ObjectGuid[SharedConst.PvpTeamsCount];
List<ObjectGuid> m_ResurrectQueue = new();
protected BattleField m_Bf;
}
+2 -127
View File
@@ -117,7 +117,6 @@ namespace Game.BattleGrounds
}
else
{
_ProcessRessurect(diff);
if (Global.BattlegroundMgr.GetPrematureFinishTime() != 0 && (GetPlayersCountByTeam(Team.Alliance) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(Team.Horde) < GetMinPlayersPerTeam()))
_ProcessProgress(diff);
else if (m_PrematureCountDown)
@@ -214,61 +213,6 @@ namespace Game.BattleGrounds
}
}
void _ProcessRessurect(uint diff)
{
// *********************************************************
// *** Battleground RESSURECTION SYSTEM ***
// *********************************************************
// this should be handled by spell system
m_LastResurrectTime += diff;
if (m_LastResurrectTime >= BattlegroundConst.ResurrectionInterval)
{
if (GetReviveQueueSize() != 0)
{
Creature sh = null;
foreach (var pair in m_ReviveQueue)
{
Player player = Global.ObjAccessor.FindPlayer(pair.Value);
if (!player)
continue;
if (!sh && player.IsInWorld)
{
sh = player.GetMap().GetCreature(pair.Key);
// only for visual effect
if (sh)
// Spirit Heal, effect 117
sh.CastSpell(sh, BattlegroundConst.SpellSpiritHeal, true);
}
// Resurrection visual
player.CastSpell(player, BattlegroundConst.SpellResurrectionVisual, true);
m_ResurrectQueue.Add(pair.Value);
}
m_ReviveQueue.Clear();
m_LastResurrectTime = 0;
}
else
// queue is clear and time passed, just update last resurrection time
m_LastResurrectTime = 0;
}
else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC
{
foreach (var guid in m_ResurrectQueue)
{
Player player = Global.ObjAccessor.FindPlayer(guid);
if (!player)
continue;
player.ResurrectPlayer(1.0f);
player.CastSpell(player, 6962, true);
player.CastSpell(player, BattlegroundConst.SpellSpiritHealMana, true);
player.SpawnCorpseBones(false);
}
m_ResurrectQueue.Clear();
}
}
public virtual Team GetPrematureWinner()
{
Team winner = 0;
@@ -835,8 +779,6 @@ namespace Game.BattleGrounds
if (PlayerScores.ContainsKey(guid))
PlayerScores.Remove(guid);
RemovePlayerFromResurrectQueue(guid);
Player player = Global.ObjAccessor.FindPlayer(guid);
if (player)
{
@@ -940,7 +882,6 @@ namespace Game.BattleGrounds
SetStatus(BattlegroundStatus.WaitQueue);
SetElapsedTime(0);
SetRemainingTime(0);
SetLastResurrectTime(0);
m_Events = 0;
if (m_InvitedAlliance > 0 || m_InvitedHorde > 0)
@@ -960,7 +901,6 @@ namespace Game.BattleGrounds
public void StartBattleground()
{
SetElapsedTime(0);
SetLastResurrectTime(0);
// add BG to free slot queue
AddToBGFreeSlotQueue();
@@ -1313,56 +1253,6 @@ namespace Game.BattleGrounds
return true;
}
public void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid)
{
m_ReviveQueue.Add(npc_guid, player_guid);
Player player = Global.ObjAccessor.FindPlayer(player_guid);
if (!player)
return;
player.CastSpell(player, BattlegroundConst.SpellWaitingForResurrect, true);
}
public void RemovePlayerFromResurrectQueue(ObjectGuid player_guid)
{
foreach (var pair in m_ReviveQueue.KeyValueList)
{
if (pair.Value == player_guid)
{
m_ReviveQueue.Remove(pair);
Player player = Global.ObjAccessor.FindPlayer(player_guid);
if (player)
player.RemoveAurasDueToSpell(BattlegroundConst.SpellWaitingForResurrect);
return;
}
}
}
public void RelocateDeadPlayers(ObjectGuid guideGuid)
{
// Those who are waiting to resurrect at this node are taken to the closest own node's graveyard
List<ObjectGuid> ghostList = m_ReviveQueue[guideGuid];
if (!ghostList.Empty())
{
WorldSafeLocsEntry closestGrave = null;
foreach (var guid in ghostList)
{
Player player = Global.ObjAccessor.FindPlayer(guid);
if (!player)
continue;
if (closestGrave == null)
closestGrave = GetClosestGraveYard(player);
if (closestGrave != null)
player.TeleportTo(closestGrave.Loc);
}
ghostList.Clear();
}
}
public bool AddObject(int type, uint entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint respawnTime = 0, GameObjectState goState = GameObjectState.Ready)
{
Map map = FindBgMap();
@@ -1602,20 +1492,9 @@ namespace Game.BattleGrounds
{
uint entry = (uint)(teamIndex == TeamId.Alliance ? BattlegroundCreatures.A_SpiritGuide : BattlegroundCreatures.H_SpiritGuide);
Creature creature = AddCreature(entry, type, x, y, z, o);
if (creature)
{
creature.SetDeathState(DeathState.Dead);
creature.AddChannelObject(creature.GetGUID());
// aura
//todo Fix display here
// creature.SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
// casting visual effect
creature.SetChannelSpellId(BattlegroundConst.SpellSpiritHealChannel);
creature.SetChannelVisual(new SpellCastVisual(BattlegroundConst.SpellSpiritHealChannelVisual, 0));
//creature.CastSpell(creature, SPELL_SPIRIT_HEAL_CHANNEL, true);
if (AddCreature(entry, type, x, y, z, o) != null)
return true;
}
Log.outError(LogFilter.Battleground, $"Battleground.AddSpiritGuide: cannot create spirit guide (type: {type}, entry: {entry}) for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
EndNow();
return false;
@@ -1965,7 +1844,6 @@ namespace Game.BattleGrounds
public uint GetClientInstanceID() { return m_ClientInstanceID; }
public uint GetElapsedTime() { return m_StartTime; }
public uint GetRemainingTime() { return (uint)m_EndTime; }
public uint GetLastResurrectTime() { return m_LastResurrectTime; }
int GetStartDelayTime() { return m_StartDelayTime; }
public ArenaTypes GetArenaType() { return m_ArenaType; }
@@ -1980,7 +1858,6 @@ namespace Game.BattleGrounds
public void SetClientInstanceID(uint InstanceID) { m_ClientInstanceID = InstanceID; }
public void SetElapsedTime(uint Time) { m_StartTime = Time; }
public void SetRemainingTime(uint Time) { m_EndTime = (int)Time; }
public void SetLastResurrectTime(uint Time) { m_LastResurrectTime = Time; }
public void SetRated(bool state) { m_IsRated = state; }
public void SetArenaType(ArenaTypes type) { m_ArenaType = type; }
public void SetWinner(PvPTeamId winnerTeamId) { _winnerTeamId = winnerTeamId; }
@@ -2118,7 +1995,6 @@ namespace Game.BattleGrounds
uint m_ResetStatTimer;
uint m_ValidStartPositionTimer;
int m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
uint m_LastResurrectTime;
ArenaTypes m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattlegroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
@@ -2130,7 +2006,6 @@ namespace Game.BattleGrounds
uint m_LastPlayerPositionBroadcast;
// Player lists
List<ObjectGuid> m_ResurrectQueue = new(); // Player GUID
List<ObjectGuid> m_OfflineQueue = new(); // Player GUID
// Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction
@@ -452,19 +452,6 @@ namespace Game.BattleGrounds
Log.outError(LogFilter.Battleground, $"BattlegroundMgr.SendToBattleground: Instance {instanceId} (bgType {bgTypeId}) not found while trying to teleport player {player.GetName()}");
}
public void SendAreaSpiritHealerQuery(Player player, Battleground bg, ObjectGuid guid)
{
uint time = 30000 - bg.GetLastResurrectTime(); // resurrect every 30 seconds
if (time == 0xFFFFFFFF)
time = 0;
AreaSpiritHealerTime areaSpiritHealerTime = new();
areaSpiritHealerTime.HealerGuid = guid;
areaSpiritHealerTime.TimeLeft = time;
player.SendPacket(areaSpiritHealerTime);
}
bool IsArenaType(BattlegroundTypeId bgTypeId)
{
return bgTypeId == BattlegroundTypeId.AA || bgTypeId == BattlegroundTypeId.BE || bgTypeId == BattlegroundTypeId.NA
@@ -377,8 +377,6 @@ namespace Game.BattleGrounds.Zones
//remove bonus honor aura trigger creature when node is lost
DelCreature(node + 7);//null checks are in DelCreature! 0-6 spirit guides
RelocateDeadPlayers(BgCreatures[node]);
DelCreature(node);
// buff object isn't despawned
+16
View File
@@ -427,6 +427,9 @@ namespace Game.Entities
{
if (IsAIEnabled() && triggerJustAppeared && m_deathState != DeathState.Dead)
{
if (IsAreaSpiritHealer() && !IsAreaSpiritHealerIndividual())
CastSpell(null, BattlegroundConst.SpellSpiritHealChannelAoE, false);
if (m_respawnCompatibilityMode && VehicleKit != null)
VehicleKit.Reset();
@@ -1129,6 +1132,19 @@ namespace Game.Entities
SetHomePosition(GetPosition());
}
public void SummonGraveyardTeleporter()
{
if (!IsAreaSpiritHealer())
return;
uint npcEntry = GetFaction() == (uint)FactionTemplates.AllianceGeneric ? 26350 : 26351u;
// maybe NPC is summoned with these spells:
// ID - 24237 Summon Alliance Graveyard Teleporter (SERVERSIDE)
// ID - 46894 Summon Horde Graveyard Teleporter (SERVERSIDE)
SummonCreature(npcEntry, GetPosition(), TempSummonType.TimedDespawn, TimeSpan.FromSeconds(1), 0, 0);
}
public bool HasFlag(CreatureStaticFlags flag) { return _staticFlags.HasFlag(flag); }
public bool HasFlag(CreatureStaticFlags2 flag) { return _staticFlags.HasFlag(flag); }
public bool HasFlag(CreatureStaticFlags3 flag) { return _staticFlags.HasFlag(flag); }
@@ -55,6 +55,7 @@ namespace Game.Entities
long m_lastHonorUpdateTime;
uint m_contestedPvPTimer;
bool _usePvpItemLevels;
ObjectGuid _areaSpiritHealerGUID;
//Groups/Raids
GroupReference m_group = new();
+40
View File
@@ -3938,6 +3938,8 @@ namespace Game.Entities
public void ResurrectPlayer(float restore_percent, bool applySickness = false)
{
SetAreaSpiritHealer(null);
DeathReleaseLoc packet = new();
packet.MapID = -1;
SendPacket(packet);
@@ -4021,6 +4023,44 @@ namespace Game.Entities
}
}
ObjectGuid GetSpiritHealerGUID() { return _areaSpiritHealerGUID; }
public bool CanAcceptAreaSpiritHealFrom(Unit spiritHealer) { return spiritHealer.GetGUID() == _areaSpiritHealerGUID; }
public void SetAreaSpiritHealer(Creature creature)
{
if (!creature)
{
_areaSpiritHealerGUID = ObjectGuid.Empty;
RemoveAurasDueToSpell(BattlegroundConst.SpellWaitingForResurrect);
return;
}
if (!creature.IsAreaSpiritHealer())
return;
_areaSpiritHealerGUID = creature.GetGUID();
CastSpell(null, BattlegroundConst.SpellWaitingForResurrect);
}
public void SendAreaSpiritHealerTime(Unit spiritHealer)
{
int timeLeft = 0;
Spell spell = spiritHealer.GetCurrentSpell(CurrentSpellTypes.Channeled);
if (spell != null)
timeLeft = spell.GetTimer();
SendAreaSpiritHealerTime(spiritHealer.GetGUID(), timeLeft);
}
public void SendAreaSpiritHealerTime(ObjectGuid spiritHealerGUID, int timeLeft)
{
AreaSpiritHealerTime areaSpiritHealerTime = new();
areaSpiritHealerTime.HealerGuid = spiritHealerGUID;
areaSpiritHealerTime.TimeLeft = (uint)timeLeft;
SendPacket(areaSpiritHealerTime);
}
public void KillPlayer()
{
if (IsFlying() && GetTransport() == null)
+4
View File
@@ -466,6 +466,9 @@ namespace Game.Entities
if (IsInWorld)
{
if (IsAreaSpiritHealer())
ToCreature()?.SummonGraveyardTeleporter();
m_duringRemoveFromWorld = true;
UnitAI ai = GetAI();
if (ai != null)
@@ -847,6 +850,7 @@ namespace Game.Entities
NPCFlags.AreaSpiritHealer | NPCFlags.TabardDesigner | NPCFlags.Auctioneer);
}
public bool IsSpiritService() { return HasNpcFlag(NPCFlags.SpiritHealer | NPCFlags.AreaSpiritHealer); }
public bool IsAreaSpiritHealerIndividual() { return HasNpcFlag2(NPCFlags2.AreaSpiritHealerIndividual); }
public bool IsCritter() { return GetCreatureType() == CreatureType.Critter; }
public bool IsInFlight() { return HasUnitState(UnitState.InFlight); }
+33 -18
View File
@@ -10,6 +10,7 @@ using Game.Entities;
using Game.Groups;
using Game.Networking;
using Game.Networking.Packets;
using Game.Spells;
using System;
using System.Collections.Generic;
@@ -618,39 +619,53 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.AreaSpiritHealerQuery)]
void HandleAreaSpiritHealerQuery(AreaSpiritHealerQuery areaSpiritHealerQuery)
{
Creature unit = ObjectAccessor.GetCreature(GetPlayer(), areaSpiritHealerQuery.HealerGuid);
if (!unit)
Player player = GetPlayer();
Creature spiritHealer = ObjectAccessor.GetCreature(player, areaSpiritHealerQuery.HealerGuid);
if (spiritHealer == null)
return;
if (!unit.IsSpiritService()) // it's not spirit service
if (!spiritHealer.IsAreaSpiritHealer())
return;
Battleground bg = GetPlayer().GetBattleground();
if (bg != null)
Global.BattlegroundMgr.SendAreaSpiritHealerQuery(GetPlayer(), bg, areaSpiritHealerQuery.HealerGuid);
if (_player.GetExactDist(spiritHealer) > PlayerConst.MaxAreaSpiritHealerRange)
return;
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(GetPlayer().GetMap(), GetPlayer().GetZoneId());
if (bf != null)
bf.SendAreaSpiritHealerQuery(GetPlayer(), areaSpiritHealerQuery.HealerGuid);
if (spiritHealer.IsAreaSpiritHealerIndividual())
{
Aura aura = player.GetAura(BattlegroundConst.SpellSpiritHealPlayerAura);
if (aura != null)
{
player.SendAreaSpiritHealerTime(spiritHealer.GetGUID(), aura.GetDuration());
}
else
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(BattlegroundConst.SpellSpiritHealPlayerAura, Difficulty.None);
if (spellInfo != null)
{
spiritHealer.CastSpell(player, BattlegroundConst.SpellSpiritHealPlayerAura);
player.SendAreaSpiritHealerTime(spiritHealer.GetGUID(), spellInfo.GetDuration());
spiritHealer.CastSpell(null, BattlegroundConst.SpellSpiritHealChannelSelf);
}
}
}
else
_player.SendAreaSpiritHealerTime(spiritHealer);
}
[WorldPacketHandler(ClientOpcodes.AreaSpiritHealerQueue)]
void HandleAreaSpiritHealerQueue(AreaSpiritHealerQueue areaSpiritHealerQueue)
{
Creature unit = ObjectAccessor.GetCreature(GetPlayer(), areaSpiritHealerQueue.HealerGuid);
if (!unit)
Creature spiritHealer = ObjectAccessor.GetCreature(GetPlayer(), areaSpiritHealerQueue.HealerGuid);
if (spiritHealer == null)
return;
if (!unit.IsSpiritService()) // it's not spirit service
if (!spiritHealer.IsAreaSpiritHealer())
return;
Battleground bg = GetPlayer().GetBattleground();
if (bg)
bg.AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, GetPlayer().GetGUID());
if (_player.GetExactDist(spiritHealer) > PlayerConst.MaxAreaSpiritHealerRange)
return;
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(GetPlayer().GetMap(), GetPlayer().GetZoneId());
if (bf != null)
bf.AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, GetPlayer().GetGUID());
_player.SetAreaSpiritHealer(spiritHealer);
}
[WorldPacketHandler(ClientOpcodes.HearthAndResurrect)]
+2 -8
View File
@@ -138,16 +138,10 @@ namespace Game
unit.PauseMovement(pause);
unit.SetHomePosition(unit.GetPosition());
// If spiritguide, no need for gossip menu, just put player into resurrect queue
if (unit.IsAreaSpiritHealer())
{
Battleground bg = GetPlayer().GetBattleground();
if (bg)
{
bg.AddPlayerToResurrectQueue(unit.GetGUID(), GetPlayer().GetGUID());
Global.BattlegroundMgr.SendAreaSpiritHealerQuery(GetPlayer(), bg, unit.GetGUID());
return;
}
_player.SetAreaSpiritHealer(unit);
_player.SendAreaSpiritHealerTime(unit);
}
_player.PlayerTalkClass.ClearMenus();
-12
View File
@@ -4317,18 +4317,6 @@ namespace Game.Spells
case SpellFamilyNames.Generic:
switch (GetId())
{
case 2584: // Waiting to Resurrect
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
if (target.IsTypeId(TypeId.Player))
{
Battleground bg = target.ToPlayer().GetBattleground();
if (bg)
bg.RemovePlayerFromResurrectQueue(target.GetGUID());
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(target.GetMap(), target.GetZoneId());
if (bf != null)
bf.RemovePlayerFromResurrectQueue(target.GetGUID());
}
break;
case 36730: // Flame Strike
target.CastSpell(target, 36731, new CastSpellExtraArgs(this));
break;
+2
View File
@@ -7960,6 +7960,8 @@ namespace Game.Spells
public SpellInfo GetTriggeredByAuraSpell() { return m_triggeredByAuraSpell; }
public int GetTimer() { return m_timer; }
public static implicit operator bool(Spell spell)
{
return spell != null;
+20 -4
View File
@@ -4221,14 +4221,30 @@ namespace Game.Spells
Log.outDebug(LogFilter.Spells, "WORLD: SkillEFFECT");
}
/* There is currently no need for this effect. We handle it in Battleground.cpp
If we would handle the resurrection here, the spiritguide would instantly disappear as the
player revives, and so we wouldn't see the spirit heal visual effect on the npc.
This is why we use a half sec delay between the visual effect and the resurrection itself */
void EffectSpiritHeal()
{
Unit caster = GetCaster().ToUnit();
if (effectHandleMode == SpellEffectHandleMode.Hit)
caster.CastSpell(null, BattlegroundConst.SpellResurrectionVisual, true);
if (effectHandleMode != SpellEffectHandleMode.HitTarget)
return;
Player playerTarget = unitTarget.ToPlayer();
if (playerTarget != null)
{
if (!playerTarget.IsInWorld)
return;
// skip if player does not want to live
if (!playerTarget.CanAcceptAreaSpiritHealFrom(caster))
return;
playerTarget.ResurrectPlayer(1.0f);
playerTarget.CastSpell(playerTarget, BattlegroundConst.SpellPetSummoned, true);
playerTarget.CastSpell(playerTarget, BattlegroundConst.SpellSpiritHealMana, true);
playerTarget.SpawnCorpseBones(false);
}
}
// remove insignia spell effect
-2
View File
@@ -902,8 +902,6 @@ namespace Game.Spells
case 34976: // Netherstorm Flag
return map_id == 566 && player != null && player.InBattleground() ? SpellCastResult.SpellCastOk : SpellCastResult.RequiresArea;
case 2584: // Waiting to Resurrect
case 22011: // Spirit Heal Channel
case 22012: // Spirit Heal
case 42792: // Recently Dropped Flag
case 43681: // Inactive
case 44535: // Spirit Heal (mana)
+118 -12
View File
@@ -1937,7 +1937,7 @@ namespace Scripts.Spells.Generic
OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
// 35357 - Spawn Feign Death
[Script] // 51329 - Feign Death
class spell_gen_feign_death_no_dyn_flag : AuraScript
@@ -5010,17 +5010,17 @@ namespace Scripts.Spells.Generic
}
}
// 2825 - Bloodlust
// 32182 - Heroism
// 80353 - Time Warp
// 264667 - Primal Rage
// 390386 - Fury of the Aspects
// 146555 - Drums of Rage
// 178207 - Drums of Fury
// 230935 - Drums of the Mountain
// 256740 - Drums of the Maelstrom
// 309658 - Drums of Deathly Ferocity
// 381301 - Feral Hide Drums
// 2825 - Bloodlust
// 32182 - Heroism
// 80353 - Time Warp
// 264667 - Primal Rage
// 390386 - Fury of the Aspects
// 146555 - Drums of Rage
// 178207 - Drums of Fury
// 230935 - Drums of the Mountain
// 256740 - Drums of the Maelstrom
// 309658 - Drums of Deathly Ferocity
// 381301 - Feral Hide Drums
[Script("spell_sha_bloodlust", SpellIds.ShamanSated)]
[Script("spell_sha_heroism", SpellIds.ShamanExhaustion)]
[Script("spell_mage_time_warp", SpellIds.MageTemporalDisplacement)]
@@ -5071,6 +5071,112 @@ namespace Scripts.Spells.Generic
}
}
// AoE resurrections by spirit guides
[Script] // 22012 - Spirit Heal
class spell_gen_spirit_heal_aoe : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
Unit caster = GetCaster();
targets.RemoveAll(target =>
{
Player playerTarget = target.ToPlayer();
if (playerTarget != null)
return !playerTarget.CanAcceptAreaSpiritHealFrom(caster);
return true;
});
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaAlly));
}
}
// Personal resurrections in battlegrounds
[Script] // 156758 - Spirit Heal
class spell_gen_spirit_heal_personal : AuraScript
{
uint SPELL_SPIRIT_HEAL_EFFECT = 156763;
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
return;
Player targetPlayer = GetTarget().ToPlayer();
if (targetPlayer == null)
return;
Unit caster = GetCaster();
if (caster == null)
return;
if (targetPlayer.CanAcceptAreaSpiritHealFrom(caster))
caster.CastSpell(targetPlayer, SPELL_SPIRIT_HEAL_EFFECT);
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
class RecastSpiritHealChannelEvent : BasicEvent
{
Unit _caster;
public RecastSpiritHealChannelEvent(Unit caster)
{
_caster = caster;
}
public override bool Execute(ulong e_time, uint p_time)
{
if (_caster.GetChannelSpellId() == 0)
_caster.CastSpell(null, BattlegroundConst.SpellSpiritHealChannelAoE, false);
return true;
}
}
[Script] // 22011 - Spirit Heal Channel
class spell_gen_spirit_heal_channel : AuraScript
{
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
return;
Unit target = GetTarget();
target.m_Events.AddEventAtOffset(new RecastSpiritHealChannelEvent(target), TimeSpan.FromSeconds(1));
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
}
}
[Script] // 2584 - Waiting to Resurrect
class spell_gen_waiting_to_resurrect : AuraScript
{
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Player targetPlayer = GetTarget().ToPlayer();
if (targetPlayer == null)
return;
targetPlayer.SetAreaSpiritHealer(null);
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
// 40307 - Stasis Field
class StasisFieldSearcher : ICheck<Unit>
{