Bump version of dependency WaterGun-V70PoweredLights_Fix to 1.2.1
Version 1.2.1 correctly applies animators patches, so this mod doesn't have to include a copy anymore.
This commit is contained in:
parent
d600a3170f
commit
7fb63e4718
|
|
@ -89,7 +89,6 @@
|
||||||
<PackagedResources Include="$(SolutionDir)icon.png" />
|
<PackagedResources Include="$(SolutionDir)icon.png" />
|
||||||
<PackagedResources Include="$(SolutionDir)manifest.json" />
|
<PackagedResources Include="$(SolutionDir)manifest.json" />
|
||||||
<PackagedResources Include="$(ProjectDir)UnityAssets\muzikagromche_discoball" />
|
<PackagedResources Include="$(ProjectDir)UnityAssets\muzikagromche_discoball" />
|
||||||
<PackagedResources Include="$(ProjectDir)UnityAssets\muzikagromche_poweredlightsanimators" />
|
|
||||||
<PackagedResources Include="$(TargetDir)$(AssemblyName).dll" />
|
<PackagedResources Include="$(TargetDir)$(AssemblyName).dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,9 @@ namespace MuzikaGromche
|
||||||
#endif
|
#endif
|
||||||
Config = new Config(base.Config);
|
Config = new Config(base.Config);
|
||||||
DiscoBallManager.Load();
|
DiscoBallManager.Load();
|
||||||
PoweredLightsAnimators.Load();
|
|
||||||
Harmony = new Harmony(MyPluginInfo.PLUGIN_NAME);
|
Harmony = new Harmony(MyPluginInfo.PLUGIN_NAME);
|
||||||
Harmony.PatchAll(typeof(GameNetworkManagerPatch));
|
Harmony.PatchAll(typeof(GameNetworkManagerPatch));
|
||||||
Harmony.PatchAll(typeof(JesterPatch));
|
Harmony.PatchAll(typeof(JesterPatch));
|
||||||
Harmony.PatchAll(typeof(PoweredLightsAnimatorsPatch));
|
|
||||||
Harmony.PatchAll(typeof(AllPoweredLightsPatch));
|
Harmony.PatchAll(typeof(AllPoweredLightsPatch));
|
||||||
Harmony.PatchAll(typeof(DiscoBallTilePatch));
|
Harmony.PatchAll(typeof(DiscoBallTilePatch));
|
||||||
Harmony.PatchAll(typeof(DiscoBallDespawnPatch));
|
Harmony.PatchAll(typeof(DiscoBallDespawnPatch));
|
||||||
|
|
|
||||||
|
|
@ -1,244 +1,9 @@
|
||||||
using DunGen;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MuzikaGromche
|
namespace MuzikaGromche
|
||||||
{
|
{
|
||||||
static class PoweredLightsAnimators
|
|
||||||
{
|
|
||||||
private const string PoweredLightTag = "PoweredLight";
|
|
||||||
|
|
||||||
private delegate void ManualPatch(GameObject animatorContainer);
|
|
||||||
|
|
||||||
private readonly record struct AnimatorPatch(
|
|
||||||
string AnimatorContainerPath,
|
|
||||||
RuntimeAnimatorController AnimatorController,
|
|
||||||
bool AddTagAndAnimator,
|
|
||||||
ManualPatch? ManualPatch);
|
|
||||||
|
|
||||||
private readonly record struct TilePatch(string TileName, AnimatorPatch[] Patches)
|
|
||||||
{
|
|
||||||
// We are specifically looking for cloned tiles, not the original prototypes.
|
|
||||||
public readonly string TileCloneName = $"{TileName}(Clone)";
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly record struct AnimatorPatchDescriptor(
|
|
||||||
string AnimatorContainerPath,
|
|
||||||
string AnimatorControllerAssetPath,
|
|
||||||
bool AddTagAndAnimator = false,
|
|
||||||
ManualPatch? ManualPatch = null)
|
|
||||||
{
|
|
||||||
public AnimatorPatch Load(AssetBundle assetBundle)
|
|
||||||
{
|
|
||||||
var animationController = assetBundle.LoadAsset<RuntimeAnimatorController>(AnimatorControllerAssetPath)
|
|
||||||
?? throw new FileNotFoundException($"RuntimeAnimatorController not found: {AnimatorControllerAssetPath}", AnimatorControllerAssetPath);
|
|
||||||
return new(AnimatorContainerPath, animationController, AddTagAndAnimator, ManualPatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly record struct TilePatchDescriptor(string[] TileNames, AnimatorPatchDescriptor[] Descriptors)
|
|
||||||
{
|
|
||||||
public TilePatchDescriptor(string TileName, AnimatorPatchDescriptor[] Descriptors)
|
|
||||||
: this([TileName], Descriptors)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TilePatch[] Load(AssetBundle assetBundle)
|
|
||||||
{
|
|
||||||
var patches = Descriptors.Select(d => d.Load(assetBundle)).ToArray();
|
|
||||||
return [.. TileNames.Select(tileName => new TilePatch(tileName, patches))];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IDictionary<string, TilePatch> Patches = new Dictionary<string, TilePatch>();
|
|
||||||
|
|
||||||
private static AudioClip AudioClipOn = null!;
|
|
||||||
private static AudioClip AudioClipOff = null!;
|
|
||||||
private static AudioClip AudioClipFlicker = null!;
|
|
||||||
|
|
||||||
public static void Load()
|
|
||||||
{
|
|
||||||
const string BundleFileName = "muzikagromche_poweredlightsanimators";
|
|
||||||
string bundlePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), BundleFileName);
|
|
||||||
var assetBundle = AssetBundle.LoadFromFile(bundlePath)
|
|
||||||
?? throw new NullReferenceException("Failed to load bundle");
|
|
||||||
|
|
||||||
AudioClipOn = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightOn.ogg");
|
|
||||||
AudioClipOff = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightOff.ogg");
|
|
||||||
AudioClipFlicker = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightFlicker.ogg");
|
|
||||||
|
|
||||||
const string BasePath = "Assets/LethalCompany/Mods/MuzikaGromche/AnimatorControllers/";
|
|
||||||
|
|
||||||
const string PointLight4 = $"{BasePath}Point Light (4) (Patched).controller";
|
|
||||||
const string MineshaftSpotlight = $"{BasePath}MineshaftSpotlight (Patched).controller";
|
|
||||||
const string LightbulbsLine = $"{BasePath}lightbulbsLineMesh (Patched).controller";
|
|
||||||
const string CeilingFan = $"{BasePath}CeilingFan (originally GameObject) (Patched).controller";
|
|
||||||
const string LEDHangingLight = $"{BasePath}LEDHangingLight (Patched).controller";
|
|
||||||
const string MineshaftStartTileSpotlight = $"{BasePath}MineshaftStartTileSpotlight (New).controller";
|
|
||||||
|
|
||||||
TilePatchDescriptor[] descriptors =
|
|
||||||
[
|
|
||||||
// any version
|
|
||||||
new("KitchenTile", [
|
|
||||||
new("PoweredLightTypeB", PointLight4),
|
|
||||||
new("PoweredLightTypeB (1)", PointLight4),
|
|
||||||
]),
|
|
||||||
// < v70
|
|
||||||
new("ManorStartRoom", [
|
|
||||||
new("ManorStartRoom/Chandelier/PoweredLightTypeB (1)", PointLight4),
|
|
||||||
new("ManorStartRoom/Chandelier2/PoweredLightTypeB", PointLight4),
|
|
||||||
]),
|
|
||||||
// v70+
|
|
||||||
new("ManorStartRoomSmall", [
|
|
||||||
new("ManorStartRoomMesh/Chandelier/PoweredLightTypeB (1)", PointLight4),
|
|
||||||
new("ManorStartRoomMesh/Chandelier2/PoweredLightTypeB", PointLight4),
|
|
||||||
]),
|
|
||||||
new("NarrowHallwayTile2x2", [
|
|
||||||
new("MineshaftSpotlight (1)", MineshaftSpotlight),
|
|
||||||
new("MineshaftSpotlight (2)", MineshaftSpotlight),
|
|
||||||
]),
|
|
||||||
new("BirthdayRoomTile", [
|
|
||||||
new("Lights/MineshaftSpotlight", MineshaftSpotlight),
|
|
||||||
]),
|
|
||||||
new("BathroomTileContainer", [
|
|
||||||
new("MineshaftSpotlight", MineshaftSpotlight),
|
|
||||||
new("LightbulbLine/lightbulbsLineMesh", LightbulbsLine),
|
|
||||||
]),
|
|
||||||
new(["BedroomTile", "BedroomTileB"], [
|
|
||||||
new("CeilingFanAnimContainer", CeilingFan),
|
|
||||||
new("MineshaftSpotlight (1)", MineshaftSpotlight),
|
|
||||||
]),
|
|
||||||
new("GarageTile", [
|
|
||||||
new("HangingLEDBarLight (3)", LEDHangingLight),
|
|
||||||
new("HangingLEDBarLight (4)", LEDHangingLight),
|
|
||||||
// This HangingLEDBarLight's IndirectLight is wrongly named, so animator couldn't find it
|
|
||||||
// renamed by WaterGun-V70PoweredLights_Fix-1.1.0
|
|
||||||
// ManualPatch: RenameGameObjectPatch("IndirectLight (1)", "IndirectLight")),
|
|
||||||
]),
|
|
||||||
new("PoolTile", [
|
|
||||||
new("PoolLights/HangingLEDBarLight", LEDHangingLight),
|
|
||||||
new("PoolLights/HangingLEDBarLight (4)", LEDHangingLight),
|
|
||||||
new("PoolLights/HangingLEDBarLight (5)", LEDHangingLight),
|
|
||||||
]),
|
|
||||||
new("MineshaftStartTile", [
|
|
||||||
new("Cylinder.001 (1)", MineshaftStartTileSpotlight, AddTagAndAnimator: true),
|
|
||||||
new("Cylinder.001 (2)", MineshaftStartTileSpotlight, AddTagAndAnimator: true),
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
|
|
||||||
Patches = descriptors
|
|
||||||
.SelectMany(d => d.Load(assetBundle))
|
|
||||||
.ToDictionary(d => d.TileCloneName, d => d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Patch(Tile tile)
|
|
||||||
{
|
|
||||||
if (tile == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(tile));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Patches.TryGetValue(tile.gameObject.name, out var tilePatch))
|
|
||||||
{
|
|
||||||
foreach (var patch in tilePatch.Patches)
|
|
||||||
{
|
|
||||||
Transform animationContainerTransform = tile.gameObject.transform.Find(patch.AnimatorContainerPath);
|
|
||||||
if (animationContainerTransform == null)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
throw new NullReferenceException($"{tilePatch.TileName}/{patch.AnimatorContainerPath} Animation Container not found");
|
|
||||||
#endif
|
|
||||||
#pragma warning disable CS0162 // Unreachable code detected
|
|
||||||
continue;
|
|
||||||
#pragma warning restore CS0162 // Unreachable code detected
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObject animationContainer = animationContainerTransform.gameObject;
|
|
||||||
Animator animator = animationContainer.GetComponent<Animator>();
|
|
||||||
|
|
||||||
if (patch.AddTagAndAnimator)
|
|
||||||
{
|
|
||||||
animationContainer.tag = PoweredLightTag;
|
|
||||||
if (animator == null)
|
|
||||||
{
|
|
||||||
animator = animationContainer.AddComponent<Animator>();
|
|
||||||
}
|
|
||||||
if (!animationContainer.TryGetComponent<PlayAudioAnimationEvent>(out var audioScript))
|
|
||||||
{
|
|
||||||
audioScript = animationContainer.AddComponent<PlayAudioAnimationEvent>();
|
|
||||||
audioScript.audioClip = AudioClipOn;
|
|
||||||
audioScript.audioClip2 = AudioClipOff;
|
|
||||||
audioScript.audioClip3 = AudioClipFlicker;
|
|
||||||
}
|
|
||||||
if (!animationContainer.TryGetComponent<AudioSource>(out var audioSource))
|
|
||||||
{
|
|
||||||
// Copy from an existing AudioSource of another light animator
|
|
||||||
var otherSource = tile.gameObject.GetComponentInChildren<AudioSource>();
|
|
||||||
if (otherSource != null)
|
|
||||||
{
|
|
||||||
audioSource = animationContainer.AddComponent<AudioSource>();
|
|
||||||
audioSource.spatialBlend = 1;
|
|
||||||
audioSource.playOnAwake = false;
|
|
||||||
audioSource.outputAudioMixerGroup = otherSource.outputAudioMixerGroup;
|
|
||||||
audioSource.spread = otherSource.spread;
|
|
||||||
audioSource.rolloffMode = otherSource.rolloffMode;
|
|
||||||
audioSource.maxDistance = otherSource.maxDistance;
|
|
||||||
audioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, otherSource.GetCustomCurve(AudioSourceCurveType.CustomRolloff));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animator == null)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
throw new NullReferenceException($"{tilePatch.TileName}/{patch.AnimatorContainerPath} Animation Component not found");
|
|
||||||
#endif
|
|
||||||
#pragma warning disable CS0162 // Unreachable code detected
|
|
||||||
continue;
|
|
||||||
#pragma warning restore CS0162 // Unreachable code detected
|
|
||||||
}
|
|
||||||
|
|
||||||
patch.ManualPatch?.Invoke(animationContainer);
|
|
||||||
|
|
||||||
animator.runtimeAnimatorController = patch.AnimatorController;
|
|
||||||
Plugin.Log.LogDebug($"{nameof(PoweredLightsAnimatorsPatch)} {tilePatch.TileName}/{patch.AnimatorContainerPath}: Replaced animator controller");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ManualPatch RenameGameObjectPatch(string relativePath, string newName) => animatorContainer =>
|
|
||||||
{
|
|
||||||
var targetObject = animatorContainer.transform.Find(relativePath)?.gameObject;
|
|
||||||
if (targetObject == null)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
throw new NullReferenceException($"{animatorContainer.name}/{relativePath}: GameObject not found!");
|
|
||||||
#endif
|
|
||||||
#pragma warning disable CS0162 // Unreachable code detected
|
|
||||||
return;
|
|
||||||
#pragma warning restore CS0162 // Unreachable code detected
|
|
||||||
}
|
|
||||||
targetObject.name = newName;
|
|
||||||
Plugin.Log.LogDebug($"{nameof(PoweredLightsAnimatorsPatch)} {animatorContainer.name}/{relativePath}: Renamed GameObject");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(Tile))]
|
|
||||||
static class PoweredLightsAnimatorsPatch
|
|
||||||
{
|
|
||||||
[HarmonyPatch(nameof(Tile.AddTriggerVolume))]
|
|
||||||
[HarmonyPostfix]
|
|
||||||
static void OnAddTriggerVolume(Tile __instance)
|
|
||||||
{
|
|
||||||
PoweredLightsAnimators.Patch(__instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(RoundManager))]
|
[HarmonyPatch(typeof(RoundManager))]
|
||||||
static class AllPoweredLightsPatch
|
static class AllPoweredLightsPatch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -7,6 +7,6 @@
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"BepInEx-BepInExPack-5.4.2100",
|
"BepInEx-BepInExPack-5.4.2100",
|
||||||
"AinaVT-LethalConfig-1.4.6",
|
"AinaVT-LethalConfig-1.4.6",
|
||||||
"WaterGun-V70PoweredLights_Fix-1.0.0"
|
"WaterGun-V70PoweredLights_Fix-1.2.1"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue