Skip to content

Commit

Permalink
shop data
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaPiggy committed Sep 11, 2024
1 parent 100493b commit 5ca759a
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Winch/Core/AssetLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ private static void LoadAssetFolder(string path)
string harvestZoneFolderpath = Path.Combine(path, "HarvestZones");
string vibrationFolderpath = Path.Combine(path, "Vibrations");
string mapMarkerFolderpath = Path.Combine(path, "MapMarkers");
string shopFolderpath = Path.Combine(path, "Shops");
string dockFolderpath = Path.Combine(path, "Docks");
string abilityFolderpath = Path.Combine(path, "Abilities");
string worldEventFolderpath = Path.Combine(path, "WorldEvents");
Expand All @@ -76,6 +77,7 @@ private static void LoadAssetFolder(string path)
if(Directory.Exists(itemFolderPath)) LoadItemFiles(itemFolderPath);
if(Directory.Exists(vibrationFolderpath)) LoadVibrationFiles(vibrationFolderpath);
if(Directory.Exists(mapMarkerFolderpath)) LoadMapMarkerFiles(mapMarkerFolderpath);
if(Directory.Exists(shopFolderpath)) LoadShopFiles(shopFolderpath);
if(Directory.Exists(dockFolderpath)) LoadDockFiles(dockFolderpath);
if(Directory.Exists(poiFolderpath)) LoadPoiFiles(poiFolderpath);
if(Directory.Exists(harvestZoneFolderpath)) LoadHarvestZoneFiles(harvestZoneFolderpath);
Expand Down Expand Up @@ -228,6 +230,22 @@ private static void LoadMapMarkerFiles(string mapMarkerFolderPath)
}
}

private static void LoadShopFiles(string shopFolderPath)
{
string[] shopFolderFiles = Directory.GetFiles(shopFolderPath);
foreach (string file in shopFolderFiles)
{
try
{
ShopUtil.AddShopDataFromMeta(file);
}
catch (Exception ex)
{
WinchCore.Log.Error($"Failed to load shop data from {file}: {ex}");
}
}
}

private static void LoadPoiFilesOfType<T>(string poiFolderPath) where T : CustomPOI
{
string[] poiFiles = Directory.GetFiles(poiFolderPath);
Expand Down
39 changes: 39 additions & 0 deletions Winch/Data/Shop/ModdedShopData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Linq;
using Winch.Util;

namespace Winch.Data.Shop;

public class ModdedShopData : ShopData
{
public string id = string.Empty;

public GridKey gridKey = GridKey.NONE;

internal void Populate()
{
foreach (var itemData in alwaysInStock.Concat(phaseLinkedShopData.SelectMany(pl => pl.itemData)).Concat(dialogueLinkedShopData.SelectMany(pl => pl.itemData)))
{
if (itemData is ModdedShopItemData moddedItemData)
moddedItemData.Populate();
}
}

public static implicit operator ShopRestocker.ShopDataGridConfig(ModdedShopData shopData) => new ShopRestocker.ShopDataGridConfig
{
shopData = shopData,
gridKey = shopData.gridKey,
};

public class ModdedShopItemData : ShopItemData
{
public new string itemData = string.Empty;

public SpatialItemData ItemData => ItemUtil.GetSpatialItemData(itemData);

internal void Populate()
{
base.itemData = ItemData;
}
}
}
20 changes: 20 additions & 0 deletions Winch/Patches/API/ShopLoadPatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using HarmonyLib;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.ResourceManagement.AsyncOperations;
using Winch.Core.API;
using Winch.Util;
using static ShopRestocker;

namespace Winch.Patches.API;

[HarmonyPatch(typeof(ShopRestocker))]
[HarmonyPatch(nameof(ShopRestocker.Awake))]
internal static class ShopLoadPatcher
{
public static void Postfix(ShopRestocker __instance)
{
ShopUtil.AddModdedShopData(__instance);
ShopUtil.PopulateShopData(__instance.shopDataGridConfigs);
}
}
58 changes: 58 additions & 0 deletions Winch/Serialization/DredgeTypeHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
using Winch.Data.Item.Prerequisites;
using Winch.Data.POI.Dock;
using Winch.Data.POI.Dock.Destinations;
using Winch.Data.Shop;
using Winch.Data.WorldEvent.Condition;
using Winch.Serialization.Vibration;
using Winch.Util;
using static ShopData;

namespace Winch.Serialization;

Expand Down Expand Up @@ -735,4 +737,60 @@ public static List<CustomUpgradeDestination> ParseUpgradeDestinations(JArray des
}
return parsed;
}

public static ModdedShopData.ModdedShopItemData ParseShopItemData(JToken shopItemData)
{
var config = new ModdedShopData.ModdedShopItemData();
var meta = shopItemData.Type == JTokenType.String
? new Dictionary<string, object> { { "itemData", shopItemData.ToString() } }
: shopItemData.ToObject<Dictionary<string, object>>() ?? new Dictionary<string, object>();
ShopUtil.PopulateShopItemDataFromMetaWithConverter(config, meta);
return config;
}

