forked from nikita/muzika-gromche
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)manifest.json" />
|
||||
<PackagedResources Include="$(ProjectDir)UnityAssets\muzikagromche_discoball" />
|
||||
<PackagedResources Include="$(ProjectDir)UnityAssets\muzikagromche_poweredlightsanimators" />
|
||||
<PackagedResources Include="$(TargetDir)$(AssemblyName).dll" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -158,11 +158,9 @@ namespace MuzikaGromche
|
|||
#endif
|
||||
Config = new Config(base.Config);
|
||||
DiscoBallManager.Load();
|
||||
PoweredLightsAnimators.Load();
|
||||
Harmony = new Harmony(MyPluginInfo.PLUGIN_NAME);
|
||||
Harmony.PatchAll(typeof(GameNetworkManagerPatch));
|
||||
Harmony.PatchAll(typeof(JesterPatch));
|
||||
Harmony.PatchAll(typeof(PoweredLightsAnimatorsPatch));
|
||||
Harmony.PatchAll(typeof(AllPoweredLightsPatch));
|
||||
Harmony.PatchAll(typeof(DiscoBallTilePatch));
|
||||
Harmony.PatchAll(typeof(DiscoBallDespawnPatch));
|
||||
|
|
|
|||
|
|
@ -1,244 +1,9 @@
|
|||
using DunGen;
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
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))]
|
||||
static class AllPoweredLightsPatch
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -7,6 +7,6 @@
|
|||
"dependencies": [
|
||||
"BepInEx-BepInExPack-5.4.2100",
|
||||
"AinaVT-LethalConfig-1.4.6",
|
||||
"WaterGun-V70PoweredLights_Fix-1.0.0"
|
||||
"WaterGun-V70PoweredLights_Fix-1.2.1"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue