Core/PacketIO: Handle QueryCountdownTimer
* Add it to battleground * Base implementation countdowns in Group * Fix timer sync between groups in battlegrounds Port From (https://github.com/TrinityCore/TrinityCore/commit/6ed8b5c9077aba788ff5bc51f2652109bfea6175)
This commit is contained in:
@@ -166,4 +166,11 @@ namespace Framework.Constants
|
|||||||
|
|
||||||
Max
|
Max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CountdownTimerType
|
||||||
|
{
|
||||||
|
Pvp = 0,
|
||||||
|
ChallengeMode = 1,
|
||||||
|
PlayerCountdown = 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1888,13 +1888,6 @@ namespace Framework.Constants
|
|||||||
Max
|
Max
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TimerType
|
|
||||||
{
|
|
||||||
Pvp = 0,
|
|
||||||
ChallengerMode = 1,
|
|
||||||
PlayerCountdown = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum GameError : uint
|
public enum GameError : uint
|
||||||
{
|
{
|
||||||
System = 0,
|
System = 0,
|
||||||
|
|||||||
@@ -130,10 +130,7 @@ namespace Game.BattleGrounds
|
|||||||
// Update start time and reset stats timer
|
// Update start time and reset stats timer
|
||||||
SetElapsedTime(GetElapsedTime() + diff);
|
SetElapsedTime(GetElapsedTime() + diff);
|
||||||
if (GetStatus() == BattlegroundStatus.WaitJoin)
|
if (GetStatus() == BattlegroundStatus.WaitJoin)
|
||||||
{
|
|
||||||
m_ResetStatTimer += diff;
|
m_ResetStatTimer += diff;
|
||||||
m_CountdownTimer += diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
PostUpdateImpl(diff);
|
PostUpdateImpl(diff);
|
||||||
}
|
}
|
||||||
@@ -278,26 +275,6 @@ namespace Game.BattleGrounds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send packet every 10 seconds until the 2nd field reach 0
|
|
||||||
if (m_CountdownTimer >= 10000)
|
|
||||||
{
|
|
||||||
uint countdownMaxForBGType = IsArena() ? BattlegroundConst.ArenaCountdownMax : BattlegroundConst.BattlegroundCountdownMax;
|
|
||||||
|
|
||||||
StartTimer timer = new();
|
|
||||||
timer.Type = TimerType.Pvp;
|
|
||||||
timer.TimeLeft = countdownMaxForBGType - (GetElapsedTime() / 1000);
|
|
||||||
timer.TotalTime = countdownMaxForBGType;
|
|
||||||
|
|
||||||
foreach (var guid in GetPlayers().Keys)
|
|
||||||
{
|
|
||||||
Player player = Global.ObjAccessor.FindPlayer(guid);
|
|
||||||
if (player != null)
|
|
||||||
player.SendPacket(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CountdownTimer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_Events.HasAnyFlag(BattlegroundEventFlags.Event1))
|
if (!m_Events.HasAnyFlag(BattlegroundEventFlags.Event1))
|
||||||
{
|
{
|
||||||
m_Events |= BattlegroundEventFlags.Event1;
|
m_Events |= BattlegroundEventFlags.Event1;
|
||||||
@@ -316,6 +293,11 @@ namespace Game.BattleGrounds
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_preparationStartTime = GameTime.GetGameTime();
|
||||||
|
foreach (Group group in m_BgRaids)
|
||||||
|
if (group != null)
|
||||||
|
group.StartCountdown(CountdownTimerType.Pvp, TimeSpan.FromSeconds((int)StartDelayTimes[BattlegroundConst.EventIdFirst] / 1000), _preparationStartTime);
|
||||||
|
|
||||||
StartingEventCloseDoors();
|
StartingEventCloseDoors();
|
||||||
SetStartDelayTime(StartDelayTimes[BattlegroundConst.EventIdFirst]);
|
SetStartDelayTime(StartDelayTimes[BattlegroundConst.EventIdFirst]);
|
||||||
// First start warning - 2 or 1 Minute
|
// First start warning - 2 or 1 Minute
|
||||||
@@ -1017,18 +999,8 @@ namespace Game.BattleGrounds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetStatus() == BattlegroundStatus.WaitJoin) // not started yet
|
if (GetStatus() == BattlegroundStatus.WaitJoin) // not started yet
|
||||||
{
|
|
||||||
player.CastSpell(player, BattlegroundConst.SpellPreparation, true); // reduces all mana cost of spells.
|
player.CastSpell(player, BattlegroundConst.SpellPreparation, true); // reduces all mana cost of spells.
|
||||||
|
|
||||||
uint countdownMaxForBGType = IsArena() ? BattlegroundConst.ArenaCountdownMax : BattlegroundConst.BattlegroundCountdownMax;
|
|
||||||
StartTimer timer = new();
|
|
||||||
timer.Type = TimerType.Pvp;
|
|
||||||
timer.TimeLeft = countdownMaxForBGType - (GetElapsedTime() / 1000);
|
|
||||||
timer.TotalTime = countdownMaxForBGType;
|
|
||||||
|
|
||||||
player.SendPacket(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bp.Mercenary)
|
if (bp.Mercenary)
|
||||||
{
|
{
|
||||||
if (bp.Team == Team.Horde)
|
if (bp.Team == Team.Horde)
|
||||||
@@ -1062,6 +1034,11 @@ namespace Game.BattleGrounds
|
|||||||
group = new Group();
|
group = new Group();
|
||||||
SetBgRaid(team, group);
|
SetBgRaid(team, group);
|
||||||
group.Create(player);
|
group.Create(player);
|
||||||
|
TimeSpan countdownMaxForBGType = TimeSpan.FromSeconds((int)StartDelayTimes[BattlegroundConst.EventIdFirst] / 1000);
|
||||||
|
if (_preparationStartTime != 0)
|
||||||
|
group.StartCountdown(CountdownTimerType.Pvp, countdownMaxForBGType, _preparationStartTime);
|
||||||
|
else
|
||||||
|
group.StartCountdown(CountdownTimerType.Pvp, countdownMaxForBGType);
|
||||||
}
|
}
|
||||||
else // raid already exist
|
else // raid already exist
|
||||||
{
|
{
|
||||||
@@ -1952,7 +1929,6 @@ namespace Game.BattleGrounds
|
|||||||
BattlegroundStatus m_Status;
|
BattlegroundStatus m_Status;
|
||||||
uint m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use
|
uint m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use
|
||||||
uint m_StartTime;
|
uint m_StartTime;
|
||||||
uint m_CountdownTimer;
|
|
||||||
uint m_ResetStatTimer;
|
uint m_ResetStatTimer;
|
||||||
uint m_ValidStartPositionTimer;
|
uint m_ValidStartPositionTimer;
|
||||||
int m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
|
int m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
|
||||||
@@ -1994,6 +1970,9 @@ namespace Game.BattleGrounds
|
|||||||
List<uint> _pvpStatIds = new();
|
List<uint> _pvpStatIds = new();
|
||||||
|
|
||||||
List<BattlegroundPlayerPosition> _playerPositions = new();
|
List<BattlegroundPlayerPosition> _playerPositions = new();
|
||||||
|
|
||||||
|
// Time when the first message "the battle will begin in 2minutes" is send (or 1m for arenas)
|
||||||
|
long _preparationStartTime;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1394,6 +1394,25 @@ namespace Game.Groups
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StartCountdown(CountdownTimerType timerType, TimeSpan duration, long? startTime = null)
|
||||||
|
{
|
||||||
|
if (timerType < 0 || (int)timerType >= _countdowns.Length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_countdowns[(int)timerType] == null)
|
||||||
|
_countdowns[(int)timerType] = new();
|
||||||
|
|
||||||
|
_countdowns[(int)timerType].StartCountdown(duration, startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CountdownInfo GetCountdownInfo(CountdownTimerType timerType)
|
||||||
|
{
|
||||||
|
if (timerType < 0 || (int)timerType >= _countdowns.Length)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return _countdowns[(int)timerType];
|
||||||
|
}
|
||||||
|
|
||||||
public void SetLootMethod(LootMethod method)
|
public void SetLootMethod(LootMethod method)
|
||||||
{
|
{
|
||||||
m_lootMethod = method;
|
m_lootMethod = method;
|
||||||
@@ -1961,6 +1980,8 @@ namespace Game.Groups
|
|||||||
// Raid markers
|
// Raid markers
|
||||||
RaidMarker[] m_markers = new RaidMarker[MapConst.RaidMarkersCount];
|
RaidMarker[] m_markers = new RaidMarker[MapConst.RaidMarkersCount];
|
||||||
uint m_activeMarkers;
|
uint m_activeMarkers;
|
||||||
|
|
||||||
|
CountdownInfo[] _countdowns = new CountdownInfo[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MemberSlot
|
public class MemberSlot
|
||||||
@@ -1986,4 +2007,32 @@ namespace Game.Groups
|
|||||||
public WorldLocation Location;
|
public WorldLocation Location;
|
||||||
public ObjectGuid TransportGUID;
|
public ObjectGuid TransportGUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CountdownInfo
|
||||||
|
{
|
||||||
|
long _startTime;
|
||||||
|
long _endTime;
|
||||||
|
|
||||||
|
public long GetTimeLeft()
|
||||||
|
{
|
||||||
|
return Math.Max(_endTime - GameTime.GetGameTime(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartCountdown(TimeSpan duration, long? startTime)
|
||||||
|
{
|
||||||
|
_startTime = startTime.HasValue ? startTime.Value : GameTime.GetGameTime();
|
||||||
|
_endTime = (long)(_startTime + duration.TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsRunning()
|
||||||
|
{
|
||||||
|
return _endTime > GameTime.GetGameTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetTotalTime()
|
||||||
|
{
|
||||||
|
return _endTime - _startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -465,6 +465,25 @@ namespace Game
|
|||||||
SendPacket(splashScreenShowLatest);
|
SendPacket(splashScreenShowLatest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[WorldPacketHandler(ClientOpcodes.QueryCountdownTimer, Processing = PacketProcessing.Inplace)]
|
||||||
|
void HandleQueryCountdownTimer(QueryCountdownTimer queryCountdownTimer)
|
||||||
|
{
|
||||||
|
Group group = _player.GetGroup();
|
||||||
|
if (group == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CountdownInfo info = group.GetCountdownInfo(queryCountdownTimer.TimerType);
|
||||||
|
if (info == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StartTimer startTimer = new();
|
||||||
|
startTimer.Type = queryCountdownTimer.TimerType;
|
||||||
|
startTimer.TimeLeft = info.GetTimeLeft();
|
||||||
|
startTimer.TotalTime = info.GetTotalTime();
|
||||||
|
|
||||||
|
_player.SendPacket(startTimer);
|
||||||
|
}
|
||||||
|
|
||||||
[WorldPacketHandler(ClientOpcodes.ChatUnregisterAllAddonPrefixes)]
|
[WorldPacketHandler(ClientOpcodes.ChatUnregisterAllAddonPrefixes)]
|
||||||
void HandleUnregisterAllAddonPrefixes(ChatUnregisterAllAddonPrefixes packet)
|
void HandleUnregisterAllAddonPrefixes(ChatUnregisterAllAddonPrefixes packet)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ namespace Game.Networking.Packets
|
|||||||
public bool IsTournamentRealm;
|
public bool IsTournamentRealm;
|
||||||
public bool XRealmPvpAlert;
|
public bool XRealmPvpAlert;
|
||||||
public bool BlockExitingLoadingScreen; // when set to true, sending SMSG_UPDATE_OBJECT with CreateObject Self bit = true will not hide loading screen
|
public bool BlockExitingLoadingScreen; // when set to true, sending SMSG_UPDATE_OBJECT with CreateObject Self bit = true will not hide loading screen
|
||||||
// instead it will be done after this packet is sent again with false in this bit and SMSG_UPDATE_OBJECT Values for player
|
// instead it will be done after this packet is sent again with false in this bit and SMSG_UPDATE_OBJECT Values for player
|
||||||
public uint? RestrictedAccountMaxLevel;
|
public uint? RestrictedAccountMaxLevel;
|
||||||
public ulong? RestrictedAccountMaxMoney;
|
public ulong? RestrictedAccountMaxMoney;
|
||||||
public uint? InstanceGroupSize;
|
public uint? InstanceGroupSize;
|
||||||
@@ -1156,7 +1156,7 @@ namespace Game.Networking.Packets
|
|||||||
Enable = _worldPacket.HasBit();
|
Enable = _worldPacket.HasBit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Enable;
|
public bool Enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AccountHeirloomUpdate : ServerPacket
|
class AccountHeirloomUpdate : ServerPacket
|
||||||
@@ -1277,7 +1277,19 @@ namespace Game.Networking.Packets
|
|||||||
|
|
||||||
public long TotalTime;
|
public long TotalTime;
|
||||||
public long TimeLeft;
|
public long TimeLeft;
|
||||||
public TimerType Type;
|
public CountdownTimerType Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QueryCountdownTimer : ClientPacket
|
||||||
|
{
|
||||||
|
public CountdownTimerType TimerType;
|
||||||
|
|
||||||
|
public QueryCountdownTimer(WorldPacket packet) : base(packet) { }
|
||||||
|
|
||||||
|
public override void Read()
|
||||||
|
{
|
||||||
|
TimerType = (CountdownTimerType)_worldPacket.ReadInt32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConversationLineStarted : ClientPacket
|
class ConversationLineStarted : ClientPacket
|
||||||
|
|||||||
Reference in New Issue
Block a user