Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity Settings #437

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions JotunnLib/Configs/PieceTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ public static string GetInternalName(string pieceTable)
return pieceTable;
}

/// <summary>
/// Get the human readable name for a piece table from its internal name.
/// </summary>
/// <param name="internalName"></param>
/// <returns>
/// The matched human readable name or the unchanged internalName if no match was found.
/// </returns>
public static string GetDisplayName(string internalName)
{
return NamesMap.FirstOrDefault(x => x.Value == internalName).Key ?? internalName;
}

private static readonly Dictionary<string, string> NamesMap = new Dictionary<string, string>
{
{ nameof(Hammer), Hammer },
Expand Down
67 changes: 63 additions & 4 deletions JotunnLib/Entities/CustomPiece.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Reflection;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Settings;
using Jotunn.Utils;
using UnityEngine;

Expand All @@ -26,7 +27,21 @@ public class CustomPiece : CustomEntity
/// <summary>
/// Name of the <see cref="global::PieceTable"/> this custom piece belongs to.
/// </summary>
public string PieceTable { get; set; }
public string PieceTable
{
get => pieceTable;
set
{
var oldPieceTable = pieceTable;
pieceTable = value;

if (Piece && !string.IsNullOrEmpty(pieceTable))
{
PieceManager.Instance.RemoveFromPieceTable(Piece, oldPieceTable);
PieceManager.Instance.AddToPieceTable(Piece, pieceTable);
}
}
}

/// <summary>
/// Name of the category this custom piece belongs to.<br />
Expand All @@ -50,7 +65,13 @@ public string Category
/// Indicator if references from <see cref="Entities.Mock{T}"/>s will be replaced at runtime.
/// </summary>
public bool FixReference { get; set; }


public Setting<bool> SettingsEnabled { get; set; }

public Setting<string> CategorySetting { get; set; }

public Setting<string> PieceTableSetting { get; set; }

/// <summary>
/// Indicator if references from configs should get replaced
/// </summary>
Expand All @@ -64,6 +85,7 @@ private string PieceName
private string fallbackPieceName;

private string category;
private string pieceTable;

/// <summary>
/// Custom piece from a prefab.<br />
Expand All @@ -82,6 +104,7 @@ public CustomPiece(GameObject piecePrefab, string pieceTable, bool fixReference)
Piece = piecePrefab.GetComponent<Piece>();
PieceTable = pieceTable;
FixReference = fixReference;
CreateSettings();
}

/// <summary>
Expand All @@ -101,8 +124,9 @@ public CustomPiece(GameObject piecePrefab, PieceConfig pieceConfig) : base(Assem
Category = pieceConfig.Category;

pieceConfig.Apply(piecePrefab);
CreateSettings();
}

/// <summary>
/// Custom piece from a prefab with a <see cref="PieceConfig"/> attached.<br />
/// The members and references from the <see cref="PieceConfig"/> will be referenced by Jötunn at runtime.
Expand All @@ -120,6 +144,7 @@ public CustomPiece(GameObject piecePrefab, bool fixReference, PieceConfig pieceC
Category = pieceConfig.Category;

pieceConfig.Apply(piecePrefab);
CreateSettings();
}

/// <summary>
Expand Down Expand Up @@ -147,6 +172,7 @@ public CustomPiece(AssetBundle assetBundle, string assetName, string pieceTable,
Piece = PiecePrefab.GetComponent<Piece>();
PieceTable = pieceTable;
FixReference = fixReference;
CreateSettings();
}

/// <summary>
Expand Down Expand Up @@ -174,8 +200,9 @@ public CustomPiece(AssetBundle assetBundle, string assetName, PieceConfig pieceC
Category = pieceConfig.Category;

pieceConfig.Apply(PiecePrefab);
CreateSettings();
}

/// <summary>
/// Custom piece from a prefab loaded from an <see cref="AssetBundle"/> with a <see cref="PieceConfig"/> attached.<br />
/// The members and references from the <see cref="PieceConfig"/> will be referenced by Jötunn at runtime.
Expand All @@ -201,6 +228,7 @@ public CustomPiece(AssetBundle assetBundle, string assetName, bool fixReference,
Category = pieceConfig.Category;

pieceConfig.Apply(PiecePrefab);
CreateSettings();
}

