261 lines
No EOL
10 KiB
C#
261 lines
No EOL
10 KiB
C#
// WingsEmu
|
|
//
|
|
// Developed by NosWings Team
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using WingsAPI.Packets.Enums;
|
|
using WingsEmu.Game._enum;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game.Entities;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Networking;
|
|
|
|
namespace WingsEmu.Game.Raids;
|
|
|
|
public static class RaidsPacketExtensions
|
|
{
|
|
public static string GenerateRaidName(this IClientSession session, IGameLanguageService gameLanguageService, RaidType raidType)
|
|
{
|
|
string raidKey = $"RAID_NAME_{raidType.ToString().ToUpper()}";
|
|
if (!System.Enum.TryParse(raidKey, out GameDialogKey key))
|
|
{
|
|
return raidKey;
|
|
}
|
|
|
|
return gameLanguageService.GetLanguage(key, session.UserLanguage);
|
|
}
|
|
|
|
public static string GenerateRdList(this IClientSession session)
|
|
{
|
|
var stringBuilder = new StringBuilder("rdlst");
|
|
stringBuilder.Append($" {session.PlayerEntity.Raid.MinimumLevel}");
|
|
stringBuilder.Append($" {session.PlayerEntity.Raid.MaximumLevel}");
|
|
stringBuilder.Append($" {(byte)session.PlayerEntity.Raid.Type}");
|
|
foreach (IClientSession targetSession in session.PlayerEntity.Raid.Members)
|
|
{
|
|
stringBuilder.Append(
|
|
$" {targetSession.PlayerEntity.Level}.{(targetSession.PlayerEntity.Specialist != null && targetSession.PlayerEntity.UseSp ? targetSession.PlayerEntity.Specialist.GameItem.Morph : -1)}" +
|
|
$".{(byte)targetSession.PlayerEntity.Class}.{targetSession.PlayerEntity.RaidDeaths}." +
|
|
$"{targetSession.PlayerEntity.Name}.{(byte)targetSession.PlayerEntity.Gender}.{targetSession.PlayerEntity.Id}.{targetSession.PlayerEntity.HeroLevel}");
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static string GenerateRl(this IClientSession session, byte type, IRaidManager raidManager)
|
|
{
|
|
IReadOnlyCollection<RaidParty> registeredRaids = raidManager.RaidPublishList;
|
|
if (!registeredRaids.Any())
|
|
{
|
|
return $"rl {type}";
|
|
}
|
|
|
|
string header = $"rl {type} ";
|
|
foreach (RaidParty raid in registeredRaids)
|
|
{
|
|
IClientSession leader = raid.Members.First();
|
|
header += $" {(byte)raid.Type}.{raid.MinimumLevel}.{raid.MaximumLevel}.{leader.PlayerEntity.Name}.{leader.PlayerEntity.Level}." +
|
|
$"{(leader.PlayerEntity.Morph == 0 ? -1 : leader.PlayerEntity.Morph)}.{(byte)leader.PlayerEntity.Class}.{(byte)leader.PlayerEntity.Gender}.{raid.Members.Count}.{leader.PlayerEntity.HeroLevel}";
|
|
}
|
|
|
|
return header;
|
|
}
|
|
|
|
public static string GenerateRaidPacket(this IClientSession session, RaidPacketType packetType, bool isLeaving = false)
|
|
{
|
|
var stringBuilder = new StringBuilder("raid");
|
|
switch (packetType)
|
|
{
|
|
case RaidPacketType.LIST_MEMBERS:
|
|
stringBuilder.Append(" 0");
|
|
|
|
if (session.PlayerEntity.Raid?.Members != null)
|
|
{
|
|
foreach (IClientSession targetSession in session.PlayerEntity.Raid.Members.OrderByDescending(s => s.PlayerEntity.Level))
|
|
{
|
|
stringBuilder.Append(" ");
|
|
stringBuilder.Append(targetSession.PlayerEntity.Id);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case RaidPacketType.LEAVE:
|
|
return isLeaving ? "raid 1 0" : "raid 1 1";
|
|
case RaidPacketType.LEADER_RELATED:
|
|
return "raid 2 " + (isLeaving
|
|
? "-1"
|
|
: $"{(session.PlayerEntity.Raid?.Members != null && session.PlayerEntity.Raid.Members.Any() ? session.PlayerEntity.Raid.Members.First().PlayerEntity.Id : 0)}");
|
|
case RaidPacketType.REFRESH_MEMBERS_HP_MP:
|
|
stringBuilder.Append(" 3");
|
|
|
|
if (session.PlayerEntity.Raid?.Members != null)
|
|
{
|
|
foreach (IClientSession targetSession in session.PlayerEntity.Raid.Members.OrderByDescending(s => s.PlayerEntity.Level))
|
|
{
|
|
stringBuilder.Append($" {targetSession.PlayerEntity.Id}.{targetSession.PlayerEntity.GetHpPercentage()}.{targetSession.PlayerEntity.GetMpPercentage()}");
|
|
}
|
|
}
|
|
|
|
break;
|
|
case RaidPacketType.AFTER_INSTANCE_START_BUT_BEFORE_REFRESH_MEMBERS:
|
|
return "raid 4";
|
|
case RaidPacketType.INSTANCE_START:
|
|
return "raid 5 1";
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static string GenerateRaidBossPacket(this IMonsterEntity entity, bool secondBoss)
|
|
=> $"rboss {(secondBoss ? 4 : 3)} {entity.Id} {entity.Hp} {entity.MaxHp} {entity.MonsterVNum}";
|
|
|
|
public static string GenerateEmptyRaidBoss(this IClientSession session) => "rboss -1 -1 0 0";
|
|
|
|
public static void SendEmptyRaidBoss(this IClientSession session)
|
|
{
|
|
session.SendPacket(session.GenerateEmptyRaidBoss());
|
|
}
|
|
|
|
public static string GenerateRaidUiPacket(this IClientSession session, RaidType raidType, RaidWindowType windowType) =>
|
|
$"raidbf 0 {(byte)windowType} {(raidType == RaidType.Laurena ? 40 : 25)}";
|
|
|
|
public static string GenerateThrowPacket(this IBattleEntity entity, MonsterMapItem mapItem)
|
|
=> $"throw {mapItem.ItemVNum} {mapItem.TransportId} {entity.PositionX} {entity.PositionY} {mapItem.PositionX} {mapItem.PositionY} {mapItem.Amount}";
|
|
|
|
public static string GeneraterRaidmbf(this IClientSession session)
|
|
{
|
|
RaidSubInstance raidSubInstance = session.PlayerEntity.Raid.Instance.RaidSubInstances[session.PlayerEntity.MapInstanceId];
|
|
|
|
return "raidmbf " +
|
|
$"{raidSubInstance.CurrentTargetMonsters.ToString()} " + // initialMonstersToKill
|
|
$"{(raidSubInstance.CurrentTargetMonsters - raidSubInstance.CurrentCompletedTargetMonsters).ToString()} " + // currentMonsterToKill
|
|
$"{raidSubInstance.CurrentTargetButtons.ToString()} " + // initialButtonsToUse
|
|
$"{(raidSubInstance.CurrentTargetButtons - raidSubInstance.CurrentCompletedTargetButtons).ToString()} " + // currentButtonsToUse
|
|
$"{session.PlayerEntity.Raid.Instance.Lives.ToString()} " +
|
|
$"{session.PlayerEntity.Raid.Instance.MaxLives.ToString()} " +
|
|
$"{(session.PlayerEntity.Raid.Type == RaidType.Laurena ? 40 : 25).ToString()}";
|
|
}
|
|
|
|
public static void SendRaidPacket(this IClientSession session, RaidPacketType type, bool isLeaving = false)
|
|
{
|
|
session.SendPacket(session.GenerateRaidPacket(type, isLeaving));
|
|
}
|
|
|
|
public static void RefreshRaidMemberList(this IClientSession session)
|
|
{
|
|
if (!session.PlayerEntity.IsInRaidParty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
session.SendPacket(session.GenerateRdList());
|
|
}
|
|
|
|
public static void SendRlPacket(this IClientSession session, byte type, IRaidManager raidManager) => session.SendPacket(session.GenerateRl(type, raidManager));
|
|
|
|
public static void TrySendRaidBossPackets(this IClientSession session)
|
|
{
|
|
if (!session.PlayerEntity.IsInRaidParty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.CurrentMapInstance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.Raid?.Instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.Raid.Instance.RaidSubInstances.TryGetValue(session.CurrentMapInstance.Id, out RaidSubInstance subInstance))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool secondBoss = false;
|
|
foreach (IMonsterEntity boss in subInstance.BossMonsters)
|
|
{
|
|
session.SendPacket(boss.GenerateRaidBossPacket(secondBoss));
|
|
secondBoss = true;
|
|
}
|
|
}
|
|
|
|
public static void TrySendRaidBossDeadPackets(this IClientSession session)
|
|
{
|
|
if (!session.PlayerEntity.Raid.Instance.RaidSubInstances.ContainsKey(session.CurrentMapInstance.Id))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RaidSubInstance subInstance = session.PlayerEntity.Raid.Instance.RaidSubInstances[session.CurrentMapInstance.Id];
|
|
|
|
bool secondBoss = false;
|
|
foreach (IMonsterEntity boss in subInstance.DeadBossMonsters)
|
|
{
|
|
session.SendPacket(boss.GenerateRaidBossPacket(secondBoss));
|
|
secondBoss = true;
|
|
}
|
|
}
|
|
|
|
public static void SendRaidUiPacket(this IClientSession session, RaidType raidType, RaidWindowType raidWindowType) =>
|
|
session.SendPacket(session.GenerateRaidUiPacket(raidType, raidWindowType));
|
|
|
|
public static void SendRaidmbf(this IClientSession session)
|
|
{
|
|
if (session.PlayerEntity.Raid?.Instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.Raid.Instance.RaidSubInstances.ContainsKey(session.PlayerEntity.MapInstanceId))
|
|
{
|
|
return;
|
|
}
|
|
|
|
session.SendPacket(session.GeneraterRaidmbf());
|
|
}
|
|
|
|
public static void BroadcastThrow(this IBattleEntity entity, MonsterMapItem mapItem) => entity.MapInstance.Broadcast(entity.GenerateThrowPacket(mapItem));
|
|
|
|
public static bool IsRaidTypeRestricted(this IClientSession session, RaidType raidType)
|
|
{
|
|
switch (raidType)
|
|
{
|
|
case RaidType.Glacerus:
|
|
case RaidType.LordDraco:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool CanPlayerJoinToRestrictedRaid(this IClientSession session, RaidType raidType)
|
|
{
|
|
return raidType switch
|
|
{
|
|
RaidType.LordDraco => session.PlayerEntity.RaidRestrictionDto.LordDraco > 0,
|
|
RaidType.Glacerus => session.PlayerEntity.RaidRestrictionDto.Glacerus > 0,
|
|
_ => true
|
|
};
|
|
}
|
|
|
|
public static bool IsPlayerWearingRaidAmulet(this IClientSession session, RaidType raidType)
|
|
{
|
|
if (session.PlayerEntity.Amulet == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return raidType switch
|
|
{
|
|
RaidType.LordDraco => session.PlayerEntity.Amulet.ItemVNum == (short)ItemVnums.DRACO_AMULET,
|
|
RaidType.Glacerus => session.PlayerEntity.Amulet.ItemVNum == (short)ItemVnums.GLACERUS_AMULET,
|
|
_ => true
|
|
};
|
|
}
|
|
} |