using System; using System.Linq; using PhoenixLib.Scheduler; using WingsEmu.Game; using WingsEmu.Game.Characters; using WingsEmu.Game.Entities; using WingsEmu.Game.Extensions; using WingsEmu.Game.Extensions.Mates; using WingsEmu.Game.Maps; using WingsEmu.Packets.Enums; namespace WingsAPI.Game.Extensions.PacketGeneration { public static class MapExtensions { public static string GenerateDrop(this MapItem mapItem) => $"drop {mapItem.ItemVNum} {mapItem.TransportId} {mapItem.PositionX} {mapItem.PositionY} {mapItem.Amount} {(mapItem.IsQuest ? 1 : 0)} {(mapItem is MonsterMapItem monsterMapItem ? monsterMapItem.OwnerId ?? -1 : -1)}"; public static string GenerateMapDesignObjects(this IMapInstance map) => map.MapDesignObjects.Aggregate("mltobj", (current, mp) => current + $" {mp.InventoryItem.ItemInstance.ItemVNum.ToString()}.{mp.InventoryItem.Slot.ToString()}.{mp.MapX.ToString()}.{mp.MapY.ToString()}"); public static void BroadcastDrop(this MapItem mapItem) => mapItem.MapInstance.Broadcast(mapItem.GenerateDrop()); public static void AddPortalToMap(this IMapInstance mapInstance, IPortalEntity portal, IScheduler scheduler = null, int timeInSeconds = 0, bool isTemporary = false) { mapInstance.Portals.Add(portal); mapInstance.Broadcast(portal.GenerateGp()); if (isTemporary) { scheduler?.Schedule(TimeSpan.FromSeconds(timeInSeconds), o => { mapInstance.DeletePortal(portal); }); } } public static void DeletePortal(this IMapInstance mapInstance, IPortalEntity portal) { mapInstance.Portals.Remove(portal); mapInstance.MapClear(); } public static IPortalEntity GetClosestPortal(this IMapInstance mapInstance, short posX, short posY, PortalType portalType = PortalType.TSNormal) { return mapInstance.Portals.Where(x => x.Type == portalType).OrderBy(x => Math.Abs(x.PositionX - posX)).ThenBy(x => Math.Abs(x.PositionY - posY)).FirstOrDefault(); } public static void MapClear(this IMapInstance mapInstance, bool onlyItemsAndPortals = false) { mapInstance.Broadcast(mapInstance.GenerateMapClear()); mapInstance.Broadcast(mapInstance.GetEntitiesOnMapPackets(onlyItemsAndPortals)); } public static void BroadcastTimeSpacePartnerInfo(this IMapInstance mapInstance) { if (mapInstance.MapInstanceType != MapInstanceType.TimeSpaceInstance) { return; } foreach (INpcEntity npc in mapInstance.GetAliveNpcs(x => x.CharacterPartnerId.HasValue)) { if (!npc.CharacterPartnerId.HasValue) { continue; } IPlayerEntity player = mapInstance.GetCharacterById(npc.CharacterPartnerId.Value); if (player == null) { continue; } player.Session.SendMateControl(npc); player.Session.SendCondMate(npc); } } } }