/// <summary>
Expand All @@ -226,6 +254,7 @@ public CustomPiece(string name, bool addZNetView, string pieceTable) : base(Asse
Piece = PiecePrefab.AddComponent<Piece>();
Piece.m_name = name;
PieceTable = pieceTable;
CreateSettings();
}

/// <summary>
Expand All @@ -251,6 +280,7 @@ public CustomPiece(string name, bool addZNetView, PieceConfig pieceConfig) : bas
Category = pieceConfig.Category;

pieceConfig.Apply(PiecePrefab);
CreateSettings();
}

/// <summary>
Expand All @@ -275,6 +305,7 @@ public CustomPiece(string name, string baseName, string pieceTable) : base(Assem

Piece = PiecePrefab.GetComponent<Piece>();
PieceTable = pieceTable;
CreateSettings();
}

/// <summary>
Expand All @@ -300,6 +331,23 @@ public CustomPiece(string name, string baseName, PieceConfig pieceConfig) : base
Category = pieceConfig.Category;

pieceConfig.Apply(PiecePrefab);
CreateSettings();
}

private void CreateSettings()
{
SettingsEnabled = new BepInExSetting<bool>(SourceMod, PiecePrefab.name, "Enabled", false, $"Enable settings for {PiecePrefab.name}", 10);
SettingsEnabled.OnChanged += () =>
{
BindSettings();
ConfigManagerUtils.BuildSettingList();
};

CategorySetting = new BepInExDropdownSetting<string>(SourceMod, PiecePrefab.name, "Category", Category, PieceCategories.GetNames().Keys, $"Tool Category of {PiecePrefab.name}", 9);
CategorySetting.OnChanged += () => Category = CategorySetting.Value;

PieceTableSetting = new BepInExDropdownSetting<string>(SourceMod, PiecePrefab.name, "Tool", PieceTables.GetDisplayName(PieceTable), PieceTables.GetNames().Keys, $"Tool of of {PiecePrefab.name}", 8);
PieceTableSetting.OnChanged += () => PieceTable = PieceTableSetting.Value;
}

/// <summary>
Expand All @@ -316,20 +364,24 @@ public bool IsValid()
Logger.LogError(SourceMod, $"CustomPiece '{this}' has no prefab");
valid = false;
}

if (PiecePrefab && !PiecePrefab.IsValid())
{
valid = false;
}

if (!Piece)
{
Logger.LogError(SourceMod, $"CustomPiece '{this}' has no Piece component");
valid = false;
}

if (Piece && !Piece.m_icon)
{
Logger.LogError(SourceMod, $"CustomPiece '{this}' has no icon");
valid = false;
}

if (string.IsNullOrEmpty(PieceTable))
{
Logger.LogError(SourceMod, $"CustomPiece '{this}' has no PieceTable");
Expand All @@ -339,6 +391,13 @@ public bool IsValid()
return valid;
}

public void BindSettings()
{
SettingsEnabled?.Bind();
CategorySetting?.UpdateBinding(SettingsEnabled?.Value ?? false);
PieceTableSetting?.UpdateBinding(SettingsEnabled?.Value ?? false);
}

/// <summary>
/// Helper method to determine if a prefab with a given name is a custom piece created with Jötunn.
/// </summary>
Expand Down
105 changes: 90 additions & 15 deletions JotunnLib/Managers/PieceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection.Emit;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
Expand Down Expand Up @@ -131,6 +132,9 @@ private static void Hud_LateUpdate()
[HarmonyPatch(typeof(ObjectDB), nameof(ObjectDB.Awake)), HarmonyPostfix, HarmonyPriority(Priority.Last)]
private static void InvokeOnPiecesRegistered(ObjectDB __instance) => Instance.InvokeOnPiecesRegistered(__instance);

[HarmonyPatch(typeof(FejdStartup), nameof(FejdStartup.Awake)), HarmonyPostfix]
public static void BindSettings() => Instance.BindSettings();

