ascnet/AscNet.GameServer/Handlers/Drops/DropsHandler.cs

257 lines
9.9 KiB
C#

using AscNet.Common.MsgPack;
using AscNet.Common.Util;
using AscNet.Logging;
using AscNet.Table.V2.share.equip;
using System.Reflection;
namespace AscNet.GameServer.Handlers.Drops
{
internal static class DropsHandler
{
#region Items
public const int ProofofHonor = 37;
public const int StrangeMark = 100;
public const int HQShard = 300;
public const int ChallengeMedal = 350;
public const int MarkofFriendship = 400;
public const int NightmareMedal = 401;
public const int ChristmasVoucher = 1000;
public const int StarryHairclip = 1001;
public const int SnowballBomb = 1002;
public const int IceCreamVoucher = 1003;
public const int GoldenRetriever = 1004;
public const int RedPacket = 1005;
public const int ChristmasFroggie = 1006;
public const int PlushSheep = 1007;
public const int SudokuHell = 1008;
public const int LegendsoftheWild = 1009;
public const int PortableSewingKit = 1010;
public const int HometownSnowman = 1011;
public const int DragonRevelation = 1012;
public const int ArtCollection = 1013;
public const int OldGuitar = 1014;
public const int BitingShark = 1015;
public const int MiniLantern = 1020;
public const int MessageCard = 1021;
public const int VenusRose = 1022;
public const int VenusCoupon = 1023;
public const int AntiqueMirror = 1024;
public const int PortableDetector = 1025;
public const int SwordCommand = 1026;
public const int SignalPoint = 1027;
public const int RaceToken = 1028;
public const int EnameledPlumBlossom = 1029;
public const int NewYearToken = 1030;
public const int FateToken = 1031;
public const int CrystalHeartPlush = 1032;
public const int MoonDust = 1033;
public const int CrumpledPaper = 1034;
public const int KleinBottle = 1035;
public const int FiveStarWeaponDrop = 10004;
public const int FourStarWeaponDrop = 10005;
public const int ThreeStarWeaponDrop = 10006;
public const int TwoStarWeaponDrop = 10007;
public const int FiveStarMemoryDrop = 10009;
public const int FourStarMemoryDrop = 10010;
public const int ThreeStarMemoryDrop = 10011;
public const int TwoStarMemoryDrop = 10012;
public const int FiveStarEquipmentDrop = 10013;
public const int FourStarEquipmentDrop = 10014;
public const int ThreeStarEquipmentDrop = 10015;
public const int TwoStarEquipmentDrop = 10016;
public const int OneStarEquipmentDrop = 10017;
public const int TwoToFourStarEquipmentDrop = 10018;
public const int MajorOverclockmaterial = 10034;
public const int OverclockMaterialI = 10035;
public const int FiveStarHQFacility = 10036;
public const int FourStarHQFacility = 10037;
public const int ThreeStarHQFacility = 10038;
public const int ThreeToSixStarEquipmentDrop = 10039;
public const int ThreeToFiveStarEquipmentDrop = 10040;
public const int VoltaireSetDrop = 10041;
public const int GloriaSetDrop = 10042;
public const int RichelieuSetDrop = 10043;
public const int SamanthaSetDrop = 10044;
public const int IkeSetDrop = 10045;
public const int MozartSetDrop = 10046;
public const int Carrielynnsetdrop = 10047;
public const int AifeSetDrop = 10048;
public const int SixStarEquipmentDrop = 10049;
public const int SixStarWeaponDrop = 10050;
public const int SixStarMemoryDrop = 10051;
/*public const int MemoryEnhancer = 10052;
public const int MemoryEnhancer = 10053;
public const int MemoryEnhancer = 10054;
public const int MemoryEnhancer = 10055;
public const int MemoryEnhancer = 10056;*/
public const int BorderCertificate = 10057;
public const int ProcessingUnit = 10058;
public const int FalseWordsCertificate = 10059;
public const int HonorMedal = 10060;
public const int HeterosoilGrownCertificate = 10061;
public const int MemorialPhotoAlbum = 10062;
public const int CafeDecor = 11001;
public const int JapaneseDecor = 11002;
public const int CyberDecor = 11003;
public const int CafeBlueprint = 11004;
public const int JapaneseBlueprint = 11005;
public const int CyberBlueprint = 11006;
public const int Yan = 62301;
public const int Rang = 62302;
public const int Ying = 62303;
public const int Sui = 62304;
public const int Tu = 62305;
public const int Su = 62306;
public const int Nuan = 62307;
public const int Chun = 62308;
public const int YanRangYingSui = 62310;
public const int TuSuNuanChun = 62311;
public const int NewYearBox = 62312;
public const int SilverHammer = 62313;
public const int GoldenHammer = 62314;
public const int AwakenedLion = 62315;
public const int FortuneLion = 62316;
public const int LockCharm = 62317;
public const int FortuneCharacterBag = 62319;
public const int FOSInstructorMedal = 96001;
public const int Prayer = 96108;
#endregion
#region Memory Drops
// 2★ Memory Drop
[DropHandler(TwoStarMemoryDrop)]
public static IEnumerable<DropHandlerRet> TwoStarMemoryDropHandler(Session session, int count)
{
return RandomMemoryDrop(session, count, 2);
}
// 3★ Memory Drop
[DropHandler(ThreeStarMemoryDrop)]
public static IEnumerable<DropHandlerRet> ThreeStarMemoryDropHandler(Session session, int count)
{
return RandomMemoryDrop(session, count, 3);
}
// 4★ Memory Drop
[DropHandler(FourStarMemoryDrop)]
public static IEnumerable<DropHandlerRet> FourStarMemoryDropHandler(Session session, int count)
{
return RandomMemoryDrop(session, count, 4);
}
// 5★ Memory Drop
[DropHandler(FiveStarMemoryDrop)]
public static IEnumerable<DropHandlerRet> FiveStarMemoryDropHandler(Session session, int count)
{
return RandomMemoryDrop(session, count, 5);
}
// 6★ Memory Drop
[DropHandler(SixStarMemoryDrop)]
public static IEnumerable<DropHandlerRet> SixStarMemoryDropHandler(Session session, int count)
{
return RandomMemoryDrop(session, count, 6);
}
public static IEnumerable<DropHandlerRet> RandomMemoryDrop(Session session, int count, int quality)
{
List<DropHandlerRet> rets = new();
EquipTable[] memoryPool = TableReaderV2.Parse<EquipTable>().Where(x => x.Type == 0 && x.Quality == quality).ToArray();
if (GetProgressiveChance((int)session.player.PlayerData.Level, quality))
{
EquipTable equip = memoryPool[Random.Shared.Next(0, memoryPool.Length)];
rets.Add(new()
{
TemplateId = equip.Id,
Count = 1,
Level = 1,
Quality = equip.Quality,
Type = RewardType.Equip
});
NotifyEquipDataList notifyEquipData = new();
notifyEquipData.EquipDataList.Add(session.character.AddEquip((uint)equip.Id));
session.SendPush(notifyEquipData);
}
return rets;
}
#endregion
/// <summary>
/// TODO: Progressive chance of getting the item based on item quality and commandant level
/// </summary>
static bool GetProgressiveChance(int level, int quality)
{
return true;
}
}
public static class DropsHandlerFactory
{
public static readonly Dictionary<int, DropHandlerDelegate> dropHandlers = new();
static readonly Logger log = new(typeof(DropsHandlerFactory), LogLevel.DEBUG, LogLevel.DEBUG);
static DropsHandlerFactory()
{
log.LogLevelColor[LogLevel.INFO] = ConsoleColor.White;
log.Info("Loading drop handlers...");
IEnumerable<Type> classes = from t in Assembly.GetExecutingAssembly().GetTypes()
select t;
foreach (var method in classes.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)))
{
var attr = method.GetCustomAttribute<DropHandler>(false);
if (attr is null)
continue;
foreach (var itemId in attr.ItemIds)
{
if (dropHandlers.ContainsKey(itemId))
continue;
dropHandlers.Add(itemId, (DropHandlerDelegate)Delegate.CreateDelegate(typeof(DropHandlerDelegate), method));
}
#if DEBUG
log.Info($"Loaded {method.Name}");
#endif
}
log.Info("Finished loading drop handlers");
}
public static DropHandlerDelegate? GetDropHandler(int itemId)
{
dropHandlers.TryGetValue(itemId, out DropHandlerDelegate? handler);
return handler;
}
}
public delegate IEnumerable<DropHandlerRet> DropHandlerDelegate(Session session, int count);
[AttributeUsage(AttributeTargets.Method)]
public class DropHandler : Attribute
{
public int[] ItemIds { get; }
public DropHandler(params int[] itemIds)
{
ItemIds = itemIds;
}
}
public struct DropHandlerRet
{
public int TemplateId { get; set; }
public int Count { get; set;}
public int Level { get; set;}
public int Quality { get; set;}
public RewardType Type { get; set;}
}
}