Skip to content

Commit

Permalink
Update the freshness control patch in Waste Not, Want Not to cover al…
Browse files Browse the repository at this point in the history
…l of the code paths used since the big tag change.

Fix a potential crash in Sandbox Tools when spawning prefabs.
  • Loading branch information
peterhaneve committed Dec 10, 2022
1 parent 4c3e2ca commit 487a488
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 36 deletions.
1 change: 0 additions & 1 deletion DebugNotIncluded/DebugNotIncludedPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
Expand Down
19 changes: 7 additions & 12 deletions NoWasteWant/FreshnessControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ namespace PeterHan.NoWasteWant {
[SerializationConfig(MemberSerialization.OptIn)]
public class FreshnessControl : KMonoBehaviour, ISim4000ms, ISingleSliderControl {
public float MinFreshness {
get {
return minFreshness;
}
get => minFreshness;
set {
minFreshness = value;
DropStaleItems();
Expand Down Expand Up @@ -61,15 +59,12 @@ public FreshnessControl() {
public void DropStaleItems() {
if (storage != null && minFreshness > 0.0f) {
var toDrop = ListPool<GameObject, FreshnessControl>.Allocate();
try {
foreach (var item in storage.items)
if (item != null && !IsAcceptable(item))
toDrop.Add(item);
foreach (var item in toDrop)
storage.Drop(item, false);
} finally {
toDrop.Recycle();
}
foreach (var item in storage.items)
if (item != null && !IsAcceptable(item))
toDrop.Add(item);
foreach (var item in toDrop)
storage.Drop(item, false);
toDrop.Recycle();
}
}

Expand Down
2 changes: 1 addition & 1 deletion NoWasteWant/NoWasteWant.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyTitle>Waste Not, Want Not</AssemblyTitle>
<FileVersion>1.3.0.0</FileVersion>
<FileVersion>1.4.0.0</FileVersion>
<RootNamespace>PeterHan.NoWasteWant</RootNamespace>
<Description>Encourages Duplicants to eat older food and adds other tools for managing food storage.</Description>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
Expand Down
67 changes: 49 additions & 18 deletions NoWasteWant/NoWasteWantPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ namespace PeterHan.NoWasteWant {
/// Patches which will be applied via annotations for Waste Not, Want Not.
/// </summary>
public sealed class NoWasteWantPatches : KMod.UserMod2 {
private static TagBits EDIBLE_BITS;
private static readonly Tag[] EDIBLE_BITS = {
GameTags.CookingIngredient, GameTags.Edible
};

/// <summary>
/// The maximum mass of food in kilograms that will rot.
Expand Down Expand Up @@ -63,14 +65,7 @@ internal static IEnumerable<CodeInstruction> FixEfficientSupply(
public static void AddFreshnessControl(GameObject go) {
go.AddOrGet<FreshnessControl>();
}

[PLibMethod(RunAt.AfterDbInit)]
internal static void AfterDbInit() {
// For compatibility with Not Enough Tags
EDIBLE_BITS.SetTag(GameTags.CookingIngredient);
EDIBLE_BITS.SetTag(GameTags.Edible);
}


public override void OnLoad(Harmony harmony) {
base.OnLoad(harmony);
PUtil.InitLibrary();
Expand Down Expand Up @@ -133,16 +128,22 @@ private static IEnumerable<CodeInstruction> TranspileNegateLast(
/// Applied to FetchManager to ban fetching stale items to refrigerators.
/// </summary>
[HarmonyPatch]
public static class FetchManager_IsFetchablePickup_Patch {
public static class FetchManager_IsFetchablePickupExclude_Patch {
// Why can we not use byref types in attributes...
internal static MethodBase TargetMethod() {
internal static IEnumerable<MethodBase> TargetMethods() {
var refTagBits = typeof(TagBits).MakeByRefType();
var newMethod = typeof(FetchManager).GetMethodSafe("IsFetchablePickup_Exclude",
var excMethod = typeof(FetchManager).GetMethodSafe("IsFetchablePickup_Exclude",
true, typeof(KPrefabID), typeof(Storage), typeof(float),
typeof(HashSet<Tag>), typeof(Tag), typeof(Storage));
return newMethod ?? typeof(FetchManager).GetMethodSafe(nameof(FetchManager.
if (excMethod != null)
yield return excMethod;
// TODO Remove when versions prior to U44-535211 no longer need to be supported
// and convert the other one to an attribute patch
var oldMethod = typeof(FetchManager).GetMethodSafe(nameof(FetchManager.
IsFetchablePickup), true, typeof(KPrefabID), typeof(Storage),
typeof(float), refTagBits, refTagBits, refTagBits, typeof(Storage));
if (oldMethod != null)
yield return oldMethod;
}

/// <summary>
Expand All @@ -151,11 +152,41 @@ internal static MethodBase TargetMethod() {
internal static void Postfix(KPrefabID pickup_id, Storage destination,
ref bool __result) {
if (__result && pickup_id != null && destination != null && pickup_id.
HasAnyTags(ref EDIBLE_BITS)) {
var freshness = destination.gameObject.GetComponentSafe<FreshnessControl>();
if (freshness != null)
__result = freshness.IsAcceptable(pickup_id.gameObject);
}
HasAnyTags(EDIBLE_BITS) && destination.TryGetComponent(
out FreshnessControl freshness))
__result = freshness.IsAcceptable(pickup_id.gameObject);
}
}

/// <summary>
/// Applied to FetchManager to ban fetching stale items to refrigerators.
/// </summary>
[HarmonyPatch]
public static class FetchManager_IsFetchablePickup_Patch {
/// <summary>
/// The target method to patch.
/// </summary>
private static readonly MethodBase TARGET = typeof(FetchManager).GetMethodSafe(
nameof(FetchManager.IsFetchablePickup), true, typeof(Pickupable),
typeof(FetchChore), typeof(Storage));

internal static bool Prepare() {
return TARGET != null;
}

internal static MethodBase TargetMethod() {
return TARGET;
}

/// <summary>
/// Applied after IsFetchablePickup runs.
/// </summary>
internal static void Postfix(Pickupable pickup, Storage destination,
ref bool __result) {
if (__result && pickup != null && destination != null && pickup.
KPrefabID.HasAnyTags(EDIBLE_BITS) && destination.TryGetComponent(
out FreshnessControl freshness))
__result = freshness.IsAcceptable(pickup.gameObject);
}
}

Expand Down
2 changes: 1 addition & 1 deletion SandboxTools/SandboxTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyTitle>Sandbox Tools</AssemblyTitle>
<FileVersion>3.6.0.0</FileVersion>
<FileVersion>3.7.0.0</FileVersion>
<RootNamespace>PeterHan.SandboxTools</RootNamespace>
<Description>Improves the Sandbox Mode tools with numerous small tweaks.</Description>
<AssemblyVersion>3.1.0.0</AssemblyVersion>
Expand Down
9 changes: 6 additions & 3 deletions SandboxTools/SandboxToolsPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,12 @@ internal static void Prefix(BuildingDef __instance, IList<Tag> selected_elements
settings.InstantBuild))) {
if (__instance.PrefabID == MassiveHeatSinkConfig.ID) {
// Special case the AETN to iron (it uses niobium otherwise)
selected_elements.Clear();
selected_elements.Add(ElementLoader.FindElementByHash(SimHashes.Iron).
tag);
var iron = ElementLoader.FindElementByHash(SimHashes.Iron).tag;
if (selected_elements.Count == 1 && selected_elements[0] != iron &&
!selected_elements.IsReadOnly) {
selected_elements.Clear();
selected_elements.Add(iron);
}
} else if (selected_elements.Count > 0) {
// Lower temperature to at least the element's melt point - 1 K
var pe = ElementLoader.GetElement(selected_elements[0]);
Expand Down

0 comments on commit 487a488

Please sign in to comment.