server-master/srcs/_plugins/Plugin.Raids/RecurrentJob/RaidSystem.cs
2026-02-10 18:21:30 +01:00

158 lines
No EOL
4.9 KiB
C#

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using PhoenixLib.Events;
using PhoenixLib.Logging;
using Plugin.Raids.Const;
using WingsEmu.Core.Extensions;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Monster.Event;
using WingsEmu.Game.Raids;
using WingsEmu.Game.Raids.Enum;
using WingsEmu.Game.Raids.Events;
using WingsEmu.Packets.Enums.Chat;
namespace Plugin.Raids.RecurrentJob;
public class RaidSystem : BackgroundService
{
private static readonly TimeSpan Interval = TimeSpan.FromSeconds(1);
private readonly IAsyncEventPipeline _eventPipeline;
private readonly IRaidManager _raidManager;
public RaidSystem(IRaidManager raidManager, IAsyncEventPipeline eventPipeline)
{
_raidManager = raidManager;
_eventPipeline = eventPipeline;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Log.Info("[RAID_SYSTEM] Started!");
while (!stoppingToken.IsCancellationRequested)
{
try
{
foreach (RaidParty raid in _raidManager.Raids.ToArray())
{
await ProcessRaid(raid);
}
}
catch (Exception e)
{
Log.Error("[RAID_SYSTEM]", e);
}
await Task.Delay(Interval, stoppingToken);
}
}
private async Task ProcessRaid(RaidParty raidParty)
{
DateTime currentDate = DateTime.UtcNow;
await TryFinish(raidParty, currentDate);
await TryRemove(raidParty, currentDate);
await TryExecuteEventsAfterSlowMo(raidParty, currentDate);
await TryRefreshInfo(raidParty);
await TrySpawnMonsterByRaidWave(raidParty, currentDate);
}
private async Task TrySpawnMonsterByRaidWave(RaidParty raidParty, DateTime currentDate)
{
if (!raidParty.Started || raidParty.Finished || raidParty.Instance == null)
{
return;
}
if (raidParty.Instance.RaidSubInstances == null)
{
return;
}
foreach (RaidSubInstance raidSubInstance in raidParty.Instance.RaidSubInstances.Values)
{
if (raidSubInstance == null)
{
continue;
}
if (!raidSubInstance.RaidWavesActivated)
{
continue;
}
if (!raidSubInstance.RaidWaves.Any())
{
continue;
}
if (raidSubInstance.LastRaidWave > currentDate)
{
continue;
}
RaidWave wave = raidSubInstance.RaidWaves.GetOrDefault(raidSubInstance.RaidWaveState);
if (wave == null)
{
raidSubInstance.RaidWaveState = 0;
raidSubInstance.LastRaidWave = currentDate;
continue;
}
raidSubInstance.LastRaidWave = currentDate.AddSeconds(wave.TimeInSeconds);
raidSubInstance.RaidWaveState++;
await _eventPipeline.ProcessEventAsync(new MonsterSummonEvent(raidSubInstance.MapInstance, wave.Monsters));
raidSubInstance.MapInstance.Broadcast(x =>
x.GenerateMsgPacket(x.GetLanguage(GameDialogKey.RAID_SHOUTMESSAGE_MONSTERS_WAVE), MsgMessageType.Middle));
}
}
private async Task TryFinish(RaidParty raidParty, DateTime currentTime)
{
if (!raidParty.Started || raidParty.Finished || raidParty.Instance.FinishDate > currentTime)
{
return;
}
await _eventPipeline.ProcessEventAsync(new RaidInstanceFinishEvent(raidParty, RaidFinishType.TimeIsUp));
}
private async Task TryRemove(RaidParty raidParty, DateTime currentTime)
{
if (!raidParty.Started || !raidParty.Finished || raidParty.Instance.RemoveDate > currentTime)
{
return;
}
Log.Warn($"REMOVING RAID MAP {raidParty.Instance.RemoveDate}");
await _eventPipeline.ProcessEventAsync(new RaidInstanceDestroyEvent(raidParty));
}
private async Task TryExecuteEventsAfterSlowMo(RaidParty raidParty, DateTime currentTime)
{
if (!raidParty.Started || !raidParty.Finished || raidParty.Instance.FinishSlowMoDate == null || raidParty.Instance.FinishSlowMoDate > currentTime)
{
return;
}
raidParty.Instance.SetFinishSlowMoDate(null);
foreach (RaidSubInstance subInstance in raidParty.Instance.RaidSubInstances.Values)
{
await subInstance.TriggerEvents(RaidConstEventKeys.RaidSubInstanceAfterSlowMo);
}
}
private async Task TryRefreshInfo(RaidParty raidParty)
{
if (!raidParty.Started || raidParty.Destroy)
{
return;
}
await _eventPipeline.ProcessEventAsync(new RaidInstanceRefreshInfoEvent(raidParty));
}
}