158 lines
No EOL
4.9 KiB
C#
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));
|
|
}
|
|
} |