diff --git a/moe.yuyui.weebsights-port/Assorts/MechanicAssort.cs b/moe.yuyui.weebsights-port/Assorts/MechanicAssort.cs new file mode 100644 index 0000000..cf4d7c9 --- /dev/null +++ b/moe.yuyui.weebsights-port/Assorts/MechanicAssort.cs @@ -0,0 +1,67 @@ +using System.Reflection; +using Microsoft.Extensions.Logging; +using moe.yuyui.weebsights_port.Enums; +using moe.yuyui.weebsights_port.Models; +using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.DI; +using SPTarkov.Server.Core.Extensions; +using SPTarkov.Server.Core.Models.Common; +using SPTarkov.Server.Core.Models.Eft.Common.Tables; +using SPTarkov.Server.Core.Models.Enums; +using SPTarkov.Server.Core.Models.Spt.Mod; +using SPTarkov.Server.Core.Models.Utils; +using SPTarkov.Server.Core.Servers; +using SPTarkov.Server.Core.Services; +using SPTarkov.Server.Core.Services.Mod; +using SPTarkov.Server.Core.Utils; + +namespace moe.yuyui.weebsights_port.Assorts; + +[Injectable(TypePriority = OnLoadOrder.PostDBModLoader + 1)] +public class MechanicAssort(ISptLoggerlogger, JsonUtil jsonUtil, DatabaseService databaseService, CustomItemService customItemService) +{ + public bool InjectAssortFromItemClone(IEnumerable itemCloneResults) + { + if (!databaseService.GetTables().Traders.TryGetValue(Traders.MECHANIC, out var mechanic)) + { + logger.Error("[Weeb Iron Sights] Failed to find MECHANIC trader"); + return false; + } + + foreach (var itemResult in itemCloneResults) + { + var item = databaseService.GetItems().FirstOrDefault(i => i.Key == itemResult.ItemId); + var traderItem = GenerateItemForTrader(item); + var traderBarter = new BarterScheme() + { + Count = item.Value.Properties?.CreditsPrice ?? 1, + Template = CurrencyType.RUB.GetCurrencyTpl() + }; + + mechanic.Assort.Items.Add(traderItem); + if (!mechanic.Assort.BarterScheme.TryAdd(item.Key, [[traderBarter]])) + { + logger.Error($"[Weeb Iron Sights] Failed to add barter for item {item.Value.Name} with ID {item.Value.Id} in MECHANIC"); + } + logger.Success($"[Weeb Iron Sights] Added item {item.Value.Name} with ID {item.Value.Id} to MECHANIC"); + } + + return true; + } + + private Item GenerateItemForTrader(KeyValuePair databaseItem) + { + return new Item + { + Id = databaseItem.Key, + Template = databaseItem.Value.Id, + ParentId = "hideout", + SlotId = "hideout", + Upd = new Upd() + { + UnlimitedCount = true, + StackObjectsCount = 99999, + } + }; + } +} \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Enums/ESightsMbus.cs b/moe.yuyui.weebsights-port/Enums/ESightsMbus.cs new file mode 100644 index 0000000..4fea785 --- /dev/null +++ b/moe.yuyui.weebsights-port/Enums/ESightsMbus.cs @@ -0,0 +1,23 @@ +using moe.yuyui.weebsights_port.Interfaces; +using moe.yuyui.weebsights_port.Models; +using SPTarkov.Server.Core.Models.Common; + +namespace moe.yuyui.weebsights_port.Enums; + +public class ESightsMbus : IWeebSightEnum +{ + public static readonly WeebSight Anti = new("6753d006cec7fc449f055445", "sight_rear_all_magpul_mbus_anti", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Anti2 = new("6753d006cec7fc449f05544a", "sight_rear_all_magpul_mbus_gen2_anti2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeAnti = new("6753d006cec7fc449f055450","sight_rear_all_magpul_mbus_gen2_fde_anti", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeAnti2 = new("6753d006cec7fc449f055451", "sight_rear_all_magpul_mbus_gen2_fde_anti2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Fuyuumi = new("6753d006cec7fc449f055446", "sight_rear_all_magpul_mbus_gen2_anime", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeFuyuumi = new("6753d006cec7fc449f05544c","sight_rear_all_magpul_mbus_gen2_fde_anime", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight M4Sopmod = new("6753d006cec7fc449f055447","sight_rear_all_magpul_mbus_gen2_anime2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeM4Sopmod = new("6753d006cec7fc449f05544d","sight_rear_all_magpul_mbus_gen2_fde_anime2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Animu3 = new("6753d006cec7fc449f055448","sight_rear_all_magpul_mbus_gen2_anime3", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeAnimu3 = new("6753d006cec7fc449f05544e","sight_rear_all_magpul_mbus_gen2_fde_anime3", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Animu3V2 = new("6753d006cec7fc449f055449","sight_rear_all_magpul_mbus_gen2_anime3v2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeAnimu3V2 = new("6753d006cec7fc449f05544f","sight_rear_all_magpul_mbus_gen2_fde_anime3v2", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Ramrem = new("6753d006cec7fc449f05544b","sight_rear_all_magpul_mbus_gen2_ramrem", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); + public static readonly WeebSight FdeRamrem = new("6753d006cec7fc449f055452","sight_rear_all_magpul_mbus_gen2_fde_ramrem", ItemTpl.IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT); +} \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Enums/ESightsMcx.cs b/moe.yuyui.weebsights-port/Enums/ESightsMcx.cs new file mode 100644 index 0000000..de9db2a --- /dev/null +++ b/moe.yuyui.weebsights-port/Enums/ESightsMcx.cs @@ -0,0 +1,16 @@ +using moe.yuyui.weebsights_port.Interfaces; +using moe.yuyui.weebsights_port.Models; +using SPTarkov.Server.Core.Models.Common; + +namespace moe.yuyui.weebsights_port.Enums; + +public class ESightsMcx : IWeebSightEnum +{ + public static readonly WeebSight Fuyuumi = new("6753d006cec7fc449f055453", "sight_rear_all_sig_flip_up_anime", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight M4Sopmod = new("6753d006cec7fc449f055454", "sight_rear_all_sig_flip_up_anime2", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Animu3 = new("6753d006cec7fc449f055455", "sight_rear_all_sig_flip_up_anime3", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Animu3V2 = new("6753d006cec7fc449f055456", "sight_rear_all_sig_flip_up_anime3v2", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Anti = new("6753d006cec7fc449f055457", "sight_rear_all_sig_flip_up_anti", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Anti2 = new("6753d006cec7fc449f055458", "sight_rear_all_sig_flip_up_anti2", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); + public static readonly WeebSight Ramrem = new("6753d006cec7fc449f055459", "sight_rear_all_sig_flip_up_ramrem", ItemTpl.IRONSIGHT_MCX_FLIPUP_REAR_SIGHT); +} \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Interfaces/IWeebSightEnum.cs b/moe.yuyui.weebsights-port/Interfaces/IWeebSightEnum.cs new file mode 100644 index 0000000..1fb9fa6 --- /dev/null +++ b/moe.yuyui.weebsights-port/Interfaces/IWeebSightEnum.cs @@ -0,0 +1,7 @@ +using SPTarkov.Server.Core.Models.Common; + +namespace moe.yuyui.weebsights_port.Interfaces; + +public interface IWeebSightEnum +{ +} \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Items/ItemGenerator.cs b/moe.yuyui.weebsights-port/Items/ItemGenerator.cs new file mode 100644 index 0000000..17c2ffe --- /dev/null +++ b/moe.yuyui.weebsights-port/Items/ItemGenerator.cs @@ -0,0 +1,67 @@ +using System.Reflection; +using Microsoft.Extensions.Logging; +using moe.yuyui.weebsights_port.Interfaces; +using moe.yuyui.weebsights_port.Models; +using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.DI; +using SPTarkov.Server.Core.Models.Eft.Common.Tables; +using SPTarkov.Server.Core.Models.Spt.Mod; +using SPTarkov.Server.Core.Models.Utils; +using SPTarkov.Server.Core.Services.Mod; + +namespace moe.yuyui.weebsights_port.Items; + +[Injectable(TypePriority = OnLoadOrder.PostDBModLoader + 2)] +public class ItemGenerator(ISptLogger logger, CustomItemService customItemService) +{ + public IEnumerable GenerateWeebSights() where T : IWeebSightEnum + { + FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static ).Where(f => f.FieldType == typeof(WeebSight)).ToArray(); + foreach (var field in fields) + { + WeebSight? sight = field.GetValue(typeof(WeebSight)) as WeebSight; + if (sight == null) + { + logger.Error($"[Weeb Iron Sights] Failed to convert field {field.Name} of type {field.FieldType} into WeebSight"); + continue; + } + + NewItemFromCloneDetails clonedItem = new() + { + NewId = sight.Id, + ItemTplToClone = sight.CloneFromTpl, + ParentId = "55818ac54bdc2d5b648b456e", // Ironsight + HandbookParentId = "5b5f746686f77447ec5d7708", // CATEGORY + HandbookPriceRoubles = 4000, + OverrideProperties = new TemplateItemProperties() + { + Ergonomics = 3, + CreditsPrice = 4000, + Prefab = new Prefab() + { + Path = $"assets/content/items/mods/sights rear/{sight.Asset}.bundle" + }, + }, + Locales = new Dictionary + { + { + "en", new LocaleDetails() + { + Name = $"{sight.Id} TODO LOCALE LOADER FROM JSON", + ShortName = "WEEBSIGHT", + Description = "DESCRIPTION", + } + } + } + }; + var itemCreation = customItemService.CreateItemFromClone(clonedItem); + if (itemCreation.Success is false or null) + { + logger.Error($"[Weeb Iron Sights] Failed to clone item {sight.CloneFromTpl} into {sight.Id}"); + itemCreation.Errors?.ForEach(e => logger.Critical("[Weeb Iron Sights] " + e)); + continue; + } + yield return itemCreation; + } + } +} \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Mod.cs b/moe.yuyui.weebsights-port/Mod.cs index 7dbda8c..d37c8dc 100644 --- a/moe.yuyui.weebsights-port/Mod.cs +++ b/moe.yuyui.weebsights-port/Mod.cs @@ -1,12 +1,15 @@ -using moe.yuyui.weebsights_port.Locales; +using moe.yuyui.weebsights_port.Assorts; +using moe.yuyui.weebsights_port.Enums; +using moe.yuyui.weebsights_port.Items; +using moe.yuyui.weebsights_port.Locales; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.DI; using SPTarkov.Server.Core.Models.Utils; namespace moe.yuyui.weebsights_port; -[Injectable(TypePriority = OnLoadOrder.PostSptModLoader)] -public class Mod(ISptLogger logger, EnglishLocale englishLocale): IOnLoad +[Injectable(TypePriority = OnLoadOrder.PostSptModLoader + 1)] +public class Mod(ISptLogger logger, EnglishLocale englishLocale, MechanicAssort mechanicAssort, ItemGenerator itemGenerator): IOnLoad { public Task OnLoad() { @@ -14,7 +17,18 @@ public class Mod(ISptLogger logger, EnglishLocale englishLocale): IOnLoad { logger.Error("[Weeb Iron Sights] Failed to load locales, you may see garbled text"); } - logger.Success("[Weeb Iron Sights] Items loaded successfully"); + + var sightsMbus = itemGenerator.GenerateWeebSights(); + var sightsMcx = itemGenerator.GenerateWeebSights(); + if (!mechanicAssort.InjectAssortFromItemClone(sightsMbus)) + { + logger.Critical("[Weeb Iron Sights] Failed to inject MBUS Sights"); + } + + if (!mechanicAssort.InjectAssortFromItemClone(sightsMcx)) + { + logger.Critical("[Weeb Iron Sights] Failed to inject MCX Sights"); + } return Task.CompletedTask; } } \ No newline at end of file diff --git a/moe.yuyui.weebsights-port/Models/WeebSight.cs b/moe.yuyui.weebsights-port/Models/WeebSight.cs new file mode 100644 index 0000000..65d2fbd --- /dev/null +++ b/moe.yuyui.weebsights-port/Models/WeebSight.cs @@ -0,0 +1,5 @@ +using SPTarkov.Server.Core.Models.Common; + +namespace moe.yuyui.weebsights_port.Models; + +public record WeebSight(MongoId Id, string Asset, MongoId? CloneFromTpl);