diff --git a/SkinManagerMod/CommsRadioSkinSwitcher.cs b/SkinManagerMod/CommsRadioSkinSwitcher.cs index 13c3d31..1b22072 100644 --- a/SkinManagerMod/CommsRadioSkinSwitcher.cs +++ b/SkinManagerMod/CommsRadioSkinSwitcher.cs @@ -36,13 +36,16 @@ public class CommsRadioSkinSwitcher : MonoBehaviour, ICommsRadioMode private RaycastHit Hit; private TrainCar SelectedCar = null; private TrainCar PointedCar = null; + private bool HasInterior = false; private MeshRenderer HighlighterRender; + private PaintArea AreaToPaint = PaintArea.All; + private PaintArea AlreadyPainted = PaintArea.None; private List SkinsForCarType = null; private int SelectedSkinIdx = 0; private CustomPaintTheme SelectedSkin = null; - private string CurrentThemeName = null; + private (string exterior, string interior) CurrentThemeName; private const float SIGNAL_RANGE = 100f; private static readonly Vector3 HIGHLIGHT_BOUNDS_EXTENSION = new Vector3(0.25f, 0.8f, 0f); @@ -197,7 +200,7 @@ private void SetState(State newState) case State.SelectSkin: UpdateAvailableSkinsList(SelectedCar.carLivery); SetSelectedSkin(SkinsForCarType?.FirstOrDefault()); - (CurrentThemeName, _) = SkinManager.GetCurrentCarSkin(SelectedCar, false); + CurrentThemeName = SkinManager.GetCurrentCarSkin(SelectedCar, false); ButtonBehaviour = ButtonBehaviourType.Override; break; @@ -253,7 +256,7 @@ public void OnUpdate() { PointToCar(trainCar); - if (!SkinProvider.IsBuiltInTheme(SelectedSkin) && (SelectedSkin.name == CurrentThemeName)) + if (!HasInterior && !SkinProvider.IsBuiltInTheme(SelectedSkin) && (SelectedSkin.name == CurrentThemeName.exterior)) { display.SetAction(Translations.ReloadAction); } @@ -277,7 +280,15 @@ public void OnUpdate() (trainCar = TrainCar.Resolve(Hit.transform.root)) && (trainCar == SelectedCar)) { PointToCar(trainCar); - display.SetAction(Translations.ConfirmAction); + + if ((AlreadyPainted == AreaToPaint) && !SkinProvider.IsBuiltInTheme(SelectedSkin)) + { + display.SetAction(Translations.ReloadAction); + } + else + { + display.SetAction(Translations.ConfirmAction); + } } else { @@ -296,16 +307,13 @@ private string AreaToPaintName { get { - switch (AreaToPaint) + return AreaToPaint switch { - case PaintArea.Exterior: - return CommsRadioLocalization.MODE_PAINTJOB_EXTERIOR; - case PaintArea.Interior: - return CommsRadioLocalization.MODE_PAINTJOB_INTERIOR; - case PaintArea.All: - default: - return CommsRadioLocalization.MODE_PAINTJOB_ALL; + PaintArea.Exterior => CommsRadioLocalization.MODE_PAINTJOB_EXTERIOR, + PaintArea.Interior => CommsRadioLocalization.MODE_PAINTJOB_INTERIOR, + _ => CommsRadioLocalization.MODE_PAINTJOB_ALL, }; + ; } } @@ -317,6 +325,7 @@ public void OnUse() if (PointedCar != null) { SelectedCar = PointedCar; + HasInterior = SelectedCar.GetComponents().Any(tcp => tcp.TargetArea == TrainCarPaint.Target.Interior); PointedCar = null; HighlightCar(SelectedCar, skinningMaterial); @@ -328,24 +337,22 @@ public void OnUse() case State.SelectSkin: if ((PointedCar != null) && (PointedCar == SelectedCar)) { - // clicked on the selected car again, this means confirm - if (!SkinProvider.IsBuiltInTheme(SelectedSkin) && (SelectedSkin.name == CurrentThemeName)) + if (HasInterior) { - SkinProvider.ReloadSkin(SelectedCar.carLivery.id, SelectedSkin.name); - ResetState(); + SetState(State.SelectAreas); } else { - if (SkinProvider.IsThemeable(PointedCar.carLivery.id)) + // for regular cars, skip area selection + if (!SkinProvider.IsBuiltInTheme(SelectedSkin) && (SelectedSkin.name == CurrentThemeName.exterior)) { - SetState(State.SelectAreas); + SkinProvider.ReloadSkin(SelectedCar.carLivery.id, SelectedSkin.name); } else { - // for regular cars, skip area selection ApplySelectedSkin(); - ResetState(); } + ResetState(); } CommsRadioController.PlayAudioFromRadio(ConfirmSound, transform); } @@ -361,7 +368,14 @@ public void OnUse() if ((PointedCar != null) && (PointedCar == SelectedCar)) { // clicked on the selected car again, this means confirm - ApplySelectedSkin(); + if ((AlreadyPainted == AreaToPaint) && !SkinProvider.IsBuiltInTheme(SelectedSkin)) + { + SkinProvider.ReloadSkin(SelectedCar.carLivery.id, SelectedSkin.name); + } + else + { + ApplySelectedSkin(); + } CommsRadioController.PlayAudioFromRadio(ConfirmSound, transform); } @@ -440,7 +454,7 @@ private void ApplySelectedSkin() } SkinManager.ApplySkin(SelectedCar, SelectedSkin, AreaToPaint); - CurrentThemeName = SelectedSkin.name; + //CurrentThemeName = SelectedSkin.name; if (CarTypes.IsMUSteamLocomotive(SelectedCar.carType) && SelectedCar.rearCoupler.IsCoupled()) { @@ -469,6 +483,16 @@ private void SetSelectedSkin(CustomPaintTheme theme) { SelectedSkin = theme; + AlreadyPainted = PaintArea.None; + if (CurrentThemeName.exterior == SelectedSkin.name) + { + AlreadyPainted |= PaintArea.Exterior; + } + if (CurrentThemeName.interior == SelectedSkin.name) + { + AlreadyPainted |= PaintArea.Interior; + } + string displayName = $"{Translations.SelectPaintPrompt}\n{SelectedSkin.LocalizedName}"; display.SetContent(displayName); } diff --git a/SkinManagerMod/Items/PaintFactory.cs b/SkinManagerMod/Items/PaintFactory.cs index 8c7373a..d29e558 100644 --- a/SkinManagerMod/Items/PaintFactory.cs +++ b/SkinManagerMod/Items/PaintFactory.cs @@ -1,12 +1,9 @@ -using DV; -using DV.CabControls; +using DV.CabControls; using DV.Customization.Paint; using DV.Interaction; using DV.Localization; using DV.Shops; -using DV.ThingTypes; using OokiiTsuki.Palette; -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -442,14 +439,15 @@ public static void InjectShopData() if (ShopDataInjected) return; Main.Log("Injecting global shop data"); - if (UnityEngine.Object.FindObjectOfType() is DisplayLoadingInfo info) + if (Object.FindObjectOfType() is DisplayLoadingInfo info) { - info.loadProgressTMP.richText = true; + const float LS_SATURATION = 0.7f; + const float LS_VALUE = 0.8f; + var color = (Color32)Random.ColorHSV(0.01f, 0.9f, LS_SATURATION, LS_SATURATION, LS_VALUE, LS_VALUE); - int colorIdx = UnityEngine.Random.Range(0, _loadingScreenColors.Length - 1); - var color = _loadingScreenColors[colorIdx]; string colString = $"{color.r:X2}{color.g:X2}{color.b:X2}"; + info.loadProgressTMP.richText = true; info.loadProgressTMP.text += $"\n{Translations.LoadingScreen}"; } @@ -499,24 +497,9 @@ public static void DestroyInjectedShopData() Main.Log("Destroying global shop data"); _dummyItemSpecs.Clear(); - UnityEngine.Object.Destroy(_dummyItemSpecHolder); + Object.Destroy(_dummyItemSpecHolder); ShopDataInjected = false; } - - private static float LS_SATURATION = 0.6f; - private static float LS_VALUE = 0.7f; - - private static Color32[] _loadingScreenColors = - { - Color.HSVToRGB(0.0f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.1f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.15f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.25f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.5f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.6f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.75f, LS_SATURATION, LS_VALUE), - Color.HSVToRGB(0.85f, LS_SATURATION, LS_VALUE), - }; } } diff --git a/SkinManagerMod/Patches/CarPatches.cs b/SkinManagerMod/Patches/CarPatches.cs index 0ce5e35..9464b33 100644 --- a/SkinManagerMod/Patches/CarPatches.cs +++ b/SkinManagerMod/Patches/CarPatches.cs @@ -2,6 +2,7 @@ using HarmonyLib; using System.Collections.Generic; using System.Reflection; +using UnityEngine; namespace SkinManagerMod.Patches { @@ -37,75 +38,43 @@ private static void BaseSpawn(TrainCar __result, bool uniqueCar) __result.gameObject.SetActive(true); } - if (uniqueCar) - { - if (__result.PaintExterior) - { - SkinManager.SetAppliedCarSkin(__result, __result.PaintExterior.CurrentTheme.name, PaintArea.Exterior); - } - if (__result.PaintInterior) - { - SkinManager.SetAppliedCarSkin(__result, __result.PaintInterior.CurrentTheme.name, PaintArea.Interior); - } - } - else + if (!uniqueCar) { (string? exterior, string? interior) = SkinManager.GetCurrentCarSkin(__result); - if (__result.PaintExterior && exterior is not null && SkinProvider.TryGetTheme(exterior, out var exteriorTheme)) + if (__result.PaintInterior && interior is not null && SkinProvider.TryGetTheme(interior, out var interiorTheme)) { - __result.PaintExterior.CurrentTheme = exteriorTheme; - SkinManager.SetAppliedCarSkin(__result, exterior, PaintArea.Exterior); + __result.PaintInterior.CurrentTheme = interiorTheme; } - if (__result.PaintInterior && interior is not null && SkinProvider.TryGetTheme(interior, out var interiorTheme)) + if (__result.PaintExterior && exterior is not null && SkinProvider.TryGetTheme(exterior, out var exteriorTheme)) { - __result.PaintInterior.CurrentTheme = interiorTheme; - SkinManager.SetAppliedCarSkin(__result, interior, PaintArea.Interior); + __result.PaintExterior.CurrentTheme = exteriorTheme; } } } } - /* - [HarmonyPatch] - class TrainCar_LoadInterior_Patch - { - static IEnumerable TargetMethods() - { - yield return AccessTools.Method(typeof(TrainCar), nameof(TrainCar.LoadInterior)); - yield return AccessTools.Method(typeof(TrainCar), nameof(TrainCar.LoadExternalInteractables)); - yield return AccessTools.Method(typeof(TrainCar), nameof(TrainCar.LoadDummyExternalInteractables)); - } - static void Postfix(TrainCar __instance) + [HarmonyPatch(typeof(TrainCar))] + internal static class TrainCarPatches + { + [HarmonyPatch(nameof(TrainCar.InitializeObjectPaint))] + [HarmonyPrefix] + public static void BeforeInitializePaint(GameObject obj) { - if (SkinProvider.IsThemeable(__instance.carLivery)) return; + if (obj.GetComponent()) return; - var skinName = SkinManager.GetCurrentCarSkin(__instance); - if (!string.IsNullOrEmpty(skinName)) + foreach (var paint in obj.GetComponents()) { - SkinManager.ApplyNonThemeSkinToInterior(__instance, skinName); + Object.Destroy(paint); } } - } - [HarmonyPatch(typeof(TrainCarPaint))] - internal static class TrainCarPaintPatch - { - [HarmonyPatch(nameof(TrainCarPaint.CurrentTheme), MethodType.Setter)] + [HarmonyPatch(nameof(TrainCar.InitializeObjectPaint))] [HarmonyPostfix] - public static void AfterCurrentThemeSet(TrainCarPaint __instance, PaintTheme ___currentTheme) + public static void AfterInitializePaint(TrainCar __instance) { - var trainCar = TrainCar.Resolve(__instance.gameObject); - string themeName = ___currentTheme ? ___currentTheme.name : null; - - Main.Log($"Applying skin {themeName} to car {trainCar.ID} {__instance.TargetArea}"); - - if (__instance.TargetArea != TrainCarPaint.Target.Exterior) return; - - PaintArea area = __instance.TargetArea.ToPaintArea(); - SkinManager.SetAppliedCarSkin(trainCar, themeName, area); + TrainCarPaintPatches.ReapplyThemes(__instance); } } - */ } diff --git a/SkinManagerMod/Patches/TrainCarPaintPatches.cs b/SkinManagerMod/Patches/TrainCarPaintPatches.cs index f97fb31..7a39b23 100644 --- a/SkinManagerMod/Patches/TrainCarPaintPatches.cs +++ b/SkinManagerMod/Patches/TrainCarPaintPatches.cs @@ -1,5 +1,4 @@ using DV.Customization.Paint; -using DV.ThingTypes; using HarmonyLib; namespace SkinManagerMod.Patches @@ -35,33 +34,62 @@ private static bool UpdateThemeOverride(TrainCarPaint __instance) var train = TrainCar.Resolve(__instance.gameObject); PaintArea area = (__instance.targetArea == TrainCarPaint.Target.Interior) ? PaintArea.Interior : PaintArea.Exterior; - if (__instance.currentTheme is not CustomPaintTheme theme) - { - // default theme - string themeName = __instance.currentTheme.name; + ReapplyThemes(train); - if ((themeName == SkinProvider.DefaultNewThemeName) && !SkinProvider.IsThemeable(train.carLivery)) - { - themeName = SkinProvider.DefaultThemeName; - } - theme = SkinProvider.GetTheme(themeName); - } + var theme = GetCustomTheme(__instance, train); + SkinManager.SetAppliedCarSkin(train, theme.name, area); - if (__instance.TargetArea == TrainCarPaint.Target.Interior) + return false; + } + + public static void ReapplyThemes(TrainCar train) + { + var extTheme = GetCustomTheme(train.PaintExterior, train); + if (!extTheme) return; + + var intTheme = train.PaintInterior ? GetCustomTheme(train.PaintInterior, train) : null; + + extTheme.Apply(train.gameObject, train); + + if (intTheme is not null) { if (train.loadedInterior) { - theme.Apply(train.loadedInterior, train); + intTheme.Apply(train.loadedInterior, train); + } + if (train.interiorLOD) + { + intTheme.Apply(train.interiorLOD.gameObject, train); } } - else + + if (train.loadedExternalInteractables) { - theme.Apply(__instance.gameObject, train); + extTheme.Apply(train.loadedExternalInteractables, train); } - SkinManager.SetAppliedCarSkin(train, theme.name, area); - //Main.LogVerbose($"Applied {theme.name} to {train.ID} {area}"); + if (train.loadedDummyExternalInteractables) + { + extTheme.Apply(train.loadedDummyExternalInteractables, train); + } + } - return false; + private static CustomPaintTheme GetCustomTheme(TrainCarPaint paint, TrainCar train) + { + if (!paint || !paint.currentTheme) return null!; + + if (paint.currentTheme is not CustomPaintTheme theme) + { + // default theme + string themeName = paint.currentTheme.name; + + if ((themeName == SkinProvider.DefaultNewThemeName) && !SkinProvider.IsThemeable(train.carLivery)) + { + themeName = SkinProvider.DefaultThemeName; + } + theme = SkinProvider.GetTheme(themeName); + } + + return theme; } } } diff --git a/SkinManagerMod/SkinManager.cs b/SkinManagerMod/SkinManager.cs index a09ebaa..e8a2f10 100644 --- a/SkinManagerMod/SkinManager.cs +++ b/SkinManagerMod/SkinManager.cs @@ -130,59 +130,6 @@ public static void ApplySkin(TrainCar trainCar, CustomPaintTheme newTheme, Paint } } - //public static void ApplyNonThemeSkinToInterior(TrainCar trainCar, string skinName) - //{ - // var skin = SkinProvider.FindSkinByName(trainCar.carLivery.id, skinName); - // if (skin == null) return; - - // var defaultSkin = CarMaterialData.GetDataForCar(trainCar.carLivery.id); - - // if (trainCar.loadedInterior) - // { - // ApplyNonThemeSkinToTransform(trainCar.loadedInterior, skin, defaultSkin); - // } - // if (trainCar.loadedExternalInteractables) - // { - // ApplyNonThemeSkinToTransform(trainCar.loadedExternalInteractables, skin, defaultSkin); - // } - // if (trainCar.loadedDummyExternalInteractables) - // { - // ApplyNonThemeSkinToTransform(trainCar.loadedDummyExternalInteractables, skin, defaultSkin); - // } - //} - - //public static void ApplySkin(TrainCar trainCar, Skin skin, PaintArea area) - //{ - // if (skin == null) return; - - // var defaultSkin = CarMaterialData.GetDataForCar(trainCar.carLivery.id); - - // if (area.HasFlag(PaintArea.Exterior)) - // { - // ApplyNonThemeSkinToTransform(trainCar.gameObject, skin, defaultSkin); - // } - - // if (area.HasFlag(PaintArea.Interior) && trainCar.loadedInterior) - // { - // ApplyNonThemeSkinToTransform(trainCar.loadedInterior, skin, defaultSkin); - // } - - // SetAppliedCarSkin(trainCar, skin.Name, area); - //} - - //private static void ApplyNonThemeSkinToTransform(GameObject objectRoot, Skin skin, CarMaterialData defaults) - //{ - // foreach (var renderer in objectRoot.GetComponentsInChildren(true)) - // { - // if (!renderer.material) - // { - // continue; - // } - - // TextureUtility.ApplyTextures(renderer, skin, defaults); - // } - //} - #endregion //====================================================================================================