internal static List<ShopItemData> ParseShopItemDataList(JArray o)
{
var parsed = new List<ShopItemData>();
foreach (var shopItemData in o)
{
parsed.Add(ParseShopItemData(shopItemData));
}
return parsed;
}

public static PhaseLinkedShopData ParsePhaseLinkedShopData(JToken shopData)
{
var config = new PhaseLinkedShopData();
var meta = shopData.ToObject<Dictionary<string, object>>() ?? new Dictionary<string, object>();
ShopUtil.PopulatePhaseLinkedShopDataFromMetaWithConverter(config, meta);
return config;
}

internal static List<PhaseLinkedShopData> ParsePhaseLinkedShopDataList(JArray o)
{
var parsed = new List<PhaseLinkedShopData>();
foreach (var shopItemData in o)
{
parsed.Add(ParsePhaseLinkedShopData(shopItemData));
}
return parsed;
}

public static DialogueLinkedShopData ParseDialogueLinkedShopData(JToken shopData)
{
var config = new DialogueLinkedShopData();
var meta = shopData.ToObject<Dictionary<string, object>>() ?? new Dictionary<string, object>();
ShopUtil.PopulateDialogueLinkedShopDataFromMetaWithConverter(config, meta);
return config;
}

internal static List<DialogueLinkedShopData> ParseDialogueLinkedShopDataList(JArray o)
{
var parsed = new List<DialogueLinkedShopData>();
foreach (var shopItemData in o)
{
parsed.Add(ParseDialogueLinkedShopData(shopItemData));
}
return parsed;
}
}
21 changes: 21 additions & 0 deletions Winch/Serialization/Shop/DialogueLinkedShopDataConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using static ShopData;
using static ShopData.DialogueLinkedShopData;

namespace Winch.Serialization.Shop;

public class DialogueLinkedShopDataConverter : DredgeTypeConverter<DialogueLinkedShopData>
{
private readonly Dictionary<string, FieldDefinition> _definitions = new()
{
{ "itemData", new(new List<ShopItemData>(), o=>DredgeTypeHelpers.ParseShopItemDataList((JArray)o)) },
{ "dialogueNodes", new( new List<string>(), o=>DredgeTypeHelpers.ParseStringList((JArray)o)) },
{ "requireMode", new( RequireMode.ANY, o => DredgeTypeHelpers.GetEnumValue<RequireMode>(o)) }
};

public DialogueLinkedShopDataConverter()
{
AddDefinitions(_definitions);
}
}
19 changes: 19 additions & 0 deletions Winch/Serialization/Shop/PhaseLinkedShopDataConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using static ShopData;

namespace Winch.Serialization.Shop;

public class PhaseLinkedShopDataConverter : DredgeTypeConverter<PhaseLinkedShopData>
{
private readonly Dictionary<string, FieldDefinition> _definitions = new()
{
{ "itemData", new(new List<ShopItemData>(), o=>DredgeTypeHelpers.ParseShopItemDataList((JArray)o)) },
{ "phase", new(0, o=>int.Parse(o.ToString())) },
};

public PhaseLinkedShopDataConverter()
{
AddDefinitions(_definitions);
}
}
25 changes: 25 additions & 0 deletions Winch/Serialization/Shop/ShopDataConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using Winch.Data.Shop;
using static ShopData;

namespace Winch.Serialization.Shop;

public class ShopDataConverter : DredgeTypeConverter<ModdedShopData>
{
private readonly Dictionary<string, FieldDefinition> _definitions = new()
{
{ "id", new(string.Empty, null) },
{ "alwaysInStock", new(new List<ShopItemData>(), o=>DredgeTypeHelpers.ParseShopItemDataList((JArray)o)) },
{ "phaseLinkedShopData", new(new List<PhaseLinkedShopData>(), o=>DredgeTypeHelpers.ParsePhaseLinkedShopDataList((JArray)o)) },
{ "dialogueLinkedShopData", new(new List<DialogueLinkedShopData>(), o=>DredgeTypeHelpers.ParseDialogueLinkedShopDataList((JArray)o)) },
{ "itemSubtypesFromResearchPool", new(new List<ItemSubtype>(), o=>DredgeTypeHelpers.GetEnumValues<ItemSubtype>((JArray)o)) },
{ "countOfEachItemFromResearchPool", new(0, o=>int.Parse(o.ToString())) },
{ "gridKey", new(GridKey.NONE, o=>DredgeTypeHelpers.GetEnumValue<GridKey>(o)) },
};

public ShopDataConverter()
{
AddDefinitions(_definitions);
}
}
19 changes: 19 additions & 0 deletions Winch/Serialization/Shop/ShopItemDataConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using Winch.Data.Shop;

namespace Winch.Serialization.Shop;

