server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/BCards/Handlers/BCardMeteoriteTeleportHandler.cs
2026-02-10 18:21:30 +01:00

206 lines
No EOL
8.1 KiB
C#

// WingsEmu
//
// Developed by NosWings Team
using System;
using System.Collections.Generic;
using PhoenixLib.Events;
using WingsEmu.DTOs.BCards;
using WingsEmu.Game;
using WingsEmu.Game._enum;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Families;
using WingsEmu.Game.Groups;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Maps;
using WingsEmu.Game.Mates;
using WingsEmu.Game.Monster.Event;
using WingsEmu.Packets.Enums;
namespace WingsEmu.Plugins.BasicImplementations.BCards.Handlers;
public class BCardMeteoriteTeleportHandler : IBCardEffectAsyncHandler
{
private readonly IAsyncEventPipeline _asyncEventPipeline;
private readonly IRandomGenerator _randomGenerator;
private readonly ITeleportManager _teleportManager;
public BCardMeteoriteTeleportHandler(ITeleportManager teleportManager, IRandomGenerator randomGenerator, IAsyncEventPipeline asyncEventPipeline)
{
_teleportManager = teleportManager;
_randomGenerator = randomGenerator;
_asyncEventPipeline = asyncEventPipeline;
}
public BCardType HandledType => BCardType.MeteoriteTeleport;
public void Execute(IBCardEffectContext ctx)
{
IBattleEntity sender = ctx.Sender;
IBattleEntity target = ctx.Target;
int firstData = ctx.BCard.FirstData;
BCardDTO bCard = ctx.BCard;
int firstDataValue = bCard.FirstDataValue(sender.Level);
switch (ctx.BCard.SubType)
{
case (byte)AdditionalTypes.MeteoriteTeleport.CauseMeteoriteFall:
if (!(sender is IPlayerEntity senderCharacter))
{
return;
}
int meteoritesAmount = firstDataValue + 10;
var meteorites = new List<ToSummon>();
Position positionNonTarget = ctx.Position;
for (int i = 0; i < meteoritesAmount; i++)
{
int x = positionNonTarget.X + _randomGenerator.RandomNumber(-4, 4);
int y = positionNonTarget.Y + _randomGenerator.RandomNumber(-4, 4);
if (senderCharacter.MapInstance.IsBlockedZone(x, y))
{
x = positionNonTarget.X;
y = positionNonTarget.Y;
}
int vnum = _randomGenerator.RandomNumber((short)MonsterVnum.FIRST_METEORITE, (short)MonsterVnum.SECOND_METEORITE + 1);
var toSummon = new ToSummon
{
VNum = (short)vnum,
SpawnCell = new Position((short)x, (short)y),
Target = senderCharacter,
IsMoving = true,
IsHostile = true
};
meteorites.Add(toSummon);
}
_asyncEventPipeline.ProcessEventAsync(new MonsterSummonEvent(senderCharacter.MapInstance, meteorites, senderCharacter)).ConfigureAwait(false).GetAwaiter().GetResult();
break;
case (byte)AdditionalTypes.MeteoriteTeleport.TeleportYouAndGroupToSavedLocation:
if (!(sender is IPlayerEntity character))
{
return;
}
IFamily family = character.Family;
if (!character.HasBuff(BuffVnums.MEMORIAL))
{
_teleportManager.RemovePosition(character.Id);
return;
}
Position position = _teleportManager.GetPosition(character.Id);
if (position.X == 0 && position.Y == 0)
{
_teleportManager.SavePosition(character.Id, character.Position);
character.BroadcastEffectGround(EffectType.ArchmageTeleportSet, character.PositionX, character.PositionY, false);
character.SetSkillCooldown(ctx.Skill);
character.RemoveCastingSkill();
return;
}
short savedX = _teleportManager.GetPosition(character.Id).X;
short savedY = _teleportManager.GetPosition(character.Id).Y;
IEnumerable<IBattleEntity> allies = sender.GetAlliesInRange(target, ctx.Skill.AoERange);
int counter = 0;
foreach (IBattleEntity entity in allies)
{
if (counter == firstData)
{
break;
}
if (entity.IsNpc() && !entity.IsMate())
{
continue;
}
if (entity.IsMate())
{
var mateEntity = (IMateEntity)entity;
IPlayerEntity mateOwner = mateEntity.Owner;
if (character.Id == mateOwner?.Id)
{
continue;
}
if (mateOwner == null)
{
continue;
}
PlayerGroup mateOwnerGroup = mateOwner.GetGroup();
PlayerGroup sessionGroup = character.GetGroup();
bool isInGroupMate = mateOwnerGroup?.GroupId == sessionGroup?.GroupId;
if (!isInGroupMate)
{
if (mateOwner.Family?.Id != family?.Id)
{
continue;
}
}
mateEntity.BroadcastEffectGround(EffectType.ArchmageTeleport, mateEntity.PositionX, mateEntity.PositionY, false);
mateEntity.MapInstance.Broadcast(mateEntity.GenerateEffectPacket(EffectType.ArchmageTeleportAfter));
mateEntity.TeleportOnMap(savedX, savedY);
counter++;
continue;
}
var anotherCharacter = (IPlayerEntity)entity;
if (character.Id == anotherCharacter.Id)
{
continue;
}
if (!anotherCharacter.IsInGroup() && !anotherCharacter.IsInFamily())
{
continue;
}
PlayerGroup anotherCharacterGroup = anotherCharacter.GetGroup();
PlayerGroup characterGroup = character.GetGroup();
bool isInGroup = anotherCharacterGroup?.GroupId == characterGroup?.GroupId;
if (!isInGroup)
{
if (anotherCharacter.Family?.Id != family?.Id)
{
continue;
}
}
anotherCharacter.BroadcastEffectGround(EffectType.ArchmageTeleport, anotherCharacter.PositionX, anotherCharacter.PositionY, false);
anotherCharacter.MapInstance.Broadcast(anotherCharacter.GenerateEffectPacket(EffectType.ArchmageTeleportAfter));
anotherCharacter.TeleportOnMap(savedX, savedY);
counter++;
}
character.BroadcastEffectGround(EffectType.ArchmageTeleportWhiteEffect, character.PositionX, character.PositionY, false);
character.TeleportOnMap(savedX, savedY, true);
_teleportManager.RemovePosition(character.Id);
character.BroadcastEffectGround(EffectType.ArchmageTeleportSet, savedX, savedY, true);
SkillInfo fakeTeleport = character.GetFakeTeleportSkill();
Buff memorialBuff = character.BuffComponent.GetBuff((short)BuffVnums.MEMORIAL);
character.RemoveBuffAsync(false, memorialBuff);
character.SetSkillCooldown(fakeTeleport);
character.RemoveCastingSkill();
character.SkillComponent.SendTeleportPacket = DateTime.UtcNow;
break;
}
}
}