[HarmonyPatch(typeof(Player), nameof(Player.OnSpawned)), HarmonyPostfix]
private static void ReloadKnownRecipes(Player __instance) => Instance.ReloadKnownRecipes(__instance);

Expand Down Expand Up @@ -252,6 +256,56 @@ public PieceTable GetPieceTable(string name)
return null;
}

/// <summary>
/// Add a <see cref="Piece"/> to a <see cref="PieceTable"/> by name.
/// </summary>
/// <param name="piece"></param>
/// <param name="table"></param>
/// <returns>true if the piece was added to the table</returns>
public bool AddToPieceTable(Piece piece, string table)
{
if (!piece || string.IsNullOrEmpty(table))
{
return false;
}

var pieceTable = GetPieceTable(table);
if (!pieceTable)
{
return false;
}

if (pieceTable.m_pieces.Contains(piece.gameObject))
{
return false;
}

pieceTable.m_pieces.Add(piece.gameObject);
return true;
}

/// <summary>
/// Remove a <see cref="Piece"/> from a <see cref="PieceTable"/> by name.
/// </summary>
/// <param name="piece"></param>
/// <param name="table"></param>
/// <returns>true if the piece was removed from the table</returns>
public bool RemoveFromPieceTable(Piece piece, string table)
{
if (!piece || string.IsNullOrEmpty(table))
{
return false;
}

var pieceTable = GetPieceTable(table);
if (!pieceTable)
{
return false;
}

return pieceTable.m_pieces.Remove(piece.gameObject);
}

/// <summary>
/// Returns all <see cref="global::PieceTable"/> instances in the game.
/// The list is gathered on every ObjectDB.Awake() from all items in it,
Expand Down Expand Up @@ -466,6 +520,34 @@ public void RemovePiece(CustomPiece piece)
}
}

private void BindSettings()
{
Dictionary<BepInPlugin, bool> saveOnConfigSet = new Dictionary<BepInPlugin, bool>();

foreach (var piece in Pieces.Values)
{
if (!saveOnConfigSet.ContainsKey(piece.SourceMod))
{
PluginInfo plugin = Chainloader.PluginInfos[piece.SourceMod.GUID];
saveOnConfigSet[piece.SourceMod] = plugin.Instance.Config.SaveOnConfigSet;
plugin.Instance.Config.SaveOnConfigSet = false;
}

piece.BindSettings();
}

foreach (var sourceMod in saveOnConfigSet.Keys)
{
PluginInfo plugin = Chainloader.PluginInfos[sourceMod.GUID];
plugin.Instance.Config.SaveOnConfigSet = saveOnConfigSet[sourceMod];

if (plugin.Instance.Config.SaveOnConfigSet)
{
plugin.Instance.Config.Save();
}
}
}

/// <summary>
/// Loop all items in the game and get all PieceTables used (vanilla and custom ones).
/// </summary>
Expand Down Expand Up @@ -571,18 +653,6 @@ private void RegisterPieceInPieceTable(GameObject prefab, string pieceTable, str
throw new Exception($"Prefab {prefab.name} has no Piece component attached");
}

var table = GetPieceTable(pieceTable);
if (table == null)
{
throw new Exception($"Could not find PieceTable {pieceTable}");
}

if (table.m_pieces.Contains(prefab))
{
Logger.LogDebug($"Already added piece {prefab.name}");
return;
}

var name = prefab.name;
var hash = name.GetStableHashCode();

Expand All @@ -596,13 +666,18 @@ private void RegisterPieceInPieceTable(GameObject prefab, string pieceTable, str
PrefabManager.Instance.RegisterToZNetScene(prefab);
}

if (!AddToPieceTable(piece, pieceTable))
{
if (!GetPieceTable(pieceTable))
{
Logger.LogWarning($"Could not find PieceTable {pieceTable}");
}
}

if (!string.IsNullOrEmpty(category))
{
piece.m_category = AddPieceCategory(category);
}

table.m_pieces.Add(prefab);
Logger.LogDebug($"Added piece {prefab.name} | Token: {piece.TokenName()}");
}

private void RegisterCustomData(ObjectDB self)
Expand Down
Loading