Skip to content

Commit

Permalink
Merge pull request #409 from MSchmoecker/feat/api-improvements
Browse files Browse the repository at this point in the history
feat: API improvements
  • Loading branch information
MSchmoecker committed Sep 22, 2023
2 parents 8126f27 + 95b4e17 commit eb6d5d4
Show file tree
Hide file tree
Showing 14 changed files with 365 additions and 129 deletions.
12 changes: 12 additions & 0 deletions JotunnLib/Configs/ItemConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ public string RepairStation
/// </summary>
public int MinStationLevel { get; set; } = 1;

/// <summary>
/// Whether this recipe requires only one of the crafting requirements to be crafted. Defaults to <c>false</c>.
/// </summary>
public bool RequireOnlyOneIngredient { get; set; } = false;

/// <summary>
/// Multiplier for the amount of items created by the recipe based on the quality of the crafting materials. Defaults to <c>1</c>.
/// </summary>
public int QualityResultAmountMultiplier { get; set; } = 1;

/// <summary>
/// Icons for this item. If more than one icon is added, this item automatically has variants.
/// </summary>
Expand Down Expand Up @@ -222,6 +232,8 @@ public Recipe GetRecipe()

recipe.m_minStationLevel = MinStationLevel;
recipe.m_resources = GetRequirements();
recipe.m_requireOnlyOneIngredient = RequireOnlyOneIngredient;
recipe.m_qualityResultAmountMultiplier = QualityResultAmountMultiplier;

return recipe;
}
Expand Down
12 changes: 12 additions & 0 deletions JotunnLib/Configs/RecipeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ public string RepairStation
/// </summary>
public int MinStationLevel { get; set; } = 1;

/// <summary>
/// Whether this recipe requires only one of the crafting requirements to be crafted. Defaults to <c>false</c>.
/// </summary>
public bool RequireOnlyOneIngredient { get; set; } = false;

/// <summary>
/// Multiplier for the amount of items created by the recipe based on the quality of the crafting materials. Defaults to <c>1</c>.
/// </summary>
public int QualityResultAmountMultiplier { get; set; } = 1;

/// <summary>
/// Array of <see cref="RequirementConfig"/>s for all crafting materials it takes to craft the recipe.
/// </summary>
Expand Down Expand Up @@ -123,6 +133,8 @@ public Recipe GetRecipe()

recipe.m_minStationLevel = MinStationLevel;
recipe.m_resources = GetRequirements();
recipe.m_requireOnlyOneIngredient = RequireOnlyOneIngredient;
recipe.m_qualityResultAmountMultiplier = QualityResultAmountMultiplier;

return recipe;
}
Expand Down
2 changes: 1 addition & 1 deletion JotunnLib/Configs/RequirementConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public Piece.Requirement GetRequirement()
/// Checks if the requirement has any item and amount set.
/// </summary>
/// <returns></returns>
internal bool IsValid()
public bool IsValid()
{
return !string.IsNullOrEmpty(Item) && (Amount > 0 || AmountPerLevel > 0);
}
Expand Down
35 changes: 28 additions & 7 deletions JotunnLib/Entities/CustomClutter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Reflection;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

namespace Jotunn.Entities
Expand Down Expand Up @@ -58,15 +60,34 @@ public CustomClutter(GameObject prefab, bool fixReference, ClutterConfig config)
/// <param name="config">The <see cref="ClutterConfig"/> for this custom clutter.</param>
public CustomClutter(AssetBundle assetBundle, string assetName, bool fixReference, ClutterConfig config) : base(Assembly.GetCallingAssembly())
{
var prefab = assetBundle.LoadAsset<GameObject>(assetName);
if (prefab)
Name = assetName;

if (!AssetUtils.TryLoadPrefab(SourceMod, assetBundle, assetName, out GameObject prefab))
{
return;
}

Prefab = prefab;
Clutter = config.ToClutter();
Clutter.m_prefab = Prefab;
FixReference = fixReference;
}

/// <summary>
/// Checks if a custom clutter is valid (i.e. has a prefab).
/// </summary>
/// <returns>true if all criteria is met</returns>
public bool IsValid()
{
bool valid = true;

if (!Prefab)
{
Prefab = prefab;
Name = prefab.name;
Clutter = config.ToClutter();
Clutter.m_prefab = prefab;
FixReference = fixReference;
Logger.LogError(SourceMod, $"Custom Clutter '{this}' has no prefab");
valid = false;
}

return valid;
}

/// <inheritdoc/>
Expand Down
57 changes: 44 additions & 13 deletions JotunnLib/Entities/CustomCreature.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

namespace Jotunn.Entities
Expand Down Expand Up @@ -38,6 +40,13 @@ public class CustomCreature : CustomEntity
/// </summary>
internal bool UseCumulativeLevelEffects { get; set; }

private string CreatureName
{
get => Prefab ? Prefab.name : fallbackCreatureName;
}

private string fallbackCreatureName;

/// <summary>
/// Custom creature from a prefab.
/// </summary>
Expand Down Expand Up @@ -81,6 +90,28 @@ public CustomCreature(string name, string basePrefabName, CreatureConfig creatur
}
}

/// <summary>
/// Custom creature 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.
/// </summary>
/// <param name="assetBundle">A preloaded <see cref="AssetBundle"/></param>
/// <param name="assetName">Name of the prefab in the bundle.</param>
/// <param name="fixReference">If true references for <see cref="Entities.Mock{T}"/> objects get resolved at runtime by Jötunn.</param>
/// <param name="creatureConfig">The <see cref="CreatureConfig"/> for this custom creature.</param>
public CustomCreature(AssetBundle assetBundle, string assetName, bool fixReference, CreatureConfig creatureConfig) : base(Assembly.GetCallingAssembly())
{
fallbackCreatureName = assetName;

if (!AssetUtils.TryLoadPrefab(SourceMod, assetBundle, assetName, out GameObject prefab))
{
return;
}

Prefab = prefab;
ApplyCreatureConfig(creatureConfig);
FixReference = fixReference;
}

