Skip to content

Commit 17e723b

Browse files
committed
begin patching MCC and MCU
1 parent 7492efb commit 17e723b

File tree

3 files changed

+148
-2
lines changed

3 files changed

+148
-2
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using System.Collections.Generic;
2+
using System.Reflection.Emit;
3+
using HarmonyLib;
4+
using UnityEngine;
5+
6+
namespace Shabby.DynamicProperties;
7+
8+
[HarmonyPatch(typeof(MaterialColorUpdater))]
9+
public class MaterialColorUpdaterPatch
10+
{
11+
internal static readonly Dictionary<MaterialColorUpdater, Props> temperatureColorProps = [];
12+
13+
[HarmonyPostfix]
14+
[HarmonyPatch(MethodType.Constructor, typeof(Transform), typeof(int), typeof(Part))]
15+
private static void MaterialColorUpdater_Ctor_Postfix(MaterialColorUpdater __instance)
16+
{
17+
temperatureColorProps[__instance] = new Props(int.MinValue + 1);
18+
}
19+
20+
[HarmonyPostfix]
21+
[HarmonyPatch("CreateRendererList")]
22+
private static void MaterialColorUpdater_CreateRendererList_Postfix(
23+
MaterialColorUpdater __instance)
24+
{
25+
var props = temperatureColorProps[__instance];
26+
foreach (var renderer in __instance.renderers) {
27+
MaterialPropertyManager.Instance?.Set(renderer, props);
28+
}
29+
}
30+
31+
private static void Update_SetProperty(MaterialColorUpdater mcu)
32+
{
33+
temperatureColorProps[mcu].SetColor(mcu.propertyID, mcu.setColor);
34+
}
35+
36+
[HarmonyTranspiler]
37+
[HarmonyPatch(nameof(MaterialColorUpdater.Update))]
38+
private static IEnumerable<CodeInstruction> Update_Transpiler(
39+
IEnumerable<CodeInstruction> insns)
40+
{
41+
var MPB_SetColor = AccessTools.Method(
42+
typeof(MaterialPropertyBlock),
43+
nameof(MaterialPropertyBlock.SetColor),
44+
[typeof(int), typeof(Color)]);
45+
46+
foreach (var insn in insns) {
47+
yield return insn;
48+
49+
// IL_0022: ldarg.0 // this
50+
// IL_0023: ldfld class UnityEngine.MaterialPropertyBlock MaterialColorUpdater::mpb
51+
// IL_0028: ldarg.0 // this
52+
// IL_0029: ldfld int32 MaterialColorUpdater::propertyID
53+
// IL_002e: ldarg.0 // this
54+
// IL_002f: ldfld valuetype UnityEngine.Color MaterialColorUpdater::setColor
55+
// IL_0034: callvirt instance void UnityEngine.MaterialPropertyBlock::SetColor(int32, valuetype UnityEngine.Color)
56+
if (insn.Calls(MPB_SetColor)) break;
57+
}
58+
59+
CodeInstruction[] replace = [
60+
new(OpCodes.Ldarg_0), // this
61+
CodeInstruction.Call(() => Update_SetProperty(default)),
62+
new(OpCodes.Ret)
63+
];
64+
foreach (var insn in replace) yield return insn;
65+
}
66+
67+
private static void DisposeIfExists(MaterialColorUpdater mcu)
68+
{
69+
if (mcu == null) return;
70+
if (temperatureColorProps.TryGetValue(mcu, out var props)) props.Dispose();
71+
}
72+
73+
[HarmonyPrefix]
74+
[HarmonyPatch(typeof(Part), nameof(Part.ResetMPB))]
75+
private static void Part_ResetMPB_Prefix(Part __instance)
76+
{
77+
DisposeIfExists(__instance.temperatureRenderer);
78+
}
79+
80+
[HarmonyPostfix]
81+
[HarmonyPatch(typeof(Part), "OnDestroy")]
82+
private static void Part_OnDestroy_Postfix(Part __instance)
83+
{
84+
DisposeIfExists(__instance.temperatureRenderer);
85+
}
86+
87+
// FIXME: write a transpiler for ModuleJettison.Jettison.
88+
89+
[HarmonyPostfix]
90+
[HarmonyPatch(typeof(ModuleJettison), "OnDestroy")]
91+
private static void ModuleJettison_OnDestroy_Postfix(ModuleJettison __instance)
92+
{
93+
DisposeIfExists(__instance.jettisonTemperatureRenderer);
94+
}
95+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System.Collections.Generic;
2+
using HarmonyLib;
3+
4+
namespace Shabby.DynamicProperties;
5+
6+
[HarmonyPatch(typeof(ModuleColorChanger))]
7+
internal class ModuleColorChangerPatch
8+
{
9+
internal static readonly Dictionary<ModuleColorChanger, Props> mccProps = [];
10+
11+
[HarmonyPostfix]
12+
[HarmonyPatch(nameof(ModuleColorChanger.OnStart))]
13+
private static void OnStart_Postfix(ModuleColorChanger __instance)
14+
{
15+
mccProps[__instance] = new Props(0);
16+
}
17+
18+
[HarmonyPostfix]
19+
[HarmonyPatch("EditRenderers")]
20+
private static void EditRenderers_Postfix(ModuleColorChanger __instance)
21+
{
22+
var props = mccProps[__instance];
23+
foreach (var renderer in __instance.renderers) {
24+
MaterialPropertyManager.Instance?.Set(renderer, props);
25+
}
26+
}
27+
28+
[HarmonyPrefix]
29+
[HarmonyPatch("UpdateColor")]
30+
public static bool UpdateColor_Prefix(ModuleColorChanger __instance)
31+
{
32+
mccProps[__instance].SetColor(__instance.shaderPropertyInt, __instance.color);
33+
return false;
34+
}
35+
36+
[HarmonyPostfix]
37+
[HarmonyPatch(typeof(Part), "OnDestroy")]
38+
private static void Part_OnDestroy_Postfix(Part __instance)
39+
{
40+
foreach (var mcc in __instance.FindModulesImplementing<ModuleColorChanger>()) {
41+
if (mccProps.Remove(mcc, out var props)) props.Dispose();
42+
}
43+
}
44+
45+
// FIXME: are part modules destroyed in other places? Icon renderers? Drag cube renderers?
46+
}

Source/Shabby.csproj

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@
4343

4444
<!-- Publicizer -->
4545
<ItemGroup>
46-
<Publicize Include="Assembly-CSharp:Part.modelRenderersCache"/>
47-
<Publicize Include="Assembly-CSharp:Part.highlightRenderer"/>
46+
<Publicize Include="Assembly-CSharp:MaterialColorUpdater.setColor"/>
47+
<Publicize Include="Assembly-CSharp:ModuleColorChanger.color"/>
48+
<Publicize Include="Assembly-CSharp:ModuleColorChanger.renderers"/>
49+
<Publicize Include="Assembly-CSharp:ModuleJettison.jettisonTemperatureRenderer"/>
4850
<Publicize Include="Assembly-CSharp:Part.CreateRendererLists"/>
51+
<Publicize Include="Assembly-CSharp:Part.highlightRenderer"/>
52+
<Publicize Include="Assembly-CSharp:Part.modelRenderersCache"/>
53+
<Publicize Include="Assembly-CSharp:Part.temperatureRenderer"/>
4954
</ItemGroup>
5055

5156
<!-- Version Files -->

0 commit comments

Comments
 (0)