Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of balrond runerails v1.1.2
plugins/BalrondRuneRails.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Balrond.Shared; using BalrondCargoSystems; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LitJson2; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Audio; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BalrondCargoSystems")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BalrondCargoSystems")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("cde312a0-cf19-4264-8616-e1c74774beed")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public enum BalrondLiftGateState { Closed, Opening, Open, Closing } public class BalrondLiftGate : MonoBehaviour, Hoverable, Interactable { private const string RpcToggle = "RPC_BalrondLiftGate_Toggle"; private const string RpcSetOpen = "RPC_BalrondLiftGate_SetOpen"; private const string ZdoState = "BalrondLiftGate_State"; private const string ZdoAnimStart = "BalrondLiftGate_AnimStart"; private const string ZdoInitialized = "BalrondLiftGate_Initialized"; [Header("Gate")] public string m_name = "Lift Gate"; public bool m_enabled = true; public bool m_defaultOpen = false; [Header("Gate Animation")] public Transform m_gatePivot; public Vector3 m_gateAxis = Vector3.right; public float m_openAngle = 85f; public float m_openDirection = 1f; public float m_animationSeconds = 2f; [Header("Gears - One Side")] public Transform m_gearStatic; public Transform m_gearBridge; public Vector3 m_gearAxis = Vector3.right; public float m_gearDegreesPerGateDegree = 4f; [Header("Animation Audio")] public GameObject m_animationActiveObject; [Header("Effects")] public EffectList m_openStartEffects = new EffectList(); public EffectList m_closeStartEffects = new EffectList(); [Header("Debug")] public bool m_debugLogs = false; private ZNetView _nview; private Quaternion _closedLocalRotation; private bool _closedRotationCached; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); CacheClosedRotation(); if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { _nview.Register("RPC_BalrondLiftGate_Toggle", (Action<long>)RPC_Toggle); _nview.Register<bool>("RPC_BalrondLiftGate_SetOpen", (Action<long, bool>)RPC_SetOpen); ZDO zDO = _nview.GetZDO(); if (zDO != null && !zDO.GetBool("BalrondLiftGate_Initialized", false)) { ClaimOwnershipIfNeeded(); BalrondLiftGateState balrondLiftGateState = (m_defaultOpen ? BalrondLiftGateState.Open : BalrondLiftGateState.Closed); zDO.Set("BalrondLiftGate_State", (int)balrondLiftGateState); zDO.Set("BalrondLiftGate_AnimStart", GetNetworkTime()); zDO.Set("BalrondLiftGate_Initialized", true); } } BalrondLiftGateState state = GetState(); ApplyVisual(GetVisualProgress(state)); UpdateAnimationActiveObject(state); } private void Update() { UpdateAnimationAndState(); } public string GetHoverName() { return m_name; } public float GetHoverOffset() { return 0f; } public string GetHoverText() { string text = m_name + " State: " + GetStateText(GetState()); text = text + "\n[<color=yellow><b>$KEY_Use</b></color>] " + (IsOpenOrOpening() ? "Close" : "Open"); BCSSignalLiftGateReceiver component = ((Component)this).GetComponent<BCSSignalLiftGateReceiver>(); if ((Object)(object)component != (Object)null) { text += component.GetExtraHoverText(); } return (Localization.instance != null) ? Localization.instance.Localize(text) : text; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (hold || !m_enabled) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } BCSSignalLiftGateReceiver component = ((Component)this).GetComponent<BCSSignalLiftGateReceiver>(); if ((Object)(object)component != (Object)null && IsShiftHeld()) { component.RequestSetSignalNameFromUser(); return true; } if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } _nview.InvokeRPC("RPC_BalrondLiftGate_Toggle", Array.Empty<object>()); return true; } private static bool IsShiftHeld() { return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); } private static bool IsAltHeld() { return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); } public bool UseItem(Humanoid user, ItemData item) { return false; } public void RequestOpen() { RequestSetOpen(open: true); } public void RequestClose() { RequestSetOpen(open: false); } public void RequestSetOpen(bool open) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("RPC_BalrondLiftGate_SetOpen", new object[1] { open }); } } public bool IsOpen() { return GetState() == BalrondLiftGateState.Open; } public bool IsClosed() { return GetState() == BalrondLiftGateState.Closed; } public bool IsAnimating() { BalrondLiftGateState state = GetState(); return state == BalrondLiftGateState.Opening || state == BalrondLiftGateState.Closing; } public bool IsOpenOrOpening() { BalrondLiftGateState state = GetState(); return state == BalrondLiftGateState.Open || state == BalrondLiftGateState.Opening; } public BalrondLiftGateState GetState() { ZDO zdo = GetZdo(); if (zdo == null) { return m_defaultOpen ? BalrondLiftGateState.Open : BalrondLiftGateState.Closed; } return zdo.GetInt("BalrondLiftGate_State", m_defaultOpen ? 2 : 0) switch { 1 => BalrondLiftGateState.Opening, 2 => BalrondLiftGateState.Open, 3 => BalrondLiftGateState.Closing, _ => BalrondLiftGateState.Closed, }; } private void RPC_Toggle(long sender) { if (m_enabled && !IsAnimating()) { SetTargetOpenOwned(!IsOpenOrOpening()); } } private void RPC_SetOpen(long sender, bool open) { if (m_enabled) { SetTargetOpenOwned(open); } } private void SetTargetOpenOwned(bool open) { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return; } ClaimOwnershipIfNeeded(); BalrondLiftGateState state = GetState(); if (state == BalrondLiftGateState.Opening || state == BalrondLiftGateState.Closing) { return; } if (open) { if (state != BalrondLiftGateState.Open) { SetStateOwned(BalrondLiftGateState.Opening); CreateEffects(m_openStartEffects); } } else if (state != BalrondLiftGateState.Closed) { SetStateOwned(BalrondLiftGateState.Closing); CreateEffects(m_closeStartEffects); } } private void SetStateOwned(BalrondLiftGateState state) { ZDO zdo = GetZdo(); if (zdo != null) { ClaimOwnershipIfNeeded(); zdo.Set("BalrondLiftGate_State", (int)state); zdo.Set("BalrondLiftGate_AnimStart", GetNetworkTime()); } } private void SetStateNoRestartOwned(BalrondLiftGateState state) { ZDO zdo = GetZdo(); if (zdo != null) { ClaimOwnershipIfNeeded(); zdo.Set("BalrondLiftGate_State", (int)state); } } private void UpdateAnimationAndState() { if (!m_enabled) { return; } CacheClosedRotation(); BalrondLiftGateState state = GetState(); float num = Mathf.Max(0.01f, SanitizeFloat(m_animationSeconds, 2f)); float animStartTime = GetAnimStartTime(); float networkTime = GetNetworkTime(); float num2 = Mathf.Clamp01((networkTime - animStartTime) / num); float progress = 0f; switch (state) { case BalrondLiftGateState.Closed: progress = 0f; break; case BalrondLiftGateState.Open: progress = 1f; break; case BalrondLiftGateState.Opening: progress = num2; if (num2 >= 1f && IsOwner()) { SetStateNoRestartOwned(BalrondLiftGateState.Open); } break; case BalrondLiftGateState.Closing: progress = 1f - num2; if (num2 >= 1f && IsOwner()) { SetStateNoRestartOwned(BalrondLiftGateState.Closed); } break; } ApplyVisual(progress); UpdateAnimationActiveObject(state); } private void ApplyVisual(float progress) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(progress); float num2 = Mathf.Sign(SanitizeFloat(m_openDirection, 1f)); if (Mathf.Abs(num2) <= 0.001f) { num2 = 1f; } float num3 = num * Mathf.Max(0f, SanitizeFloat(m_openAngle, 85f)) * num2; if ((Object)(object)m_gatePivot != (Object)null) { Vector3 safeAxis = GetSafeAxis(m_gateAxis, Vector3.right); m_gatePivot.localRotation = _closedLocalRotation * Quaternion.AngleAxis(num3, safeAxis); } float num4 = Mathf.Abs(num3) * Mathf.Max(0f, SanitizeFloat(m_gearDegreesPerGateDegree, 4f)); ApplyGear(m_gearStatic, 0f - num4); ApplyGear(m_gearBridge, num4); } private Transform GetGearRotationPivot(Transform gearRoot) { if ((Object)(object)gearRoot == (Object)null) { return null; } if (((Object)gearRoot).name == "gear-pivot") { return gearRoot; } Transform val = gearRoot.Find("gear-pivot"); if ((Object)(object)val != (Object)null) { return val; } Transform[] componentsInChildren = ((Component)gearRoot).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "gear-pivot") { return val2; } } return gearRoot; } private void ApplyGear(Transform gearRoot, float angle) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Transform gearRotationPivot = GetGearRotationPivot(gearRoot); if (!((Object)(object)gearRotationPivot == (Object)null)) { Vector3 safeAxis = GetSafeAxis(m_gearAxis, Vector3.right); gearRotationPivot.localRotation = Quaternion.AngleAxis(angle, safeAxis); } } private void CacheClosedRotation() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!_closedRotationCached && !((Object)(object)m_gatePivot == (Object)null)) { _closedLocalRotation = m_gatePivot.localRotation; _closedRotationCached = true; } } private float GetVisualProgress(BalrondLiftGateState state) { if (state == BalrondLiftGateState.Open || state == BalrondLiftGateState.Opening) { return 1f; } return 0f; } private void UpdateAnimationActiveObject(BalrondLiftGateState state) { bool flag = state == BalrondLiftGateState.Opening || state == BalrondLiftGateState.Closing; if ((Object)(object)m_animationActiveObject == (Object)null) { return; } if (m_animationActiveObject.activeSelf != flag) { m_animationActiveObject.SetActive(flag); } AudioSource[] componentsInChildren = m_animationActiveObject.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } val.loop = true; if (flag) { if (!val.isPlaying) { val.Play(); } continue; } if (val.isPlaying) { val.Stop(); } val.time = 0f; } } private void CreateEffects(EffectList effects) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (effects != null && effects.m_effectPrefabs != null && effects.m_effectPrefabs.Length != 0) { effects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } private float GetAnimStartTime() { ZDO zdo = GetZdo(); if (zdo == null) { return GetNetworkTime(); } return zdo.GetFloat("BalrondLiftGate_AnimStart", GetNetworkTime()); } private string GetStateText(BalrondLiftGateState state) { return state switch { BalrondLiftGateState.Open => "Open", BalrondLiftGateState.Opening => "Opening", BalrondLiftGateState.Closing => "Closing", _ => "Closed", }; } private ZDO GetZdo() { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return null; } return _nview.GetZDO(); } private bool IsOwner() { return (Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner(); } private void ClaimOwnershipIfNeeded() { if ((Object)(object)_nview != (Object)null && _nview.IsValid() && !_nview.IsOwner()) { _nview.ClaimOwnership(); } } private static Vector3 GetSafeAxis(Vector3 axis, Vector3 fallback) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref axis)).sqrMagnitude <= 0.0001f) { return ((Vector3)(ref fallback)).normalized; } return ((Vector3)(ref axis)).normalized; } private static float SanitizeFloat(float value, float fallback) { if (float.IsNaN(value) || float.IsInfinity(value)) { return fallback; } return value; } private static float GetNetworkTime() { if ((Object)(object)ZNet.instance != (Object)null) { return (float)ZNet.instance.GetTimeSeconds(); } return Time.time; } private void Log(string msg) { if (m_debugLogs) { Debug.Log((object)("[BalrondLiftGate][" + ((Object)((Component)this).gameObject).name + "] " + msg)); } } } namespace BalrondCargoSystems { internal static class BCSConfig { private static ConfigSync _configSync; private static ConfigEntry<bool> _lockConfiguration; private static ConfigEntry<float> _trainSpeedMultiplier; private static ConfigEntry<float> _maximumTrainSpeed; private static ConfigEntry<bool> _straightRunAcceleration; private static ConfigEntry<bool> _slopeSpeedEffects; private static ConfigEntry<float> _speedRailMultiplier; private static ConfigEntry<bool> _autoCoupling; private static ConfigEntry<float> _autoCoupleRadius; private static ConfigEntry<bool> _enableRunDamage; private static ConfigEntry<float> _runDamageMultiplier; private static ConfigEntry<float> _runKnockbackMultiplier; private static ConfigEntry<int> _minimumCargoOperationStopTime; private static ConfigEntry<float> _unloaderSpeedMultiplier; private static ConfigEntry<float> _signalMaximumRange; private static ConfigEntry<float> _presenceSignalMaximumRange; private static ConfigEntry<float> _dayNightSignalMaximumRange; private static ConfigEntry<float> _maximumSignalDuration; private static ConfigEntry<KeyCode> _switchModifierKey; private static ConfigEntry<KeyCode> _cameraModifierKey; private static ConfigEntry<bool> _debugLogging; private static ConfigEntry<bool> _audioRoutingDebugLogging; public static bool IsInitialized { get; private set; } public static float TrainSpeedMultiplier => ReadFloat(_trainSpeedMultiplier, 1f, 0.25f, 4f); public static float MaximumTrainSpeed => ReadFloat(_maximumTrainSpeed, 16f, 1f, 64f); public static bool StraightRunAccelerationEnabled => _straightRunAcceleration == null || _straightRunAcceleration.Value; public static bool SlopeSpeedEffectsEnabled => _slopeSpeedEffects == null || _slopeSpeedEffects.Value; public static float SpeedRailMultiplier => ReadFloat(_speedRailMultiplier, 1.75f, 0.1f, 4f); public static bool AutoCouplingEnabled => _autoCoupling == null || _autoCoupling.Value; public static float AutoCoupleRadius => ReadFloat(_autoCoupleRadius, 0.35f, 0.05f, 2f); public static bool RunDamageEnabled => _enableRunDamage == null || _enableRunDamage.Value; public static float RunDamageMultiplier => ReadFloat(_runDamageMultiplier, 1f, 0f, 5f); public static float RunKnockbackMultiplier => ReadFloat(_runKnockbackMultiplier, 1f, 0f, 5f); public static int MinimumCargoOperationStopTime { get { int num = ((_minimumCargoOperationStopTime != null) ? _minimumCargoOperationStopTime.Value : 3); return Mathf.Clamp(num, 1, 60); } } public static float UnloaderSpeedMultiplier => ReadFloat(_unloaderSpeedMultiplier, 1f, 0.25f, 4f); public static float SignalMaximumRange => ReadFloat(_signalMaximumRange, 50f, 1f, 250f); public static float PresenceSignalMaximumRange => ReadFloat(_presenceSignalMaximumRange, 50f, 1f, 250f); public static float DayNightSignalMaximumRange => ReadFloat(_dayNightSignalMaximumRange, 100f, 1f, 500f); public static float MaximumSignalDuration => ReadFloat(_maximumSignalDuration, 120f, 0f, 600f); public static KeyCode SwitchModifierKey => (KeyCode)((_switchModifierKey == null) ? 304 : ((int)_switchModifierKey.Value)); public static KeyCode CameraModifierKey => (KeyCode)((_cameraModifierKey == null) ? 308 : ((int)_cameraModifierKey.Value)); public static bool DebugLoggingEnabled => _debugLogging != null && _debugLogging.Value; public static bool AudioRoutingDebugLoggingEnabled => _audioRoutingDebugLogging != null && _audioRoutingDebugLogging.Value; public static void Initialize(ConfigFile config) { if (!IsInitialized && config != null) { _configSync = new ConfigSync("balrond.astafaraios.BalrondRuneRails") { DisplayName = "BalrondRuneRails", CurrentVersion = "1.1.2", MinimumRequiredVersion = "1.1.2" }; _lockConfiguration = config.Bind<bool>("General", "LockConfiguration", true, "If enabled, gameplay configuration is controlled by the server/host through ServerSync."); _configSync.AddLockingConfigEntry<bool>(_lockConfiguration); _trainSpeedMultiplier = BindSynced(config, "Train", "TrainSpeedMultiplier", 1f, "Scales the powered cart's normal cruise/minimum speed. Temporary speed-rail boost limits remain separate.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f)); _maximumTrainSpeed = BindSynced(config, "Train", "MaximumTrainSpeed", 16f, "Maximum normal train speed before temporary speed-rail boost headroom is applied.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 64f)); _straightRunAcceleration = BindSynced(config, "Train", "StraightRunAcceleration", defaultValue: true, "Enables the existing straight-track acceleration bonus. Disabling it leaves base movement intact."); _slopeSpeedEffects = BindSynced(config, "Train", "SlopeSpeedEffects", defaultValue: true, "Enables uphill/downhill speed and momentum effects. Disabling it leaves base movement intact."); _speedRailMultiplier = BindSynced(config, "Speed Rails", "SpeedRailMultiplier", 1.75f, "Speed multiplier applied while the powered cart is on a speed rail.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 4f)); _autoCoupling = BindSynced(config, "Coupling", "AutoCoupling", defaultValue: true, "Enables automatic cart coupling after placement/manual repositioning. Manual coupling remains available when disabled."); _autoCoupleRadius = BindSynced(config, "Coupling", "AutoCoupleRadius", 0.35f, "Maximum coupler distance used by automatic coupling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f)); _enableRunDamage = BindSynced(config, "Train Damage", "EnableRunDamage", defaultValue: true, "Enables powered leading-cart collision damage while moving above the built-in threshold."); _runDamageMultiplier = BindSynced(config, "Train Damage", "RunDamageMultiplier", 1f, "Global multiplier applied after the existing speed/cart-count run-damage curve.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f)); _runKnockbackMultiplier = BindSynced(config, "Train Damage", "RunKnockbackMultiplier", 1f, "Global multiplier applied after the existing run-damage knockback curve.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f)); _minimumCargoOperationStopTime = BindSynced(config, "Cargo", "MinimumCargoOperationStopTime", 3, "Minimum stop duration, in seconds, enforced for unload/container-transfer operations.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60)); _unloaderSpeedMultiplier = BindSynced(config, "Cargo", "UnloaderSpeedMultiplier", 1f, "Scales item ejection cadence. Values above 1 are faster; values below 1 are slower.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f)); _signalMaximumRange = BindSynced(config, "Signals", "SignalMaximumRange", 50f, "Maximum configurable range for standard rail/cart signal emitters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 250f)); _presenceSignalMaximumRange = BindSynced(config, "Signals", "PresenceSignalMaximumRange", 50f, "Maximum configurable range for presence signal emitters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 250f)); _dayNightSignalMaximumRange = BindSynced(config, "Signals", "DayNightSignalMaximumRange", 100f, "Maximum configurable range for day/night signal emitters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f)); _maximumSignalDuration = BindSynced(config, "Signals", "MaximumSignalDuration", 120f, "Maximum configurable signal delay/uphold/event duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f)); _switchModifierKey = config.Bind<KeyCode>("Controls", "SwitchModifierKey", (KeyCode)304, "Client-only modifier used by powered-cart remote switch/bridge controls."); _cameraModifierKey = config.Bind<KeyCode>("Controls", "CameraModifierKey", (KeyCode)308, "Client-only modifier used to cycle the powered-cart driver camera."); _debugLogging = config.Bind<bool>("Debug", "EnableDebugLogging", false, "Client-only Rune Rails debug logging. Leave disabled for normal play."); _audioRoutingDebugLogging = config.Bind<bool>("Debug", "EnableAudioRoutingDebugLogging", false, "Client-only detailed AudioRoutingService logging. Leave disabled unless diagnosing audio routing."); _audioRoutingDebugLogging.SettingChanged += delegate { AudioRoutingService.DebugLogging = AudioRoutingDebugLoggingEnabled; }; IsInitialized = true; AudioRoutingService.DebugLogging = AudioRoutingDebugLoggingEnabled; } } private static ConfigEntry<T> BindSynced<T>(ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues = null) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ConfigDescription val = ((acceptableValues != null) ? new ConfigDescription(description, acceptableValues, Array.Empty<object>()) : new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); ConfigEntry<T> val2 = config.Bind<T>(section, key, defaultValue, val); SyncedConfigEntry<T> syncedConfigEntry = _configSync.AddConfigEntry<T>(val2); syncedConfigEntry.SynchronizedConfig = true; return val2; } public static float GetEffectiveSignalMaxRange(float authoredMax) { return IsInitialized ? SignalMaximumRange : Mathf.Max(1f, authoredMax); } public static float GetEffectivePresenceSignalMaxRange(float authoredMax) { return IsInitialized ? PresenceSignalMaximumRange : Mathf.Max(1f, authoredMax); } public static float GetEffectiveDayNightSignalMaxRange(float authoredMax) { return IsInitialized ? DayNightSignalMaximumRange : Mathf.Max(1f, authoredMax); } public static float GetEffectiveSignalMaxDuration(float authoredMax) { return IsInitialized ? MaximumSignalDuration : Mathf.Max(0f, authoredMax); } public static float ClampSignalDuration(float value, float minDuration, float authoredMaxDuration) { float num = Mathf.Max(0f, minDuration); float num2 = Mathf.Max(num, GetEffectiveSignalMaxDuration(authoredMaxDuration)); return Mathf.Clamp(value, num, num2); } private static float ReadFloat(ConfigEntry<float> entry, float fallback, float min, float max) { float num = entry?.Value ?? fallback; if (float.IsNaN(num) || float.IsInfinity(num)) { num = fallback; } return Mathf.Clamp(num, min, max); } } public class BalrondTranslator { public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>(); public static Dictionary<string, string> getLanguage(string language) { if (string.IsNullOrEmpty(language)) { return null; } if (translations.TryGetValue(language, out var value)) { return value; } return null; } } public static class BCSPrefabFind { public static T GetOrAdd<T>(GameObject prefab) where T : Component { T component = prefab.GetComponent<T>(); return ((Object)(object)component != (Object)null) ? component : prefab.AddComponent<T>(); } public static void DestroyIfExists(Object obj) { if (obj != (Object)null) { Object.DestroyImmediate(obj); } } public static Transform FindTransformDeep(GameObject prefab, string childName) { if ((Object)(object)prefab == (Object)null || string.IsNullOrEmpty(childName)) { return null; } Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == childName) { return componentsInChildren[i]; } } return null; } public static GameObject FindGameObjectDeep(GameObject prefab, string childName) { Transform val = FindTransformDeep(prefab, childName); return ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null; } public static void WarnIfMissing(Object obj, GameObject prefab, string name) { if (obj == (Object)null && (Object)(object)prefab != (Object)null) { Debug.LogWarning((object)("[BCS] Missing " + name + " on " + ((Object)prefab).name)); } } } [DisallowMultipleComponent] public class BuilderWorkstation : MonoBehaviour { public string[] m_supportedBuildStations = new string[6] { "$piece_workbench", "$piece_forge", "$piece_stonecutter", "$piece_artisanstation", "$tag_heavyworkbench_bal", "$tag_ironworks_bal" }; public bool Supports(string stationName) { if (string.IsNullOrEmpty(stationName)) { return false; } for (int i = 0; i < m_supportedBuildStations.Length; i++) { if (m_supportedBuildStations[i] == stationName) { return true; } } return false; } } [HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")] public static class BuilderWorkstation_HaveBuildStationInRange_Patch { private static void Postfix(string name, Vector3 point, ref CraftingStation __result) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__result != (Object)null)) { __result = BuilderWorkstationUtility.HaveBuildStationInRange(name, point); } } } [HarmonyPatch(typeof(CraftingStation), "FindClosestStationInRange")] public static class BuilderWorkstation_FindClosestStationInRange_Patch { private static void Postfix(string name, Vector3 point, float range, ref CraftingStation __result) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__result != (Object)null)) { __result = BuilderWorkstationUtility.FindClosestStationInRange(name, point, range); } } } [HarmonyPatch(typeof(CraftingStation), "FindStationsInRange")] public static class BuilderWorkstation_FindStationsInRange_Patch { private static void Postfix(string name, Vector3 point, float range, List<CraftingStation> stations) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) BuilderWorkstationUtility.FindStationsInRange(name, point, range, stations); } } public static class BuilderWorkstationUtility { public static CraftingStation HaveBuildStationInRange(string requiredStationName, Vector3 point) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) CraftingStation val = null; float num = 999999f; foreach (CraftingStation allStation in CraftingStation.m_allStations) { if (IsValidSupportedStation(allStation, requiredStationName)) { float stationBuildRange = allStation.GetStationBuildRange(); Vector3 val2 = point; val2.y = ((Component)allStation).transform.position.y; float num2 = Vector3.Distance(((Component)allStation).transform.position, val2); if (!(num2 >= stationBuildRange) && ((Object)(object)val == (Object)null || num2 < num)) { val = allStation; num = num2; } } } return val; } public static CraftingStation FindClosestStationInRange(string requiredStationName, Vector3 point, float range) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) CraftingStation val = null; float num = 999999f; foreach (CraftingStation allStation in CraftingStation.m_allStations) { if (IsValidSupportedStation(allStation, requiredStationName)) { float num2 = Vector3.Distance(((Component)allStation).transform.position, point); if (!(num2 >= range) && ((Object)(object)val == (Object)null || num2 < num)) { val = allStation; num = num2; } } } return val; } public static void FindStationsInRange(string requiredStationName, Vector3 point, float range, List<CraftingStation> stations) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (stations == null) { return; } foreach (CraftingStation allStation in CraftingStation.m_allStations) { if (IsValidSupportedStation(allStation, requiredStationName) && !(Vector3.Distance(((Component)allStation).transform.position, point) >= range) && !stations.Contains(allStation)) { stations.Add(allStation); } } } private static bool IsValidSupportedStation(CraftingStation station, string requiredStationName) { if ((Object)(object)station == (Object)null || string.IsNullOrEmpty(requiredStationName)) { return false; } BuilderWorkstation component = ((Component)station).GetComponent<BuilderWorkstation>(); if ((Object)(object)component == (Object)null) { return false; } return component.Supports(requiredStationName); } } internal class BuildPieceList { public static string[] buildPieces = new string[41] { "daycycleSignalEmitter_bal", "pressenceSignalEmitter_bal", "railtrackSignalEmitter_bal", "railSignalLiftGate_bal", "railSignalDoor_bal", "railtrackStop_bal", "railtrackLampReciver_bal", "railtrackControl_bal", "railtrackSignalStopReceiver_bal", "railtrackContainer_bal", "railtrackUnload_bal", "railtrackSpeed_bal", "railtrack_bal", "railtrack1m_bal", "railtrack4m_bal", "railtrack8m_bal", "railtrackRamp_bal", "railtrackRamp26short_bal", "railtrackRamp45_bal", "railtrackRamp45short_bal", "railtrackRamp64_bal", "railtrackCross_bal", "railtrackSwitchLeft_bal", "railtrackSwitchMid_bal", "railtrackSwitchRight_bal", "railtrackTurnRight15_bal", "railtrackTurnRight30_bal", "railtrackTurnRight45_bal", "railtrackTurnLeft15_bal", "railtrackTurnLeft30_bal", "railtrackTurnLeft45_bal", "railtrackJump4m_bal", "railtrackJump6m_bal", "railtrackJump8m_bal", "railtrackDrop8m_bal", "railtrackDrawbridge10m_bal", "RailPowerWagon_bal", "RailCargoWagon_bal", "RailTableWagon_bal", "RailPersonelWagon_bal", "piece_buildstation_bal" }; } public class BalrondDayCycleRotator : MonoBehaviour { public Transform m_target; public Vector3 m_rotationAxis = Vector3.up; public float m_angleOffset = 0f; public bool m_invert = false; public bool m_smoothRotation = true; public float m_smoothSpeed = 12f; private Quaternion _currentRotation; private bool _initialized; private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_target == (Object)null) { m_target = ((Component)this).transform; } if ((Object)(object)m_target != (Object)null) { _currentRotation = m_target.localRotation; } _initialized = true; } private void Update() { ApplyRotation(); } private void ApplyRotation() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)m_target == (Object)null) && !((Object)(object)EnvMan.instance == (Object)null)) { float dayFraction = EnvMan.instance.GetDayFraction(); float num = dayFraction * 360f; if (m_invert) { num = 0f - num; } num += m_angleOffset; Quaternion val = Quaternion.AngleAxis(num, GetSafeAxis(m_rotationAxis)); if (!_initialized || !m_smoothRotation) { _currentRotation = val; } else { _currentRotation = Quaternion.Slerp(_currentRotation, val, Time.deltaTime * Mathf.Max(0.01f, m_smoothSpeed)); } m_target.localRotation = _currentRotation; } } private static Vector3 GetSafeAxis(Vector3 axis) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref axis)).sqrMagnitude <= 0.0001f) { return Vector3.right; } return ((Vector3)(ref axis)).normalized; } } public static class BCSContainerInitUtility { public static bool EnsureInitialized(Container container, ZNetView rootOverride) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown if ((Object)(object)container == (Object)null) { return false; } if ((Object)(object)rootOverride != (Object)null) { container.m_rootObjectOverride = rootOverride; } ZNetView val = (((Object)(object)container.m_rootObjectOverride != (Object)null) ? ((Component)container.m_rootObjectOverride).GetComponent<ZNetView>() : ((Component)container).GetComponent<ZNetView>()); if ((Object)(object)val == (Object)null || !val.IsValid() || val.GetZDO() == null) { return false; } container.m_nview = val; if ((Object)(object)container.m_piece == (Object)null) { container.m_piece = (((Object)(object)container.m_rootObjectOverride != (Object)null) ? ((Component)container.m_rootObjectOverride).GetComponent<Piece>() : ((Component)container).GetComponent<Piece>()); } if (container.m_inventory == null) { container.m_inventory = new Inventory(container.m_name, container.m_bkg, container.m_width, container.m_height); Inventory inventory = container.m_inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(container.OnContainerChanged)); } container.Load(); container.UpdateUseVisual(); return container.m_inventory != null; } public static bool EnsureInitialized(Container container) { return EnsureInitialized(container, null); } } public class BCSDebugRegistryReporter : MonoBehaviour { public bool m_enableLogs = true; public float m_interval = 30f; private float _nextLogTime; private void Update() { if (m_enableLogs && !(Time.time < _nextLogTime)) { _nextLogTime = Time.time + Mathf.Max(5f, m_interval); Debug.Log((object)("[BCS Registry Debug] carts=" + BCSCartRegistry.GetCartCount() + " rawCarts=" + BCSCartRegistry.GetRawCartCount() + " rails=" + BCSRailRegistry.GetRailCount() + " rawRails=" + BCSRailRegistry.GetRawRailCount() + " signalEmitters=" + BCSSignalRegistry.GetEmitterCount() + " presenceEmitters=" + BCSSignalRegistry.GetPresenceEmitterCount() + " signalReceivers=" + BCSSignalRegistry.GetReceiverCount())); } } } public class BCSCargoCartAppearanceSelector : MonoBehaviour, Hoverable, Interactable { private const string RpcSetVariant = "RPC_SetCargoAppearanceVariant"; private const string ZdoVariant = "BCS_CargoAppearanceVariant"; public string m_name = "Cargo Wagon Appearance"; [Header("States")] public string m_statesRootName = "container_states"; [Header("Debug")] public bool m_debugLogs = false; private ZNetView _nview; private Transform _statesRoot; private readonly List<GameObject> _states = new List<GameObject>(); private int _lastAppliedVariant = -999; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { ((Behaviour)this).enabled = false; return; } _nview.Register<int>("RPC_SetCargoAppearanceVariant", (Action<long, int>)RPC_SetVariant); CacheStates(); ApplyCurrentVariant(); } private void Start() { CacheStates(); ApplyCurrentVariant(); } private void Update() { int variantIndex = GetVariantIndex(); if (variantIndex != _lastAppliedVariant) { ApplyVariant(variantIndex); } } private void CacheStates() { _states.Clear(); _statesRoot = null; Transform val = ((Component)this).transform.Find(m_statesRootName); if ((Object)(object)val == (Object)null) { val = FindTransformDeep(((Component)this).transform, m_statesRootName); } if ((Object)(object)val == (Object)null) { val = ((Component)this).transform.Find("states"); } if ((Object)(object)val == (Object)null) { val = ((Component)this).transform.Find("States"); } _statesRoot = val; if ((Object)(object)_statesRoot == (Object)null) { Log("CacheStates: states root missing"); return; } for (int i = 0; i < _statesRoot.childCount; i++) { Transform child = _statesRoot.GetChild(i); if ((Object)(object)child != (Object)null) { _states.Add(((Component)child).gameObject); } } Log("CacheStates count=" + _states.Count); } public string GetHoverName() { return m_name; } public float GetHoverOffset() { return 0f; } public string GetHoverText() { StringBuilder stringBuilder = new StringBuilder(128); stringBuilder.Append(m_name); stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] Variant: "); stringBuilder.Append(GetVariantName(GetVariantIndex())); return (Localization.instance != null) ? Localization.instance.Localize(stringBuilder.ToString()) : stringBuilder.ToString(); } public bool Interact(Humanoid human, bool hold, bool alt) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (hold) { return false; } Player val = (Player)(object)((human is Player) ? human : null); if ((Object)(object)val == (Object)null) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } SetVariant(GetNextVariantIndex()); ((Character)val).Message((MessageType)2, "Cargo variant: " + GetVariantName(GetNextPreviewVariantIndex()), 0, (Sprite)null, false); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private void SetVariant(int index) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { if (!_nview.HasOwner()) { _nview.ClaimOwnership(); } _nview.InvokeRPC("RPC_SetCargoAppearanceVariant", new object[1] { ClampVariantIndex(index) }); } } private void RPC_SetVariant(long sender, int value) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner()) { int num = ClampVariantIndex(value); _nview.GetZDO().Set("BCS_CargoAppearanceVariant", num); ApplyVariant(num); } } private void ApplyCurrentVariant() { ApplyVariant(GetVariantIndex()); } private void ApplyVariant(int index) { if (_states.Count == 0) { CacheStates(); } int num = (_lastAppliedVariant = ClampVariantIndex(index)); for (int i = 0; i < _states.Count; i++) { GameObject val = _states[i]; if ((Object)(object)val != (Object)null) { val.SetActive(i == num); } } } public int GetVariantIndex() { if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.GetZDO() != null) { return ClampVariantIndex(_nview.GetZDO().GetInt("BCS_CargoAppearanceVariant", 0)); } return 0; } private int GetNextVariantIndex() { return GetNextVariantIndex(GetVariantIndex()); } private int GetNextPreviewVariantIndex() { return GetNextVariantIndex(GetVariantIndex()); } private int GetNextVariantIndex(int current) { if (_states.Count == 0) { CacheStates(); } if (_states.Count <= 0) { return 0; } return (ClampVariantIndex(current) + 1) % _states.Count; } private int ClampVariantIndex(int value) { if (_states.Count == 0) { CacheStates(); } if (_states.Count <= 0) { return 0; } return Mathf.Clamp(value, 0, _states.Count - 1); } private string GetVariantName(int index) { if (_states.Count == 0) { CacheStates(); } int num = ClampVariantIndex(index); if (num < 0 || num >= _states.Count || (Object)(object)_states[num] == (Object)null) { return "<none>"; } return ((Object)_states[num]).name; } private static Transform FindTransformDeep(Transform root, string childName) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(childName)) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == childName) { return componentsInChildren[i]; } } return null; } private void Log(string msg) { if (m_debugLogs) { Debug.Log((object)("[BCSCargoCartAppearanceSelector][" + ((Object)((Component)this).gameObject).name + "] " + msg)); } } } public class BCSCartCraftingStation : MonoBehaviour { [Header("Cart Crafting Station")] public bool m_useCartZNetView = true; public bool m_disableRoofRequirement = true; public bool m_disableFireRequirement = true; } public static class BCSCartPrefabConfigurator { public static void Configure(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { Debug.LogWarning((object)"[BCS] ConfigureTrainCart: prefab == null"); return; } BCSCartRoot orAdd = BCSPrefabFind.GetOrAdd<BCSCartRoot>(prefab); BCSPrefabFind.GetOrAdd<BCSCartRailPlacementSnap>(prefab); Smelter val = prefab.GetComponent<Smelter>(); if ((Object)(object)val == (Object)null) { val = prefab.GetComponentInChildren<Smelter>(true); } StationExtension val2 = prefab.GetComponent<StationExtension>(); if ((Object)(object)val2 == (Object)null) { val2 = prefab.GetComponentInChildren<StationExtension>(true); } Fermenter val3 = prefab.GetComponent<Fermenter>(); if ((Object)(object)val3 == (Object)null) { val3 = prefab.GetComponentInChildren<Fermenter>(true); } ZNetView component = prefab.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[BCS] ConfigureTrainCart: Smelter missing on " + ((Object)prefab).name)); CleanupVanillaReferenceComponents(prefab); return; } ConfigureCartBase(orAdd, val, val2); ConfigureCartWheels(orAdd, val); ConfigureCartSensorCollider(prefab); if ((Object)(object)val3 != (Object)null) { orAdd.m_haltingStartEffects = val3.m_tapEffects; } switch (((Object)prefab).name) { case "RailPowerWagon_bal": ConfigurePoweredCart(prefab, orAdd, val, val3); break; case "RailCargoWagon_bal": ConfigureCargoCart(prefab, orAdd, val, component); break; case "RailTableWagon_bal": ConfigureUtilityWorkbenchCart(prefab, orAdd, val, component); break; case "RailPersonelWagon_bal": ConfigurePassengerCart(prefab, orAdd); break; default: Debug.LogWarning((object)("[BCS] ConfigureTrainCart: unknown cart prefab: " + ((Object)prefab).name)); break; } CleanupVanillaReferenceComponents(prefab); } private static void ConfigureCartBase(BCSCartRoot cart, Smelter smelter, StationExtension stationExtension) { cart.m_backCouplerPoint = (((Object)(object)smelter.m_addOreSwitch != (Object)null) ? ((Component)smelter.m_addOreSwitch).transform : null); cart.m_backCouplerSwitch = smelter.m_addOreSwitch; cart.m_frontCouplerPoint = (((Object)(object)smelter.m_addWoodSwitch != (Object)null) ? ((Component)smelter.m_addWoodSwitch).transform : null); cart.m_frontCouplerSwitch = smelter.m_addWoodSwitch; cart.m_frontPosePoint = smelter.m_outputPoint; cart.m_backPosePoint = smelter.m_roofCheckPoint; cart.m_isMovingObject = smelter.m_haveFuelObject; cart.m_isHaltingObject = smelter.m_noOreObject; cart.m_moveStartEffects = smelter.m_oreAddedEffects; cart.m_moveStopEffects = smelter.m_fuelAddedEffects; cart.m_jumpLaunchRiderEffects = smelter.m_produceEffects; cart.m_jumpLandRiderEffects = smelter.m_produceEffects; cart.m_connectionPrefab = (((Object)(object)stationExtension != (Object)null) ? stationExtension.m_connectionPrefab : null); cart.m_allowRuntimeAdditions = true; } private static void ConfigureCartWheels(BCSCartRoot cart, Smelter smelter) { if ((Object)(object)cart == (Object)null || (Object)(object)smelter == (Object)null || smelter.m_animators == null || smelter.m_animators.Length < 2) { Debug.LogWarning((object)"[BCS] ConfigureCartWheels: missing wheel animators"); return; } GameObject val = (((Object)(object)smelter.m_animators[0] != (Object)null) ? ((Component)smelter.m_animators[0]).gameObject : null); GameObject val2 = (((Object)(object)smelter.m_animators[1] != (Object)null) ? ((Component)smelter.m_animators[1]).gameObject : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Debug.LogWarning((object)"[BCS] ConfigureCartWheels: wheel object missing"); return; } BCSPrefabFind.DestroyIfExists((Object)(object)val.GetComponent<Animator>()); BCSPrefabFind.DestroyIfExists((Object)(object)val2.GetComponent<Animator>()); cart.m_wheelAnimators = (Transform[])(object)new Transform[2] { val.transform, val2.transform }; } private static void ConfigurePoweredCart(GameObject prefab, BCSCartRoot cart, Smelter smelter, Fermenter fermenter) { cart.m_cartType = BCSCartType.Powered; cart.m_engineSwitch = smelter.m_emptyOreSwitch; cart.m_seatObject = smelter.m_haveOreObject; cart.m_chair = (((Object)(object)smelter.m_haveOreObject != (Object)null) ? smelter.m_haveOreObject.GetComponent<Chair>() : null); cart.m_containerObject = smelter.m_disabledObject; cart.m_container = (((Object)(object)smelter.m_disabledObject != (Object)null) ? smelter.m_disabledObject.GetComponent<Container>() : null); cart.m_powerEnabledObject = smelter.m_enabledObject; cart.m_powerDisabledObject = smelter.m_disabledObject; BCSTrainRuntime orAdd = BCSPrefabFind.GetOrAdd<BCSTrainRuntime>(prefab); ConfigurePoweredRuntime(orAdd, cart); BCSCartRunDamage orAdd2 = BCSPrefabFind.GetOrAdd<BCSCartRunDamage>(prefab); ConfigureRunDamage(prefab, cart, orAdd, orAdd2); BCSPowerCartControls orAdd3 = BCSPrefabFind.GetOrAdd<BCSPowerCartControls>(prefab); ConfigurePowerCartControls(orAdd3, cart, orAdd, fermenter); ConfigureMovingChair(cart.m_chair, 2f); } private static void ConfigurePoweredRuntime(BCSTrainRuntime runtime, BCSCartRoot cart) { runtime.m_engineRoot = cart; runtime.m_baseSpeed = 8f; runtime.m_currentSpeed = 8f; runtime.m_minSpeed = 4f; runtime.m_maxSpeed = 16f; runtime.m_speedChangeRate = 2f; runtime.m_useStraightRunAcceleration = true; runtime.m_straightRunRequiredMeters = 4f; runtime.m_straightRunBonusPerMeter = 0.35f; runtime.m_maxStraightRunBonus = 4f; runtime.m_straightRunResetRate = 8f; runtime.m_straightDirectionDotThreshold = 0.985f; runtime.m_useSlopeSpeed = true; runtime.m_slopeSampleDistance = 0.25f; runtime.m_uphillSlowdownFactor = 1.2f; runtime.m_downhillBoostFactor = 1f; runtime.m_maxUphillNormalized = 0.3f; runtime.m_maxDownhillNormalized = 0.3f; runtime.m_minSpeedMultiplierUphill = 0.8f; runtime.m_maxSpeedMultiplierDownhill = 1.5f; runtime.m_useSlopeMomentum = true; runtime.m_slopeMomentumBuildRate = 1.35f; runtime.m_slopeMomentumDecayRate = 0.55f; runtime.m_maxSlopeMomentum = 1.5f; runtime.m_slopeMomentumSpeedInfluence = 1f; runtime.m_slopeMomentumDeadzone = 0.01f; runtime.m_useSoftStopBraking = true; runtime.m_softStopBrakeStartDistance = 1.25f; runtime.m_softStopMinApproachSpeed = 0.2f; runtime.m_softStopBrakeExponent = 1.5f; } private static void ConfigureRunDamage(GameObject prefab, BCSCartRoot cart, BCSTrainRuntime runtime, BCSCartRunDamage runDamage) { runDamage.m_cart = cart; runDamage.m_runtime = runtime; Transform val = prefab.transform.Find("RunHitDamage"); runDamage.m_runDamageObject = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); runDamage.m_runDamageObjectName = "RunHitDamage"; runDamage.m_attachToLeadingCoupler = true; runDamage.m_speedThreshold = 6f; runDamage.m_fullDamageSpeed = 16f; runDamage.m_minDamageMultiplierAtThreshold = 0.75f; runDamage.m_maxDamageMultiplierAtFullSpeed = 2f; runDamage.m_extraDamageMultiplierPerAttachedCart = 0.25f; runDamage.m_maxAttachedCartDamageBonus = 1f; runDamage.m_minForceMultiplierAtThreshold = 1f; runDamage.m_maxForceMultiplierAtFullSpeed = 3f; runDamage.m_extraForceMultiplierPerAttachedCart = 0.35f; runDamage.m_maxAttachedCartForceBonus = 1.5f; if ((Object)(object)runDamage.m_runDamageObject == (Object)null) { Debug.LogWarning((object)("[BCS] ConfigurePoweredCart: RunHitDamage object missing on " + ((Object)prefab).name)); } } private static void ConfigurePowerCartControls(BCSPowerCartControls controls, BCSCartRoot cart, BCSTrainRuntime runtime, Fermenter fermenter) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) controls.m_cart = cart; controls.m_runtime = runtime; controls.m_modifierSwitch = (KeyCode)304; controls.m_modifierCamera = (KeyCode)308; controls.m_switchSearchRadius = 5f; if ((Object)(object)fermenter != (Object)null) { controls.m_switchToggleEffects = fermenter.m_spawnEffects; } } private static void ConfigureCargoCart(GameObject prefab, BCSCartRoot cart, Smelter smelter, ZNetView rootNview) { cart.m_cartType = BCSCartType.Cargo; cart.m_engineSwitch = null; cart.m_powerEnabledObject = null; cart.m_powerDisabledObject = null; cart.m_seatObject = null; cart.m_chair = null; cart.m_containerObject = smelter.m_enabledObject; cart.m_container = (((Object)(object)smelter.m_enabledObject != (Object)null) ? smelter.m_enabledObject.GetComponent<Container>() : null); if ((Object)(object)cart.m_container != (Object)null && (Object)(object)rootNview != (Object)null) { cart.m_container.m_rootObjectOverride = rootNview; } BCSCargoCartAppearanceSelector orAdd = BCSPrefabFind.GetOrAdd<BCSCargoCartAppearanceSelector>(prefab); orAdd.m_name = "Cargo Wagon Appearance"; orAdd.m_statesRootName = "container_states"; RemoveNonPoweredRuntime(prefab); } private static void ConfigureUtilityWorkbenchCart(GameObject prefab, BCSCartRoot cart, Smelter smelter, ZNetView rootNview) { cart.m_cartType = BCSCartType.Utility; cart.m_engineSwitch = null; cart.m_powerEnabledObject = null; cart.m_powerDisabledObject = null; cart.m_seatObject = null; cart.m_chair = null; cart.m_containerObject = smelter.m_enabledObject; cart.m_container = (((Object)(object)smelter.m_enabledObject != (Object)null) ? smelter.m_enabledObject.GetComponent<Container>() : null); if ((Object)(object)cart.m_container != (Object)null && (Object)(object)rootNview != (Object)null) { cart.m_container.m_rootObjectOverride = rootNview; } CraftingStation componentInChildren = prefab.GetComponentInChildren<CraftingStation>(true); if ((Object)(object)componentInChildren != (Object)null) { BCSCartCraftingStation bCSCartCraftingStation = ((Component)componentInChildren).GetComponent<BCSCartCraftingStation>(); if ((Object)(object)bCSCartCraftingStation == (Object)null) { bCSCartCraftingStation = ((Component)componentInChildren).gameObject.AddComponent<BCSCartCraftingStation>(); } bCSCartCraftingStation.m_useCartZNetView = true; bCSCartCraftingStation.m_disableRoofRequirement = true; bCSCartCraftingStation.m_disableFireRequirement = true; componentInChildren.m_craftRequireRoof = false; componentInChildren.m_craftRequireFire = false; } else { Debug.LogWarning((object)("[BCS] ConfigureUtilityWorkbenchCart: CraftingStation missing on " + ((Object)prefab).name)); } RemoveNonPoweredRuntime(prefab); } private static void ConfigurePassengerCart(GameObject prefab, BCSCartRoot cart) { cart.m_cartType = BCSCartType.Passenger; cart.m_engineSwitch = null; cart.m_powerEnabledObject = null; cart.m_powerDisabledObject = null; cart.m_containerObject = null; cart.m_container = null; Chair[] componentsInChildren = prefab.GetComponentsInChildren<Chair>(true); cart.m_chair = ((componentsInChildren != null && componentsInChildren.Length != 0) ? componentsInChildren[0] : null); cart.m_seatObject = (((Object)(object)cart.m_chair != (Object)null) ? ((Component)cart.m_chair).gameObject : null); if (componentsInChildren != null) { for (int i = 0; i < componentsInChildren.Length; i++) { ConfigureMovingChair(componentsInChildren[i], 2f); } } RemoveNonPoweredRuntime(prefab); if (componentsInChildren == null || componentsInChildren.Length == 0) { Debug.LogWarning((object)("[BCS] ConfigurePassengerCart: no Chair components found on " + ((Object)prefab).name)); } } private static void ConfigureMovingChair(Chair chair, float useDistance) { if (!((Object)(object)chair == (Object)null)) { if ((Object)(object)chair.m_attachPoint == (Object)null) { chair.m_attachPoint = ((Component)chair).transform; } chair.m_inShip = true; chair.m_attachAnimation = "emote_sit"; chair.m_useDistance = useDistance; } } private static void RemoveNonPoweredRuntime(GameObject prefab) { BCSPrefabFind.DestroyIfExists((Object)(object)prefab.GetComponent<BCSTrainRuntime>()); BCSPrefabFind.DestroyIfExists((Object)(object)prefab.GetComponent<BCSPowerCartControls>()); BCSPrefabFind.DestroyIfExists((Object)(object)prefab.GetComponent<BCSCartRunDamage>()); } private static void ConfigureCartSensorCollider(GameObject prefab) { Transform val = prefab.transform.Find("CartSensorCollider"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[BCS] ConfigureCartSensorCollider: CartSensorCollider missing on " + ((Object)prefab).name)); return; } GameObject gameObject = ((Component)val).gameObject; int num = LayerMask.NameToLayer("character_noenv"); if (num >= 0) { gameObject.layer = num; } else { Debug.LogWarning((object)("[BCS] ConfigureCartSensorCollider: layer character_noenv missing on " + ((Object)prefab).name)); } Collider component = gameObject.GetComponent<Collider>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)("[BCS] ConfigureCartSensorCollider: Collider missing on " + ((Object)prefab).name)); return; } component.isTrigger = true; DisableInPlacementGhost component2 = gameObject.GetComponent<DisableInPlacementGhost>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } } private static void CleanupVanillaReferenceComponents(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { DestroyComponentsInChildren<StationExtension>(prefab); DestroyComponentsInChildren<Smelter>(prefab); DestroyComponentsInChildren<Fermenter>(prefab); } } private static void DestroyComponentsInChildren<T>(GameObject prefab) where T : Component { if ((Object)(object)prefab == (Object)null) { return; } T[] componentsInChildren = prefab.GetComponentsInChildren<T>(true); if (componentsInChildren == null) { return; } for (int num = componentsInChildren.Length - 1; num >= 0; num--) { T val = componentsInChildren[num]; if (!((Object)(object)val == (Object)null)) { Object.DestroyImmediate((Object)(object)val); } } } } public class BCSDrawbridgeRail : MonoBehaviour { private const string RpcToggleDrawbridge = "RPC_ToggleDrawbridge"; private readonly List<BCSCartRoot> _cartScanScratch = new List<BCSCartRoot>(64); private ZNetView _nview; private BCSRailPiece _rail; private AudioSource[] _animationAudioSources; private bool _lastAnimationAudioActive; private bool _animationAudioInitialized; [Header("Drawbridge")] public bool m_enabled = true; public float m_stopMargin = 1f; public float m_animationSeconds = 3f; public float m_raisedAngle = 75f; public float m_extraStopOffset = 1.5f; [Header("Bridge Leaves")] public Transform m_leftPivotC; public Transform m_rightPivotD; [Header("Gears")] public Transform m_gearCStatic; public Transform m_gearCBridge; public Transform m_gearDStatic; public Transform m_gearDBridge; public float m_gearDegreesPerBridgeDegree = 4f; [Header("Rotation Axis")] public Vector3 m_leftLeafAxis = Vector3.right; public Vector3 m_rightLeafAxis = Vector3.right; public Vector3 m_gearAxis = Vector3.right; [Header("Animation Audio")] public GameObject m_animationActiveObject; [Header("Effects")] public EffectList m_openStartEffects = new EffectList(); public EffectList m_closeStartEffects = new EffectList(); [Header("Debug")] public bool m_debugLogs = false; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _rail = ((Component)this).GetComponent<BCSRailPiece>(); CacheAnimationAudioSources(); if ((Object)(object)_nview != (Object)null) { _nview.Register("RPC_ToggleDrawbridge", (Action<long>)RPC_ToggleDrawbridge); } UpdateAnimationActiveObject(GetState()); } private void Update() { UpdateAnimationAndState(); } public bool IsDrawbridgeRail() { return m_enabled && (Object)(object)_rail != (Object)null && _rail.m_pieceType == BCSRailPieceType.Drawbridge; } private void CacheAnimationAudioSources() { _animationAudioSources = (AudioSource[])(((Object)(object)m_animationActiveObject != (Object)null) ? ((Array)m_animationActiveObject.GetComponentsInChildren<AudioSource>(true)) : ((Array)new AudioSource[0])); } public bool IsPassableForTrain() { return GetState() == BCSDrawbridgeState.Lowered; } public bool IsBlockedForTrain() { return !IsPassableForTrain(); } public bool IsAnimating() { BCSDrawbridgeState state = GetState(); return state == BCSDrawbridgeState.Raising || state == BCSDrawbridgeState.Lowering; } public BCSDrawbridgeState GetState() { ZDO zdo = GetZdo(); if (zdo == null) { return BCSDrawbridgeState.Lowered; } return zdo.GetInt("hl_rail_drawbridge_state", 0) switch { 1 => BCSDrawbridgeState.Raising, 2 => BCSDrawbridgeState.Raised, 3 => BCSDrawbridgeState.Lowering, _ => BCSDrawbridgeState.Lowered, }; } public bool TryGetStopDistance(bool travelReversed, out float stopDistance) { stopDistance = 0f; if (!IsDrawbridgeRail()) { return false; } if (IsPassableForTrain()) { return false; } float length = _rail.GetLength(); if (length <= 0.001f) { return false; } float safeStopMargin = GetSafeStopMargin(length); float num = Mathf.Max(0f, BCSCommonUtility.SanitizeFloat(m_extraStopOffset, 1.5f)); float num2 = Mathf.Clamp(safeStopMargin - num, 0.05f, length - 0.05f); float num3 = Mathf.Clamp(length - safeStopMargin + num, 0.05f, length - 0.05f); stopDistance = (travelReversed ? num3 : num2); return true; } public bool IsDistanceOnBridgeSpan(float distance) { if ((Object)(object)_rail == (Object)null) { return false; } float length = _rail.GetLength(); if (length <= 0.001f) { return false; } float safeStopMargin = GetSafeStopMargin(length); float num = BCSCommonUtility.SanitizeFloat(distance, 0f); return num > safeStopMargin && num < length - safeStopMargin; } public bool IsBridgeSpanOccupied() { if ((Object)(object)_rail == (Object)null) { return false; } string railId = _rail.GetRailId(); if (string.IsNullOrEmpty(railId)) { return false; } BCSCartRegistry.FillAll(_cartScanScratch); for (int i = 0; i < _cartScanScratch.Count; i++) { BCSCartRoot bCSCartRoot = _cartScanScratch[i]; if (!((Object)(object)bCSCartRoot == (Object)null) && !(bCSCartRoot.GetCurrentRailId() != railId) && IsDistanceOnBridgeSpan(bCSCartRoot.GetDistanceOnRail())) { return true; } } return false; } private void RPC_ToggleDrawbridge(long sender) { if (!IsDrawbridgeRail()) { return; } if (IsBridgeSpanOccupied()) { Log("Toggle rejected: train is on bridge"); return; } if (IsAnimating()) { Log("Toggle rejected: bridge is already moving"); return; } ClaimOwnershipIfNeeded(); switch (GetState()) { case BCSDrawbridgeState.Lowered: SetStateOwned(BCSDrawbridgeState.Raising); CreateEffects(m_openStartEffects); Log("Drawbridge raising"); break; case BCSDrawbridgeState.Raised: SetStateOwned(BCSDrawbridgeState.Lowering); CreateEffects(m_closeStartEffects); Log("Drawbridge lowering"); break; } } private void SetStateOwned(BCSDrawbridgeState state) { ZDO zdo = GetZdo(); if (zdo != null) { ClaimOwnershipIfNeeded(); zdo.Set("hl_rail_drawbridge_state", (int)state); zdo.Set("hl_rail_drawbridge_anim_start_time", BCSCommonUtility.GetNetworkTimeSecondsFloat()); } } private void SetStateNoRestartOwned(BCSDrawbridgeState state) { ZDO zdo = GetZdo(); if (zdo != null) { ClaimOwnershipIfNeeded(); zdo.Set("hl_rail_drawbridge_state", (int)state); } } private void UpdateAnimationAndState() { if (!IsDrawbridgeRail()) { return; } BCSDrawbridgeState state = GetState(); float num = Mathf.Max(0.01f, BCSCommonUtility.SanitizeFloat(m_animationSeconds, 3f)); float animStartTime = GetAnimStartTime(); float networkTimeSecondsFloat = BCSCommonUtility.GetNetworkTimeSecondsFloat(); float num2 = Mathf.Clamp01((networkTimeSecondsFloat - animStartTime) / num); float progress = 0f; switch (state) { case BCSDrawbridgeState.Lowered: progress = 0f; break; case BCSDrawbridgeState.Raised: progress = 1f; break; case BCSDrawbridgeState.Raising: progress = num2; if (num2 >= 1f && IsOwner()) { SetStateNoRestartOwned(BCSDrawbridgeState.Raised); } break; case BCSDrawbridgeState.Lowering: progress = 1f - num2; if (num2 >= 1f && IsOwner()) { SetStateNoRestartOwned(BCSDrawbridgeState.Lowered); } break; } UpdateAnimationActiveObject(state); ApplyVisual(progress); } private void ApplyVisual(float progress) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(progress); float num2 = num * BCSCommonUtility.SanitizeFloat(m_raisedAngle, 75f); if ((Object)(object)m_leftPivotC != (Object)null) { Vector3 safeAxis = GetSafeAxis(m_leftLeafAxis, Vector3.right); m_leftPivotC.localRotation = Quaternion.AngleAxis(num2, safeAxis); } if ((Object)(object)m_rightPivotD != (Object)null) { Vector3 safeAxis2 = GetSafeAxis(m_rightLeafAxis, Vector3.right); m_rightPivotD.localRotation = Quaternion.AngleAxis(0f - num2, safeAxis2); } float num3 = num2 * BCSCommonUtility.SanitizeFloat(m_gearDegreesPerBridgeDegree, 4f); ApplyGear(m_gearCStatic, 0f - num3); ApplyGear(m_gearCBridge, num3); ApplyGear(m_gearDStatic, num3); ApplyGear(m_gearDBridge, 0f - num3); } private void UpdateAnimationActiveObject(BCSDrawbridgeState state) { bool flag = state == BCSDrawbridgeState.Raising || state == BCSDrawbridgeState.Lowering; if (_animationAudioInitialized && _lastAnimationAudioActive == flag) { return; } _animationAudioInitialized = true; _lastAnimationAudioActive = flag; if ((Object)(object)m_animationActiveObject != (Object)null && m_animationActiveObject.activeSelf != flag) { m_animationActiveObject.SetActive(flag); } if (_animationAudioSources == null) { CacheAnimationAudioSources(); } for (int i = 0; i < _animationAudioSources.Length; i++) { AudioSource val = _animationAudioSources[i]; if ((Object)(object)val == (Object)null) { continue; } val.loop = true; if (flag) { if (!val.isPlaying) { val.Play(); } continue; } if (val.isPlaying) { val.Stop(); } val.time = 0f; } } private Transform GetGearRotationPivot(Transform gearRoot) { if ((Object)(object)gearRoot == (Object)null) { return null; } if (((Object)gearRoot).name == "gear-pivot") { return gearRoot; } Transform val = gearRoot.Find("gear-pivot"); if ((Object)(object)val != (Object)null) { return val; } Transform[] componentsInChildren = ((Component)gearRoot).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "gear-pivot") { return val2; } } return gearRoot; } private void CreateEffects(EffectList effects) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (effects != null && effects.m_effectPrefabs != null && effects.m_effectPrefabs.Length != 0) { effects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } private void ApplyGear(Transform gearRoot, float angle) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Transform gearRotationPivot = GetGearRotationPivot(gearRoot); if (!((Object)(object)gearRotationPivot == (Object)null)) { Vector3 safeAxis = GetSafeAxis(m_gearAxis, Vector3.right); gearRotationPivot.localRotation = Quaternion.AngleAxis(angle, safeAxis); } } private float GetSafeStopMargin(float length) { float num = Mathf.Max(0.001f, BCSCommonUtility.SanitizeFloat(length, 0f)); return Mathf.Clamp(BCSCommonUtility.SanitizeFloat(m_stopMargin, 1f), 0.05f, Mathf.Max(0.05f, num * 0.45f)); } private Vector3 GetSafeAxis(Vector3 axis, Vector3 fallback) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref axis)).sqrMagnitude <= 0.0001f) { return ((Vector3)(ref fallback)).normalized; } return ((Vector3)(ref axis)).normalized; } private float GetAnimStartTime() { ZDO zdo = GetZdo(); if (zdo == null) { return BCSCommonUtility.GetNetworkTimeSecondsFloat(); } return zdo.GetFloat("hl_rail_drawbridge_anim_start_time", BCSCommonUtility.GetNetworkTimeSecondsFloat()); } public bool RequestManualToggle(Player player) { if ((Object)(object)player == (Object)null || !IsDrawbridgeRail()) { return false; } if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } if (IsBridgeSpanOccupied()) { ((Character)player).Message((MessageType)2, "Train is on bridge", 0, (Sprite)null, false); return true; } if (IsAnimating()) { ((Character)player).Message((MessageType)2, "Bridge is moving", 0, (Sprite)null, false); return true; } _nview.InvokeRPC("RPC_ToggleDrawbridge", Array.Empty<object>()); return true; } private ZDO GetZdo() { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return null; } return _nview.GetZDO(); } private bool IsOwner() { return (Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner(); } private void ClaimOwnershipIfNeeded() { if ((Object)(object)_nview != (Object)null && _nview.IsValid() && !_nview.IsOwner()) { _nview.ClaimOwnership(); } } public bool RequestSignalState(BCSDrawbridgeSignalState targetState) { if (!IsDrawbridgeRail()) { return false; } if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } if (IsBridgeSpanOccupied()) { Log("Signal state rejected: train is on bridge"); return false; } if (IsAnimating()) { Log("Signal state rejected: bridge is already moving"); return false; } ClaimOwnershipIfNeeded(); BCSDrawbridgeState state = GetState(); if (targetState == BCSDrawbridgeSignalState.Lowered) { switch (state) { case BCSDrawbridgeState.Lowered: return true; case BCSDrawbridgeState.Raised: SetStateOwned(BCSDrawbridgeState.Lowering); CreateEffects(m_closeStartEffects); Log("Signal lowering drawbridge"); return true; default: return false; } } switch (state) { case BCSDrawbridgeState.Raised: return true; case BCSDrawbridgeState.Lowered: SetStateOwned(BCSDrawbridgeState.Raising); CreateEffects(m_openStartEffects); Log("Signal raising drawbridge"); return true; default: return false; } } public bool TryInteract(Player player) { return RequestManualToggle(player); } public bool TryGetStopDistanceFromCurrentDistance(float currentDistance, out float stopDistance) { stopDistance = 0f; if (!IsDrawbridgeRail()) { return false; } if (IsPassableForTrain()) { return false; } float length = _rail.GetLength(); if (length <= 0.001f) { return false; } float safeStopMargin = GetSafeStopMargin(length); float num = Mathf.Max(0f, BCSCommonUtility.SanitizeFloat(m_extraStopOffset, 1.5f)); float num2 = Mathf.Clamp(safeStopMargin - num, 0.05f, length - 0.05f); float num3 = Mathf.Clamp(length - safeStopMargin + num, 0.05f, length - 0.05f); float num4 = Mathf.Clamp(BCSCommonUtility.SanitizeFloat(currentDistance, 0f), 0f, length); bool flag = num4 > length * 0.5f; stopDistance = (flag ? num3 : num2); return true; } private void Log(string msg) { if (m_debugLogs) { Debug.Log((object)("[BCSDrawbridgeRail][" + ((Object)((Component)this).gameObject).name + "] " + msg)); } } } public static class BCSPrefabConfigurator { public static void ConfigureTrainCart(GameObject prefab) { BCSCartPrefabConfigurator.Configure(prefab); } public static void ConfigureRail(GameObject prefab) { BCSRailPrefabConfigurator.Configure(prefab); } public static void ConfigureSignalPiece(GameObject prefab) { BCSSignalPrefabConfigurator.Configure(prefab); } } public class DatabaseAddMethods { public void AddItems(List<GameObject> items) { foreach (GameObject item in items) { AddItem(item); } } public void AddRecipes(List<Recipe> recipes) { foreach (Recipe recipe in recipes) { AddRecipe(recipe); } } public void AddStatuseffects(List<StatusEffect> statusEffects) { foreach (StatusEffect statusEffect in statusEffects) { AddStatus(statusEffect); } } private bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private void AddStatus(StatusEffect status) { if (!IsObjectDBValid() || (Object)(object)status == (Object)null) { if ((Object)(object)status == (Object)null) { Debug.LogError((object)(Launch.projectName + ": Status not found")); } } else if ((Object)(object)ObjectDB.instance.GetStatusEffect(status.m_nameHash) == (Object)null) { ObjectDB.instance.m_StatusEffects.Add(status); } } private void AddRecipe(Recipe recipe) { if (!IsObjectDBValid() || (Object)(object)recipe == (Object)null) { if ((Object)(object)recipe == (Object)null) { Debug.LogError((object)(Launch.projectName + ": Recipe not found")); } } else if ((Object)(object)recipe.m_item == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe output ItemDrop not found")); } else if ((Object)(object)ObjectDB.instance.m_recipes.Find((Recipe x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)recipe).name) == (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid() || (Object)(object)newPrefab == (Object)null) { if ((Object)(object)newPrefab == (Object)null) { Debug.LogError((object)(Launch.projectName + ": Item prefab not found")); } return; } ItemDrop component = newPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogError((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop not found on prefab")); } else if (!((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)newPrefab).name) != (Object)null)) { ObjectDB.instance.m_items.Add(newPrefab); FieldInfo field = typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Dictionary<int, GameObject> dictionary = ((field != null) ? (field.GetValue(ObjectDB.instance) as Dictionary<int, GameObject>) : null); if (dictionary != null) { dictionary[StringExtensionMethods.GetStableHashCode(((Object)newPrefab).name)] = newPrefab; } else { Debug.LogWarning((object)(Launch.projectName + ": ObjectDB.m_itemByHash was not available for " + ((Object)newPrefab).name)); } } } } public class ModResourceLoader { public AssetBundle assetBundle; public List<GameObject> buildPrefabs = new List<GameObject>(); public List<GameObject> plantPrefabs = new List<GameObject>(); public List<GameObject> itemPrefabs = new List<GameObject>(); public List<GameObject> monsterPrefabs = new List<GameObject>(); public List<GameObject> vegetationPrefabs = new List<GameObject>(); public List<GameObject> clutterPrefabs = new List<GameObject>(); public List<GameObject> locationPrefabs = new List<GameObject>(); public List<GameObject> roomPrefabs = new List<GameObject>(); public List<GameObject> vfxPrefabs = new List<GameObject>(); public List<Texture2D> texturePrefabs = new List<Texture2D>(); public List<Recipe> recipes = new List<Recipe>(); public List<StatusEffect> statusEffects = new List<StatusEffect>(); public StatusEffect newBarleyStatus = null; public ShaderReplacment shaderReplacment = new ShaderReplacment(); public Sprite newLogo = null; public GameObject railwaytable = null; public GameObject unchargedStone = null; public void loadAssets() { assetBundle = GetAssetBundleFromResources("balrondcargosystem"); if ((Object)(object)assetBundle == (Object)null) { Debug.LogError((object)"[BCS] Embedded AssetBundle 'balrondcargosystem' could not be loaded."); return; } string basePath = "Assets/Custom/BalrondCargoSystems/"; loadPieces(basePath); loadItems(basePath); loadOther(basePath); } public IEnumerable<GameObject> EnumerateAudioPrefabs() { foreach (GameObject item in EnumeratePrefabList(buildPrefabs)) { yield return item; } foreach (GameObject item2 in EnumeratePrefabList(plantPrefabs)) { yield return item2; } foreach (GameObject item3 in EnumeratePrefabList(itemPrefabs)) { yield return item3; } foreach (GameObject item4 in EnumeratePrefabList(monsterPrefabs)) { yield return item4; } foreach (GameObject item5 in EnumeratePrefabList(vegetationPrefabs)) { yield return item5; } foreach (GameObject item6 in EnumeratePrefabList(clutterPrefabs)) { yield return item6; } foreach (GameObject item7 in EnumeratePrefabList(locationPrefabs)) { yield return item7; } foreach (GameObject item8 in EnumeratePrefabList(roomPrefabs)) { yield return item8; } foreach (GameObject item9 in EnumeratePrefabList(vfxPrefabs)) { yield return item9; } } private static IEnumerable<GameObject> EnumeratePrefabList(List<GameObject> prefabs) { if (prefabs == null) { yield break; } int i = 0; while (i < prefabs.Count) { GameObject prefab = prefabs[i]; if ((Object)(object)prefab != (Object)null) { yield return prefab; } int num = i + 1; i = num; } } public void AddPrefabsToZnetScene(ZNetScene zNetScene) { AddUniquePrefabs(zNetScene.m_prefabs, vegetationPrefabs); foreach (GameObject gm in itemPrefabs) { GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == ((Object)gm).name); if ((Object)(object)val == (Object)null) { zNetScene.m_prefabs.Add(gm); } else { Debug.LogWarning((object)("Object exists: " + ((Object)gm).name)); } } foreach (GameObject gm2 in buildPrefabs) { GameObject val2 = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == ((Object)gm2).name); if ((Object)(object)val2 == (Object)null) { zNetScene.m_prefabs.Add(gm2); } else { Debug.LogWarning((object)("Object exists: " + ((Object)gm2).name)); } } foreach (GameObject gm3 in vfxPrefabs) { GameObject val3 = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == ((Object)gm3).name); if ((Object)(object)val3 == (Object)null) { zNetScene.m_prefabs.Add(gm3); } else { Debug.LogWarning((object)("Object exists: " + ((Object)gm3).name)); } } zNetScene.m_prefabs.RemoveAll((GameObject x) => (Object)(object)x == (Object)null); setupRails(zNetScene); setupTraincarts(zNetScene); setupSignalPieces(zNetScene); addPlantstoCultivator(zNetScene); setupBuildPiecesList(zNetScene); } private static void AddUniquePrefabs(List<GameObject> target, List<GameObject> source) { if (target == null || source == null) { return; } for (int i = 0; i < source.Count; i++) { GameObject prefab = source[i]; if (!((Object)(object)prefab == (Object)null) && (Object)(object)target.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)prefab).name) == (Object)null) { target.Add(prefab); } } } private void setupTraincarts(ZNetScene zNetScene) { string[] array = new string[4] { "RailCargoWagon_bal", "RailPowerWagon_bal", "RailTableWagon_bal", "RailPersonelWagon_bal" }; string[] array2 = array; foreach (string name in array2) { GameObject val = buildPrefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[BCS] setupTraincarts: prefab not found: " + name)); } else { setupTraincart(zNetScene, val); } } } private void setupTraincart(ZNetScene zNetScene, GameObject prefab) { BCSPrefabConfigurator.ConfigureTrainCart(prefab); } private void setupSignalPieces(ZNetScene zNetScene) { string[] array = new string[6] { "daycycleSignalEmitter_bal", "pressenceSignalEmitter_bal", "railtrackSignalEmitter_bal", "railtrackLampReciver_bal", "railSignalDoor_bal", "railSignalLiftGate_bal" }; string[] array2 = array; foreach (string name in array2) { GameObject val = buildPrefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[BCS] setupSignalPieces: prefab not found: " + name)); } else { setupSignalPiece(zNetScene, val); } } } private void setupSignalPiece(ZNetScene zNetScene, GameObject prefab) { BCSPrefabConfigurator.ConfigureSignalPiece(prefab); } private void setupRails(ZNetScene zNetScene) { string[] array = new string[29] { "railtrackControl_bal", "railtrackSignalStopReceiver_bal", "railtrackContainer_bal", "railtrackUnload_bal", "railtrackSpeed_bal", "railtrack_bal", "railtrack1m_bal", "railtrack4m_bal", "railtrack8m_bal", "railtrackRamp_bal", "railtrackRamp26short_bal", "railtrackRamp45_bal", "railtrackRamp45short_bal", "railtrackRamp64_bal", "railtrackCross_bal", "railtrackSwitchLeft_bal", "railtrackSwitchMid_bal", "railtrackSwitchRight_bal", "railtrackTurnRight15_bal", "railtrackTurnRight30_bal", "railtrackTurnRight45_bal", "railtrackTurnLeft15_bal", "railtrackTurnLeft30_bal", "railtrackTurnLeft45_bal", "railtrackJump4m_bal", "railtrackJump6m_bal", "railtrackJump8m_bal", "railtrackDrop8m_bal", "railtrackDrawbridge10m_bal" }; string[] array2 = array; foreach (string name in array2) { GameObject val = buildPrefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[BCS] setupRails: prefab not found: " + name)); } else { setupRail(zNetScene, val); } } } private void setupRail(ZNetScene zNetScene, GameObject prefab) { BCSPrefabConfigurator.ConfigureRail(prefab); } private void setupBuildPiecesList(ZNetScene zNetScene) { string[] array = new string[4] { "Hammer", "HammerIron", "HammerDverger", "HammerBlackmetal" }; if ((Object)(object)zNetScene == (Object)null || zNetScene.m_prefabs == null) { return; } GameObject val = zNetScene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Hammer"); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); PieceTable val3 = (((Object)(object)val2 != (Object)null) ? val2.m_itemData.m_shared.m_buildPieces : null); if ((Object)(object)val3 == (Object)null) { Debug.LogWarning((object)"[BCS] setupBuildPiecesList: Hammer/PieceTable not available."); return; } string[] array2 = array; foreach (string name in array2) { addBuildpiecesToOtherHammer(name, val3, zNetScene); } List<GameObject> pieces = val3.m_pieces; foreach (GameObject buildPrefab in buildPrefabs) { setupRavenGuide(buildPrefab, zNetScene.m_prefabs); AddToBuildList(buildPrefab, pieces); } } private void addBuildpiecesToOtherHammer(string name, PieceTable pieceTable, ZNetScene zNetScene) { GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == name); if (!((Object)(object)val == (Object)null)) { ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { component.m_itemData.m_shared.m_buildPieces = pieceTable; } } } public void setupRavenGuide(GameObject gameObject, List<GameObject> gameObjects) { GameObject val = null; Transform val2 = gameObject.transform.Find("GuidePoint"); if ((Object)(object)val2 == (Object)null) { return; } GameObject val3 = gameObjects?.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "piece_workbench"); if ((Object)(object)val3 != (Object)null) { Transform val4 = val3.transform.Find("GuidePoint"); if ((Object)(object)val4 != (Object)null) { GuidePoint component = ((Component)val4).GetComponent<GuidePoint>(); if ((Object)(object)component != (Object)null) { val = component.m_ravenPrefab; } } } if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"Ravens not found"); return; } GuidePoint component2 = ((Component)val2).GetComponent<GuidePoint>(); if ((Object)(object)component2 != (Object)null) { component2.m_ravenPrefab = val; } } public void setupBuildPiecesListDB() { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return; } GameObject val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Hammer"); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); PieceTable val3 = (((Object)(object)val2 != (Object)null) ? val2.m_itemData.m_shared.m_buildPieces : null); if ((Object)(object)val3 == (Object)null || val3.m_pieces == null) { return; } foreach (GameObject buildPrefab in buildPrefabs) { AddToBuildList(buildPrefab, val3.m_pieces); } } private void AddToBuildList(GameObject prefab, List<GameObject> buildPieces) { if (!((Object)(object)prefab == (Object)null) && buildPieces != null && (Object)(object)buildPieces.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)prefab).name) == (Object)null) { buildPieces.Add(prefab); } } private void addPlantstoCultivator(ZNetScene zNetScene) { if (plantPrefabs == null || plantPrefabs.Count == 0 || (Object)(object)zNetScene == (Object)null || zNetScene.m_prefabs == null) { return; } GameObject val = zNetScene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Cultivator"); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); PieceTable val3 = (((Object)(object)val2 != (Object)null) ? val2.m_itemData.m_shared.m_buildPieces : null); if ((Object)(object)val3 == (Object)null || val3.m_pieces == null) { Debug.LogWarning((object)"[BCS] addPlantstoCultivator: Cultivator/PieceTable not available."); return; } foreach (GameObject plantPrefab in plantPrefabs) { AddToBuildList(plantPrefab, val3.m_pieces); } } private void loadItems(string basePath) { string mainPath = basePath + "Items/"; string[] nameList = new string[9] { "WagonBundlePower_bal", "WagonBundleCargo_bal", "WagonBundleTable_bal", "WagonBundlePersonel_bal", "WagonPartsBundle_bal", "RailPartsBundle_bal", "RailwayHammer_bal", "BuilderWorkstationBundle_bal", "UncharedThunderstone_bal" }; addNewPrefabToCollection(nameList, mainPath, itemPrefabs, "item"); } private void addNewPrefabToCollection(string[] nameList, string mainPath, List<GameObject> prefabList, string typeName) { foreach (string text in nameList) { GameObject val = assetBundle.LoadAsset<GameObject>(mainPath + text + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find " + typeName + " with name: " + text)); continue; } if (((Object)val).name == "UncharedThunderstone_bal") { unchargedStone = val; } if (Object.op_Implicit((Object)(object)val.GetComponent<ZNetView>()) || typeName == "clutter") { ShaderReplacment.Replace(val); prefabList.Add(val); } else { Debug.LogWarning((object)("Prefab with name has no ZNetView could not been removed: " + text)); } } } private AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(filename, StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrEmpty(text)) { Debug.LogError((object)("[BCS] Embedded resource not found: " + filename)); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { Debug.LogError((object)("[BCS] Embedded resource stream could not be opened: " + text)); return null; } return AssetBundle.LoadFromStream(stream); } private void loadPlants(string basePath) { string text = basePath + "Plants/"; string[] array = new string[0]; string[] array2 = array; foreach (string text2 in array2) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find plant with name: " + text2)); continue; } ShaderReplacment.Replace(val); plantPrefabs.Add(val); } } private void loadPieces(string basePath) { string text = basePath + "Pieces/"; string[] buildPieces = BuildPieceList.buildPieces; string[] array = buildPieces; foreach (string text2 in array) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find piece with name: " + text2)); continue; } ShaderReplacment.Replace(val); if (((Object)val).name == "RailTableWagon_bal") { railwaytable = val; } buildPrefabs.Add(val); } } private void loadVegetation(string basePath) { string text = basePath + "Vegetation/"; string[] array = new string[0]; string[] array2 = array; foreach (string text2 in array2) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find vegegation with name: " + text2)); continue; } ShaderReplacment.Replace(val); vegetationPrefabs.Add(val); } } private void loadOther(string basePath) { string text = basePath + "Other/"; string[] array = new string[3] { "sfx_stop_cart_bal", "vfx_cartconnector_bal", "_railhammerPieceTable_bal" }; string[] array2 = array; foreach (string text2 in array2) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find object with name: " + text2)); continue; } ShaderReplacment.Replace(val); vfxPrefabs.Add(val); } } private void prepareOtherEffects(string mainPath) { string[] array = new string[0]; string[] array2 = array; foreach (string text in array2) { StatusEffect val = (StatusEffect)(object)assetBundle.LoadAsset<SE_Stats>(mainPath + "Status/" + text + ".asset"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Status not found: " + text)); } else { statusEffects.Add(val); } } } } public class ShaderReplacment { public static List<GameObject> prefabsToReplaceShader = new List<GameObject>(); public static List<Material> materialsInPrefabs = new List<Material>(); public string[] shaderlist = new string[49] { "Custom/AlphaParticle", "Custom/Blob", "Custom/Bonemass", "Custom/Clouds", "Custom/Creature", "Custom/Decal", "Custom/Distortion", "Custom/Flow", "Custom/FlowOpaque", "Custom/Grass", "Custom/GuiScroll", "Custom/Heightmap", "Custom/icon", "Custom/InteriorSide", "Custom/LitGui", "Custom/LitParticles", "Custom/mapshader", "Custom/ParticleDecal", "Custom/Piece", "Custom/Player", "Custom/Rug", "Custom/ShadowBlob", "Custom/SkyboxProcedural", "Custom/SkyObject", "Custom/StaticRock", "Custom/Tar", "Custom/Trilinearmap", "Custom/UI/BGBlur", "Custom/Vegetation", "Custom/Water", "Custom/WaterBottom", "Custom/WaterMask", "Custom/Yggdrasil", "Custom/Yggdrasil/root", "Hidden/BlitCopyHDRTonemap", "Hidden/Dof/DepthOfFieldHdr", "Hidden/Dof/DX11Dof", "Hidden/Internal-Loading", "Hidden/Internal-UIRDefaultWorld", "Hidden/SimpleClear", "Hidden/SunShaftsComposite", "Lux Lit Particles/ Bumped", "Lux Lit Particles/ Tess Bumped", "Particles/Standard Surface2", "Particles/Standard Unlit2", "Standard TwoSided", "ToonDeferredShading2017", "Unlit/DepthWrite", "Unlit/Lighting" }; public static List<Shader> shaders = new List<Shader>(); private static readonly HashSet<Shader> CachedShaders = new HashSet<Shader>(); public static bool debug = true; public static Shader findShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); if (array.Length == 0) { Debug.LogWarning((object)"SHADER LIST IS EMPTY!"); return null; } if (debug) { } return shaders.Find((Shader x) => ((Object)x).name == name); } public static Shader GetShaderByName(string name) { return shaders.Find((Shader x) => ((Object)x).name == name.Trim()); } public static void debugShaderList(List<Shader> shadersRes) { foreach (Shader shadersRe in shadersRes) { Debug.LogWarning((object)("SHADER NAME IS: " + ((Object)shadersRe).name)); } debug = false; } public static void Replace(GameObject gameObject) { prefabsToReplaceShader.Add(gameObject); GetMaterialsInPrefab(gameObject); } public static void GetMaterialsInPrefab(GameObject gameObject) { Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if ((Object)(object)val2 != (Object)null) { materialsInPrefabs.Add(val2); } } } } public static void getMeShaders() { AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable<Shader> enumerable3; try { IEnumerable<Shader> enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item in enumerable3) { CachedShaders.Add(item); } } } public static void runMaterialFix() { getMeShaders(); shaders.AddRange(CachedShaders); foreach (Material materialsInPrefab in materialsInPrefabs) { Shader shader = materialsInPrefab.shader; if (!((Object)(object)shader == (Object)null)) { string name = ((Object)shader).name; if (!(name == "Standard") && name.Contains("Balrond")) { setProperValue(materialsInPrefab, name); } } } } private static void setProperValue(Material material, string shaderName) { string name = shaderName.Replace("Balrond", "Custom"); name = checkNaming(name