public class ShopItemDataConverter : DredgeTypeConverter<ModdedShopData.ModdedShopItemData>
{
private readonly Dictionary<string, FieldDefinition> _definitions = new()
{
{ "itemData", new(string.Empty, null) },
{ "count", new(1, o=>int.Parse(o.ToString())) },
{ "chance", new(1f, o=>float.Parse(o.ToString())) },
};

public ShopItemDataConverter()
{
AddDefinitions(_definitions);
}
}
136 changes: 136 additions & 0 deletions Winch/Util/ShopUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AeLa.EasyFeedback.APIs;
using Winch.Core;
using Winch.Data.Shop;
using Winch.Serialization.Shop;
using static ShopData;
using static ShopRestocker;
using static Winch.Data.Shop.ModdedShopData;

namespace Winch.Util;

public static class ShopUtil
{
private static ShopDataConverter ShopDataConverter = new ShopDataConverter();
private static ShopItemDataConverter ShopItemDataConverter = new ShopItemDataConverter();
private static PhaseLinkedShopDataConverter PhaseLinkedShopDataConverter = new PhaseLinkedShopDataConverter();
private static DialogueLinkedShopDataConverter DialogueLinkedShopDataConverter = new DialogueLinkedShopDataConverter();

internal static bool PopulateShopDataFromMetaWithConverter(ModdedShopData data, Dictionary<string, object> meta)
{
return UtilHelpers.PopulateObjectFromMeta(data, meta, ShopDataConverter);
}

internal static bool PopulateShopItemDataFromMetaWithConverter(ModdedShopData.ModdedShopItemData data, Dictionary<string, object> meta)
{
return UtilHelpers.PopulateObjectFromMeta(data, meta, ShopItemDataConverter);
}

internal static bool PopulatePhaseLinkedShopDataFromMetaWithConverter(PhaseLinkedShopData data, Dictionary<string, object> meta)
{
return UtilHelpers.PopulateObjectFromMeta(data, meta, PhaseLinkedShopDataConverter);
}

internal static bool PopulateDialogueLinkedShopDataFromMetaWithConverter(DialogueLinkedShopData data, Dictionary<string, object> meta)
{
return UtilHelpers.PopulateObjectFromMeta(data, meta, DialogueLinkedShopDataConverter);
}

internal static List<string> KeepInStockItems = new();
internal static Dictionary<GridKey, ShopDataGridConfig> AllShopDataGridConfigDict = new();
internal static Dictionary<string, ModdedShopData> ModdedShopDataDict = new();
internal static Dictionary<string, ShopData> AllShopDataDict = new();

public static void RegisterKeepInStockItem(string itemID) => KeepInStockItems.Add(itemID);

public static ModdedShopData GetModdedShopData(string id)
{
if (string.IsNullOrWhiteSpace(id))
return null;

if (ModdedShopDataDict.TryGetValue(id, out ModdedShopData shopData))
return shopData;
else
return null;
}

public static ShopData GetShopData(string id)
{
if (string.IsNullOrWhiteSpace(id))
return null;

if (AllShopDataDict.TryGetValue(id, out var shop))
return shop;

if (ModdedShopDataDict.TryGetValue(id, out var moddedShop))
return moddedShop;

return null;
}

internal static void AddModdedShopData(ShopRestocker restocker)
{
restocker.itemIdsToKeep.AddRange(KeepInStockItems);
foreach (var shopData in ModdedShopDataDict.Values)
{
shopData.Populate();
restocker.shopDataGridConfigs.Add(shopData);
}
}

internal static void PopulateShopData(IEnumerable<ShopDataGridConfig> result)
{
foreach (var shopDataGridConfig in result)
{
AllShopDataGridConfigDict.SafeAdd(shopDataGridConfig.gridKey, shopDataGridConfig);
WinchCore.Log.Debug($"Added shop data {shopDataGridConfig.gridKey} to AllShopDataGridConfigDict");
AllShopDataDict.SafeAdd(shopDataGridConfig.shopData.name, shopDataGridConfig.shopData);
WinchCore.Log.Debug($"Added shop data {shopDataGridConfig.shopData.name} to AllShopDataDict");
}
}

internal static void ClearShopData()
{
AllShopDataGridConfigDict.Clear();
AllShopDataDict.Clear();
}

internal static void AddShopDataFromMeta(string metaPath)
{
var meta = UtilHelpers.ParseMeta(metaPath);
if (meta == null)
{
WinchCore.Log.Error($"Meta file {metaPath} is empty");
return;
}
var shopData = UtilHelpers.GetScriptableObjectFromMeta<ModdedShopData>(meta, metaPath);
if (shopData == null)
{
WinchCore.Log.Error($"Couldn't create ModdedShopData");
return;
}
var id = (string)meta["id"];
if (ModdedShopDataDict.ContainsKey(id))
{
WinchCore.Log.Error($"Duplicate shop data {id} at {metaPath} failed to load");
return;
}
if (PopulateShopDataFromMetaWithConverter(shopData, meta))
{
ModdedShopDataDict.Add(id, shopData);
}
else
{
WinchCore.Log.Error($"No shop data converter found");
}
}

public static ShopData[] GetAllShopData()
{
return AllShopDataDict.Values.ToArray();
}
}

0 comments on commit 5ca759a

Please sign in to comment.