/// <summary>
/// Checks if a custom creature is valid (i.e. has a prefab and all required components).
/// </summary>
Expand All @@ -91,37 +122,37 @@ public bool IsValid()

if (!Prefab)
{
Logger.LogError($"CustomCreature {this} has no prefab");
Logger.LogError(SourceMod, $"CustomCreature '{this}' has no prefab");
valid = false;
}

var required = new[]
var requiredComponents = new[]
{
typeof(Character),
typeof(BaseAI),
typeof(CapsuleCollider),
typeof(Rigidbody),
typeof(ZSyncAnimation)
};
foreach (var type in required)

foreach (var type in requiredComponents)
{
if (!Prefab.GetComponent(type))
if (Prefab && !Prefab.GetComponent(type))
{
Logger.LogError($"CustomCreature {this} has no {type} component");
Logger.LogError(SourceMod, $"CustomCreature '{this}' has no {type} component");
valid = false;
break;
}
}

if (!Prefab.GetComponentInChildren<Animator>())
if (Prefab && !Prefab.GetComponentInChildren<Animator>())
{
Logger.LogError($"CustomCreature {this} has no Animator component");
Logger.LogError(SourceMod, $"CustomCreature '{this}' has no Animator component");
valid = false;
}

if (!Prefab.GetComponentInChildren<CharacterAnimEvent>())
if (Prefab && !Prefab.GetComponentInChildren<CharacterAnimEvent>())
{
Logger.LogError($"CustomCreature {this} has no CharacterAnimEvent component");
Logger.LogError(SourceMod, $"CustomCreature '{this}' has no CharacterAnimEvent component");
valid = false;
}

Expand All @@ -147,13 +178,13 @@ public override bool Equals(object obj)
/// <inheritdoc/>
public override int GetHashCode()
{
return Prefab.name.GetStableHashCode();
return CreatureName.GetStableHashCode();
}

/// <inheritdoc/>
public override string ToString()
{
return Prefab.name;
return CreatureName;
}

private void ApplyCreatureConfig(CreatureConfig creatureConfig)
Expand Down
42 changes: 29 additions & 13 deletions JotunnLib/Entities/CustomItem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

namespace Jotunn.Entities
Expand Down Expand Up @@ -37,6 +38,13 @@ public class CustomItem : CustomEntity
/// </summary>
internal bool FixConfig { get; set; }

private string ItemName
{
get => ItemPrefab ? ItemPrefab.name : fallbackItemName;
}

private string fallbackItemName;

/// <summary>
/// Custom item from a prefab.<br />
/// Can fix references for <see cref="Entities.Mock{T}"/>s and the <see cref="global::Recipe"/>.
Expand Down Expand Up @@ -136,13 +144,17 @@ public CustomItem(string name, string basePrefabName, ItemConfig itemConfig) : b
/// <param name="itemConfig">The item config for this custom item.</param>
public CustomItem(AssetBundle assetBundle, string assetName, bool fixReference, ItemConfig itemConfig) : base(Assembly.GetCallingAssembly())
{
ItemPrefab = assetBundle.LoadAsset<GameObject>(assetName);
if (ItemPrefab)
fallbackItemName = assetName;

if (!AssetUtils.TryLoadPrefab(SourceMod, assetBundle, assetName, out GameObject prefab))
{
ItemDrop = ItemPrefab.GetComponent<ItemDrop>();
FixReference = fixReference;
ApplyItemConfig(itemConfig);
return;
}

ItemPrefab = prefab;
ItemDrop = ItemPrefab.GetComponent<ItemDrop>();
FixReference = fixReference;
ApplyItemConfig(itemConfig);
}

/// <summary>
Expand All @@ -155,21 +167,25 @@ public bool IsValid()

if (!ItemPrefab)
{
Logger.LogError($"CustomItem {this} has no prefab");
Logger.LogError(SourceMod, $"CustomItem '{this}' has no prefab");
valid = false;
}
if (!ItemPrefab.IsValid())

if (ItemPrefab && !ItemPrefab.IsValid())
{
valid = false;
}
if (ItemDrop == null)

if (!ItemDrop)
{
Logger.LogError($"CustomItem {this} has no ItemDrop component");
Logger.LogError(SourceMod, $"CustomItem '{this}' has no ItemDrop component");
valid = false;
}
if (Recipe != null && ItemDrop?.m_itemData.m_shared.m_icons.Length == 0)

int? iconCount = ItemDrop ? ItemDrop.m_itemData?.m_shared?.m_icons?.Length : null;
if (Recipe != null && (iconCount == null || iconCount == 0))
{
Logger.LogError($"CustomItem {this} has no icon");
Logger.LogError(SourceMod, $"CustomItem '{this}' has no icon");
valid = false;
}

Expand Down Expand Up @@ -203,13 +219,13 @@ public override bool Equals(object obj)
/// <inheritdoc/>
public override int GetHashCode()
{
return ItemPrefab.name.GetStableHashCode();
return ItemName.GetStableHashCode();
}

/// <inheritdoc/>
public override string ToString()
{
return ItemPrefab.name;
return ItemName;
}

private void ApplyItemConfig(ItemConfig itemConfig)
Expand Down
Loading

0 comments on commit eb6d5d4

Please sign in to comment.