diff --git a/.gitignore b/.gitignore
index 9491a2f..00972f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -360,4 +360,8 @@ MigrationBackup/
.ionide/
# Fody - auto-generated XML schema
-FodyWeavers.xsd
\ No newline at end of file
+FodyWeavers.xsd
+
+# git merge
+*.orig
+*.bak
diff --git a/ColorCycler/About/About.xml b/ColorCycler/About/About.xml
new file mode 100644
index 0000000..081310a
--- /dev/null
+++ b/ColorCycler/About/About.xml
@@ -0,0 +1,10 @@
+
+
+ Color Cycler
+ Elmotrix
+ 1.200000.00
+ Cycles colors on spray cans with mouse wheel
+
+ paint
+
+
\ No newline at end of file
diff --git a/ColorCycler/About/Preview.png b/ColorCycler/About/Preview.png
new file mode 100644
index 0000000..a74ec24
Binary files /dev/null and b/ColorCycler/About/Preview.png differ
diff --git a/ColorCycler/About/bepinex b/ColorCycler/About/bepinex
new file mode 100644
index 0000000..e69de29
diff --git a/ColorCycler/About/thumb.png b/ColorCycler/About/thumb.png
new file mode 100644
index 0000000..6d11a2b
Binary files /dev/null and b/ColorCycler/About/thumb.png differ
diff --git a/ColorCycler/BepInEx.cs b/ColorCycler/BepInEx.cs
index b10bea3..e267fca 100644
--- a/ColorCycler/BepInEx.cs
+++ b/ColorCycler/BepInEx.cs
@@ -1,6 +1,6 @@
-using HarmonyLib;
+using BepInEx.Logging;
+using HarmonyLib;
using System;
-using UnityEngine;
namespace ColorCycler
{
@@ -10,24 +10,39 @@ public class ColorCyclerBep : BepInEx.BaseUnityPlugin
{
public const string pluginGuid = "net.elmo.stationeers.ColorCycler";
public const string pluginName = "ColorCycler";
- public const string pluginVersion = "1.1.0";
- public static void Log(string line)
+ public const string pluginVersion = "1.2.0";
+
+ private Harmony _harmony;
+
+ internal static new ManualLogSource Logger;
+ internal static ColorCyclerConfig Settings;
+
+ public ColorCyclerBep()
{
- Debug.Log("[" + pluginName + "]: " + line);
+ Settings ??= new ColorCyclerConfig(Config);
}
+
void Awake()
{
+ Logger = base.Logger;
try
{
- var harmony = new Harmony(pluginGuid);
- harmony.PatchAll();
- Log("Patch succeeded");
+ _harmony = new Harmony(pluginGuid);
+ _harmony.PatchAll();
+ Logger.LogInfo("Patch succeeded");
}
catch (Exception e)
{
- Log("Patch Failed");
- Log(e.ToString());
+ Logger.LogFatal("Patch Failed");
+ Logger.LogFatal(e);
}
+ Logger.LogMessage($"{nameof(Settings.ShouldCreatePollution)}: {Settings.ShouldCreatePollution}");
+ Logger.LogMessage($"{nameof(Settings.InfinitePaint)}: {Settings.InfinitePaint}");
+ }
+
+ private void OnDestroy()
+ {
+ _harmony.UnpatchSelf();
}
}
#endregion
diff --git a/ColorCycler/ColorCycler.csproj b/ColorCycler/ColorCycler.csproj
index e9f824a..feeff91 100644
--- a/ColorCycler/ColorCycler.csproj
+++ b/ColorCycler/ColorCycler.csproj
@@ -12,49 +12,51 @@
v4.7.2
512
true
+ latest
true
full
false
- bin\Debug\
+ bin\Debug\ColorCycler
DEBUG;TRACE
prompt
4
- pdbonly
+ embedded
true
- bin\Release\
+ bin\Release\ColorCycler
TRACE
prompt
4
+ true
-
+
D:\SteamLibrary\steamapps\common\Stationeers\BepInEx\core\0Harmony.dll
-
+
D:\SteamLibrary\steamapps\common\Stationeers\rocketstation_Data\Managed\Assembly-CSharp.dll
-
+
D:\SteamLibrary\steamapps\common\Stationeers\BepInEx\core\BepInEx.dll
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
D:\SteamLibrary\steamapps\common\Stationeers\rocketstation_Data\Managed\UnityEngine.dll
-
+
D:\SteamLibrary\steamapps\common\Stationeers\rocketstation_Data\Managed\UnityEngine.CoreModule.dll
-
+
False
D:\SteamLibrary\steamapps\common\Stationeers\rocketstation_Data\Managed\UnityEngine.PhysicsModule.dll
@@ -63,7 +65,24 @@
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+ PreserveNewest
+
+
\ No newline at end of file
diff --git a/ColorCycler/ColorCyclerConfig.cs b/ColorCycler/ColorCyclerConfig.cs
new file mode 100644
index 0000000..5aa7f4d
--- /dev/null
+++ b/ColorCycler/ColorCyclerConfig.cs
@@ -0,0 +1,39 @@
+using BepInEx.Configuration;
+using System;
+
+namespace ColorCycler
+{
+ internal class ColorCyclerConfig
+ {
+ private ConfigEntry _shouldCreatePollutionEntry;
+ private ConfigEntry _infinitePaint;
+
+ public bool ShouldCreatePollution => _shouldCreatePollutionEntry.Value;
+ public bool InfinitePaint => _infinitePaint.Value;
+
+ public ColorCyclerConfig(ConfigFile config)
+ {
+ _shouldCreatePollutionEntry = config.Bind(
+ "ColorCycler",
+ nameof(ShouldCreatePollution),
+ false,
+ "Should spray cans create pollution?"
+ );
+ _infinitePaint = config.Bind(
+ "ColorCycler",
+ nameof(InfinitePaint),
+ true,
+ "Should spray cans have infinite uses?"
+ );
+
+ config.ConfigReloaded += OnConfigReloaded;
+ }
+
+ private void OnConfigReloaded(object sender, EventArgs e)
+ {
+ ColorCyclerBep.Logger.LogWarning("Config Reloaded");
+ ColorCyclerBep.Logger.LogWarning($"{nameof(ShouldCreatePollution)}: {ShouldCreatePollution}");
+ ColorCyclerBep.Logger.LogWarning($"{nameof(InfinitePaint)}: {InfinitePaint}");
+ }
+ }
+}
diff --git a/ColorCycler/ColorCyclerMod.cs b/ColorCycler/ColorCyclerMod.cs
index 68b201f..250e11d 100644
--- a/ColorCycler/ColorCyclerMod.cs
+++ b/ColorCycler/ColorCyclerMod.cs
@@ -44,6 +44,7 @@ public static void Prefix(InventoryManager __instance)
if (NetworkManager.IsClient)
{
+ ColorCyclerBep.Logger.LogDebug($"Sending {nameof(ThingColorMessage)} to Server. ColorIndex = {current}, ThingId = {sprayCan.ReferenceId}");
NetworkClient.SendToServer(new ThingColorMessage
{
ThingId = sprayCan.ReferenceId,
@@ -59,12 +60,45 @@ public static void Prefix(InventoryManager __instance)
public class SprayCanOnUseItemPatch
{
[UsedImplicitly]
- public static bool Prefix(ref bool __result)
+ public static bool Prefix(SprayCan __instance, ref bool __result, ref float quantity)
{
- // Modify __result and return false, so that pollution does not occur.
__result = true;
+
+ // Make Paint infinite.
+ if (ColorCyclerBep.Settings.InfinitePaint)
+ {
+ ColorCyclerBep.Logger.LogDebug($"Setting Quantity to 0 from {quantity}");
+ quantity = 0.0f;
+ }
+ ColorCyclerBep.Logger.LogDebug($"Using Quantity {quantity}");
+
+ // Return true, so that original code is executed, if pollution should occur.
+ if (ColorCyclerBep.Settings.ShouldCreatePollution)
+ {
+ return true;
+ }
+
+ // No pollution, skip original, but apply Quantity in case of non-infinite paint
+ __instance.Quantity -= quantity;
+ return false;
+ }
+ }
+
+ // We have to patch Consumable because SprayCan does not implement the method
+ [HarmonyPatch(typeof(Consumable), nameof(Consumable.GetQuantityText))]
+ public class ConsumableGetQuantityTextPatch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(Consumable __instance, ref string __result)
+ {
+ if (__instance is not SprayCan sprayCan || !ColorCyclerBep.Settings.InfinitePaint)
+ {
+ return true;
+ }
+ __result = "Infinite";
return false;
}
+
}
// We have to patch Consumable because SprayCan does not implement the method
@@ -76,7 +110,7 @@ public static void Postfix(Consumable __instance, RocketBinaryWriter writer, ush
{
if (__instance is SprayCan sprayCan)
{
- if (Thing.IsNetworkUpdateRequired(4096U, networkUpdateType))
+ if (Thing.IsNetworkUpdateRequired(ColorCyclerModHelpers.PaintableMaterialNetworkFlag, networkUpdateType))
{
writer.WriteInt32(ColorCyclerModHelpers.GetPaintColorIndex(sprayCan.PaintMaterial));
}
@@ -93,7 +127,7 @@ public static void Postfix(Consumable __instance, RocketBinaryReader reader, ush
{
if (__instance is SprayCan sprayCan)
{
- if (Thing.IsNetworkUpdateRequired(4096U, networkUpdateType))
+ if (Thing.IsNetworkUpdateRequired(ColorCyclerModHelpers.PaintableMaterialNetworkFlag, networkUpdateType))
{
int index = reader.ReadInt32();
var paintMaterial = ColorCyclerModHelpers.GetPaintColor(index);
@@ -109,6 +143,7 @@ public class ThingColorMessageProcessPatch
[UsedImplicitly]
public static void Postfix(ThingColorMessage __instance, long hostId)
{
+ ColorCyclerBep.Logger.LogDebug($"Received {nameof(ThingColorMessage)}. ColorIndex = {__instance.ColorIndex}, ThingId = {__instance.ThingId}");
if (Thing.Find(__instance.ThingId) is SprayCan sprayCan)
{
var paintMaterial = ColorCyclerModHelpers.GetPaintColor(__instance.ColorIndex);
diff --git a/ColorCycler/ColorCyclerModHelpers.cs b/ColorCycler/ColorCyclerModHelpers.cs
index febd2e9..03afb38 100644
--- a/ColorCycler/ColorCyclerModHelpers.cs
+++ b/ColorCycler/ColorCyclerModHelpers.cs
@@ -4,55 +4,75 @@
using Assets.Scripts.Objects.Items;
using UnityEngine;
-internal static class ColorCyclerModHelpers
+namespace ColorCycler
{
- public static int GetPaintColorIndex(UnityEngine.Material paintMaterial)
+
+ internal static class ColorCyclerModHelpers
{
- for (int i = 0; i < GameManager.Instance.CustomColors.Count; i++)
+ internal const ushort PaintableMaterialNetworkFlag = 0x1000; //NetworkUpdateType.Thing.GenericFlag2
+
+ public static int GetPaintColorIndex(UnityEngine.Material paintMaterial)
{
- if (GameManager.Instance.CustomColors[i].Normal == paintMaterial)
+ for (int i = 0; i < GameManager.Instance.CustomColors.Count; i++)
{
- return i;
+ if (GameManager.Instance.CustomColors[i].Normal == paintMaterial)
+ {
+ return i;
+ }
}
+ return -1;
}
- return -1;
- }
- public static UnityEngine.Material GetPaintColor(int colorIndex)
- {
- return GameManager.Instance.CustomColors[colorIndex].Normal;
- }
+ public static UnityEngine.Material GetPaintColor(int colorIndex)
+ {
+ if (colorIndex < 0 || colorIndex > GameManager.Instance.CustomColors.Count)
+ {
+ ColorCyclerBep.Logger.LogError($"{nameof(GetPaintColor)}: {nameof(colorIndex)} was {colorIndex:D} which is out of range.");
+ colorIndex = 0;
+ }
+ return GameManager.Instance.CustomColors[colorIndex].Normal;
+ }
- public static void UpdateSprayCan(SprayCan sprayCan, UnityEngine.Material paintMaterial)
- {
- sprayCan.PaintableMaterial = paintMaterial;
- sprayCan.PaintMaterial = sprayCan.PaintableMaterial;
- foreach (Thing thing in Prefab.AllPrefabs)
+ public static void UpdateSprayCan(SprayCan sprayCan, UnityEngine.Material paintMaterial)
{
- if (thing is SprayCan sprayCan2)
+ ColorCyclerBep.Logger.LogDebug($"{nameof(ColorCyclerBep.Settings.ShouldCreatePollution)}: {ColorCyclerBep.Settings.ShouldCreatePollution}");
+ ColorCyclerBep.Logger.LogDebug($"{nameof(ColorCyclerBep.Settings.InfinitePaint)}: {ColorCyclerBep.Settings.InfinitePaint}");
+ ColorCyclerBep.Logger.LogDebug($"Updating {sprayCan.DisplayName} - {sprayCan.ReferenceId} to {paintMaterial.name} on {(NetworkManager.IsServer ? "Server" : "Client")}");
+ sprayCan.PaintableMaterial = paintMaterial;
+ sprayCan.PaintMaterial = sprayCan.PaintableMaterial;
+ //TODO: Look up prefab hashes and cache for faster lookup
+ foreach (Thing thing in Prefab.AllPrefabs)
{
- if (sprayCan2.PaintMaterial == sprayCan.PaintMaterial)
+ if (thing is SprayCan sprayCan2)
{
- sprayCan.SetPrefab(sprayCan2);
- // Update Hash so that sorting and logic will remain
- sprayCan.PrefabHash = sprayCan2.PrefabHash;
- // Update "real" name
- sprayCan.PrefabName = sprayCan2.PrefabName;
- sprayCan.Thumbnail = sprayCan2.Thumbnail;
- // Update Mesh such that thrown model appears correctly
- if (sprayCan.GetComponent() is MeshRenderer mr)
+ if (sprayCan2.PaintMaterial == sprayCan.PaintMaterial)
{
- mr.sharedMaterial = sprayCan.PaintMaterial;
+ sprayCan.SetPrefab(sprayCan2);
+ // Update Hash so that sorting and logic will remain
+ sprayCan.PrefabHash = sprayCan2.PrefabHash;
+ // Update "real" name
+ sprayCan.PrefabName = sprayCan2.PrefabName;
+ sprayCan.Thumbnail = sprayCan2.Thumbnail;
+ // Update Mesh such that thrown model appears correctly
+ if (sprayCan.GetComponent() is MeshRenderer mr)
+ {
+ mr.sharedMaterial = sprayCan.PaintMaterial;
+ }
+ ColorCyclerBep.Logger.LogDebug($"Previous SprayCan Quantity: {sprayCan.Quantity}");
+ if (ColorCyclerBep.Settings.InfinitePaint)
+ {
+ ColorCyclerBep.Logger.LogDebug($"Setting Quantity to MaxQuantity.");
+ sprayCan.Quantity = sprayCan.MaxQuantity;
+ }
+ break;
}
- sprayCan.Quantity = sprayCan.MaxQuantity;
- break;
}
}
- }
- if (NetworkManager.IsServer)
- {
- sprayCan.NetworkUpdateFlags |= 4096;
+ if (NetworkManager.IsServer)
+ {
+ sprayCan.NetworkUpdateFlags |= PaintableMaterialNetworkFlag;
+ }
}
}
-}
\ No newline at end of file
+}