server-master/srcs/Plugin.RainbowBattle/EventHandlers/RainbowBattleCaptureFlagEventHandler.cs
2026-02-10 18:21:30 +01:00

205 lines
No EOL
8.7 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsAPI.Packets.Enums.Rainbow;
using WingsEmu.Game._enum;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Configurations;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Networking;
using WingsEmu.Game.RainbowBattle;
using WingsEmu.Game.RainbowBattle.Event;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Chat;
namespace Plugin.RainbowBattle.EventHandlers
{
public class RainbowBattleCaptureFlagEventHandler : IAsyncEventProcessor<RainbowBattleCaptureFlagEvent>
{
private readonly IDelayManager _delayManager;
private readonly IGameLanguageService _gameLanguageService;
private readonly RainbowBattleConfiguration _rainbowBattleConfiguration;
public RainbowBattleCaptureFlagEventHandler(IDelayManager delayManager, IGameLanguageService gameLanguageService, RainbowBattleConfiguration rainbowBattleConfiguration)
{
_delayManager = delayManager;
_gameLanguageService = gameLanguageService;
_rainbowBattleConfiguration = rainbowBattleConfiguration;
}
public async Task HandleAsync(RainbowBattleCaptureFlagEvent e, CancellationToken cancellation)
{
INpcEntity npc = e.NpcEntity;
IClientSession session = e.Sender;
if (npc.RainbowFlag == null)
{
return;
}
RainbowBattleParty rainbowBattleParty = session.PlayerEntity.RainbowBattleComponent.RainbowBattleParty;
if (rainbowBattleParty == null)
{
return;
}
if (!rainbowBattleParty.Started)
{
return;
}
if (rainbowBattleParty.FinishTime != null)
{
return;
}
if (session.PlayerEntity.RainbowBattleComponent.IsFrozen)
{
return;
}
int distance = session.PlayerEntity.Position.GetDistance(npc.Position);
if (distance > 5)
{
return;
}
RainbowBattleTeamType? flagTeam = npc.RainbowFlag.FlagTeamType switch
{
RainbowBattleFlagTeamType.Red => RainbowBattleTeamType.Red,
RainbowBattleFlagTeamType.Blue => RainbowBattleTeamType.Blue,
_ => null
};
RainbowBattleTeamType playerTeam = session.PlayerEntity.RainbowBattleComponent.Team;
if (flagTeam == playerTeam)
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_ALREADY_CAPTURED), ChatMessageColorType.Yellow);
return;
}
if (npc.RainbowFlag.RainbowBattleLastTakeOver.AddSeconds(_rainbowBattleConfiguration.DelayBetweenCapture) > DateTime.UtcNow)
{
int cooldown = (int)(npc.RainbowFlag.RainbowBattleLastTakeOver.AddSeconds(_rainbowBattleConfiguration.DelayBetweenCapture) - DateTime.UtcNow).TotalSeconds;
session.SendChatMessage(session.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_CAPTURE_COOLDOWN, cooldown), ChatMessageColorType.Yellow);
return;
}
if (!e.IsConfirm)
{
await session.PlayerEntity.RemoveInvisibility();
DateTime waitUntil = await _delayManager.RegisterAction(session.PlayerEntity, DelayedActionType.RainbowBattleCaptureFlag);
session.SendDelay((int)(waitUntil - DateTime.UtcNow).TotalMilliseconds, GuriType.IceBreaker, $"guri 504 {npc.Id}");
return;
}
if (!await _delayManager.CanPerformAction(session.PlayerEntity, DelayedActionType.RainbowBattleCaptureFlag))
{
return;
}
await _delayManager.CompleteAction(session.PlayerEntity, DelayedActionType.RainbowBattleCaptureFlag);
// If flag was red and player is in blue team
if (flagTeam != null && flagTeam != playerTeam)
{
ConcurrentDictionary<RainbowBattleFlagType, byte> flags = flagTeam == RainbowBattleTeamType.Red ? rainbowBattleParty.RedFlags : rainbowBattleParty.BlueFlags;
byte flagsCounter = (byte)(flags.TryGetValue(npc.RainbowFlag.FlagType, out byte count) ? count : 0);
if (flagsCounter > 0)
{
flagsCounter--;
flags[npc.RainbowFlag.FlagType] = flagsCounter;
}
}
int flagPoints = (byte)npc.RainbowFlag.FlagType * 3;
npc.RainbowFlag.RainbowBattleLastTakeOver = DateTime.UtcNow;
switch (playerTeam)
{
case RainbowBattleTeamType.Red:
byte redFlags = (byte)(rainbowBattleParty.RedFlags.TryGetValue(npc.RainbowFlag.FlagType, out byte redCount) ? redCount : 0);
redFlags++;
rainbowBattleParty.RedFlags[npc.RainbowFlag.FlagType] = redFlags;
npc.RainbowFlag.FlagTeamType = RainbowBattleFlagTeamType.Red;
rainbowBattleParty.IncreaseRedPoints(flagPoints);
rainbowBattleParty.IncreaseBluePoints(-flagPoints);
break;
case RainbowBattleTeamType.Blue:
byte blueFlags = (byte)(rainbowBattleParty.BlueFlags.TryGetValue(npc.RainbowFlag.FlagType, out byte blueCount) ? blueCount : 0);
blueFlags++;
rainbowBattleParty.BlueFlags[npc.RainbowFlag.FlagType] = blueFlags;
npc.RainbowFlag.FlagTeamType = RainbowBattleFlagTeamType.Blue;
rainbowBattleParty.IncreaseBluePoints(flagPoints);
rainbowBattleParty.IncreaseRedPoints(-flagPoints);
break;
}
npc.MapInstance.Broadcast(npc.GenerateFlagPacket());
EffectType effectType = npc.RainbowFlag.FlagTeamType switch
{
RainbowBattleFlagTeamType.None => EffectType.NoneFlag,
RainbowBattleFlagTeamType.Red => EffectType.RedFlag,
RainbowBattleFlagTeamType.Blue => EffectType.BlueFlag,
_ => EffectType.NoneFlag
};
npc.MapInstance.Broadcast(npc.GenerateEffectPacket(effectType));
foreach (IClientSession red in rainbowBattleParty.RedTeam)
{
string npcName = _gameLanguageService.GetNpcMonsterName(npc, red);
if (playerTeam == RainbowBattleTeamType.Red)
{
red.SendMsg(red.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_ALLY_CAPTURED, session.PlayerEntity.Name, npcName), MsgMessageType.Middle);
red.SendChatMessage(red.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_ALLY_CAPTURED, session.PlayerEntity.Name, npcName), ChatMessageColorType.Green);
}
else
{
red.SendMsg(red.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_BLUE_TEAM_FLAG_CAPTURED, npcName), MsgMessageType.Middle);
red.SendChatMessage(red.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_BLUE_TEAM_FLAG_CAPTURED, npcName), ChatMessageColorType.Red);
}
}
foreach (IClientSession blue in rainbowBattleParty.BlueTeam)
{
string npcName = _gameLanguageService.GetNpcMonsterName(npc, blue);
if (playerTeam == RainbowBattleTeamType.Blue)
{
blue.SendMsg(blue.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_ALLY_CAPTURED, session.PlayerEntity.Name, npcName), MsgMessageType.Middle);
blue.SendChatMessage(blue.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_ALLY_CAPTURED, session.PlayerEntity.Name, npcName), ChatMessageColorType.Green);
}
else
{
blue.SendMsg(blue.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_RED_TEAM_FLAG_CAPTURED, npcName), MsgMessageType.Middle);
blue.SendChatMessage(blue.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_MESSAGE_RED_TEAM_FLAG_CAPTURED, npcName), ChatMessageColorType.Red);
}
}
session.PlayerEntity.RainbowBattleComponent.ActivityPoints += _rainbowBattleConfiguration.CaptureActivityPoints;
await session.EmitEventAsync(new RainbowBattleRefreshScoreEvent
{
RainbowBattleParty = rainbowBattleParty
});
}
}
}