using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using MetalCompany.Patches;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MetalCompany")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MetalCompany")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2f300945-55e0-43c2-a7e9-19825cd77899")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MetalCompany
{
[BepInPlugin("Kahvinkeitin34.MetalCompany", "Metal Company", "1.0.5")]
public class MetalCompanyBase : BaseUnityPlugin
{
private const string modGUID = "Kahvinkeitin34.MetalCompany";
private const string modName = "Metal Company";
private const string modVersion = "1.0.5";
private readonly Harmony harmony = new Harmony("Kahvinkeitin34.MetalCompany");
public static MetalCompanyBase Instance;
internal ManualLogSource mls;
internal static AudioClip[] Clips;
internal static AssetBundle Bundle;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("Kahvinkeitin34.MetalCompany");
mls.LogInfo((object)"Metal Company mod enabled.");
harmony.PatchAll(typeof(MetalCompanyBase));
harmony.PatchAll(typeof(BoomboxItemPatch));
mls = ((BaseUnityPlugin)this).Logger;
string text = ((BaseUnityPlugin)Instance).Info.Location.TrimEnd("MetalCompany.dll".ToCharArray());
Bundle = AssetBundle.LoadFromFile(text + "metalcompanybundle");
if ((Object)(object)Bundle != (Object)null)
{
mls.LogInfo((object)"Successfully loaded asset bundle");
Clips = Bundle.LoadAllAssets<AudioClip>();
}
else
{
mls.LogError((object)"Failed to load asset bundle");
}
}
}
}
namespace MetalCompany.Patches
{
[HarmonyPatch(typeof(BoomboxItem))]
internal class BoomboxItemPatch
{
private static List<AudioClip> clipPool;
private static AudioClip previousClip;
private const string hostBoxName = "Boombox_host";
private const string standardBoxName = "Boombox";
private static float updateInterval = 0.2f;
private static float updateTimer = 0f;
private static BoomboxItem[] PlayingBoomboxes => Object.FindObjectsOfType<BoomboxItem>()?.Where((BoomboxItem box) => box.isPlayingMusic).ToArray();
private static BoomboxItem HostBoombox => PlayingBoomboxes?.FirstOrDefault((Func<BoomboxItem, bool>)((BoomboxItem box) => ((Object)box).name == "Boombox_host"));
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void Start_Postfix(BoomboxItem __instance)
{
__instance.musicAudios = MetalCompanyBase.Clips;
((GrabbableObject)__instance).itemProperties.batteryUsage = 240f;
__instance.boomboxAudio.maxDistance = 35f;
__instance.boomboxAudio.loop = false;
__instance.boomboxAudio.dopplerLevel = 0f;
((Object)__instance).name = "Boombox";
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void Update_Postfix(BoomboxItem __instance)
{
PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy;
if (updateTimer <= 0f)
{
updateTimer = updateInterval;
if ((Object)(object)playerHeldBy != (Object)null)
{
if (((GrabbableObject)__instance).playerHeldBy.carryWeight > 1f)
{
((GrabbableObject)__instance).playerHeldBy.carryWeight = 1f;
}
if (playerHeldBy.sprintMeter < 0.5f)
{
playerHeldBy.sprintMeter = 0.5f;
}
}
if (!__instance.boomboxAudio.isPlaying)
{
if ((Object)(object)__instance == (Object)(object)HostBoombox)
{
PlayNextClip(__instance);
}
else if ((Object)(object)HostBoombox != (Object)null)
{
SyncBoombox(__instance, HostBoombox);
}
}
if ((Object)(object)HostBoombox != (Object)null && HostBoombox.isPlayingMusic)
{
__instance.boomboxAudio.timeSamples = HostBoombox.boomboxAudio.timeSamples - 1;
}
}
else
{
updateTimer -= Time.deltaTime;
}
}
private static void PlayNextClip(BoomboxItem boomboxItem)
{
if (clipPool == null || clipPool.Count == 0)
{
ResetClipPool(boomboxItem);
}
int index = boomboxItem.musicRandomizer.Next(0, clipPool.Count - 1);
AudioClip clip = clipPool[index];
clipPool.RemoveAt(index);
boomboxItem.boomboxAudio.clip = clip;
boomboxItem.boomboxAudio.timeSamples = 0;
boomboxItem.boomboxAudio.Play();
previousClip = clip;
}
private static void ResetClipPool(BoomboxItem boomboxItem)
{
clipPool = boomboxItem.musicAudios.Where((AudioClip clip) => (Object)(object)clip != (Object)(object)previousClip).ToList();
if (clipPool.Count == 0)
{
clipPool = boomboxItem.musicAudios.ToList();
}
}
[HarmonyPatch("PocketItem")]
[HarmonyPrefix]
private static bool PocketItem_Prefix(BoomboxItem __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && (Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null)
{
((GrabbableObject)__instance).playerHeldBy.IsInspectingItem = false;
}
((GrabbableObject)__instance).isPocketed = true;
((GrabbableObject)__instance).EnableItemMeshes(false);
((Component)__instance).gameObject.GetComponent<AudioSource>().PlayOneShot(((GrabbableObject)__instance).itemProperties.pocketSFX, 1f);
return false;
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch("StartMusic")]
[HarmonyPrefix]
private static bool StartMusic_Prefix(object[] __args, BoomboxItem __instance)
{
bool flag = (bool)__args[0];
if (flag)
{
__instance.boomboxAudio.volume = 1f;
__instance.boomboxAudio.pitch = 1f;
if ((Object)(object)HostBoombox != (Object)null && HostBoombox.isPlayingMusic)
{
MetalCompanyBase.Instance.mls.LogMessage((object)"Host exists, syncing to host.");
SyncBoombox(__instance, HostBoombox);
}
else
{
((Object)__instance).name = "Boombox_host";
PlayNextClip(__instance);
MetalCompanyBase.Instance.mls.LogMessage((object)"Made new host boombox and started playing music.");
if (PlayingBoomboxes.Length > 1)
{
MetalCompanyBase.Instance.mls.LogMessage((object)"Syncing other boomboxes.");
SyncBoomboxes(PlayingBoomboxes, __instance);
}
}
}
else
{
if ((Object)(object)__instance == (Object)(object)HostBoombox)
{
MetalCompanyBase.Instance.mls.LogMessage((object)"Host boombox stopped playing.");
((Object)__instance).name = "Boombox";
if (PlayingBoomboxes.Length != 0)
{
((Object)PlayingBoomboxes.First()).name = "Boombox_host";
MetalCompanyBase.Instance.mls.LogMessage((object)"Switched host boombox.");
}
else
{
MetalCompanyBase.Instance.mls.LogMessage((object)"Couldn't find another playing boombox, removed host.");
}
}
Battery insertedBattery = ((GrabbableObject)__instance).insertedBattery;
insertedBattery.charge -= ((GrabbableObject)__instance).itemProperties.batteryUsage * 0.1f;
__instance.boomboxAudio.Stop();
__instance.boomboxAudio.PlayOneShot(__instance.stopAudios[Random.Range(0, __instance.stopAudios.Length)]);
}
((GrabbableObject)__instance).isBeingUsed = flag;
__instance.isPlayingMusic = flag;
return false;
}
private static void SyncBoomboxes(BoomboxItem[] boomboxes, BoomboxItem boomBox)
{
foreach (BoomboxItem val in boomboxes)
{
if (!((Object)(object)val == (Object)(object)boomBox) && val.isPlayingMusic)
{
SyncBoombox(val, boomBox);
MetalCompanyBase.Instance.mls.LogMessage((object)"Synced boombox to host.");
}
}
}
private static void SyncBoombox(BoomboxItem syncBox, BoomboxItem hostBox)
{
if (hostBox.isPlayingMusic)
{
syncBox.boomboxAudio.clip = ((IEnumerable<AudioClip>)syncBox.musicAudios).FirstOrDefault((Func<AudioClip, bool>)((AudioClip clip) => ((Object)clip).name == ((Object)hostBox.boomboxAudio.clip).name));
syncBox.boomboxAudio.timeSamples = hostBox.boomboxAudio.timeSamples;
syncBox.boomboxAudio.Play();
}
}
}
}