diff --git a/HarmonySrc/CinerariumGenie.cs b/HarmonySrc/CinerariumGenie.cs index 443158e..c91cbb1 100644 --- a/HarmonySrc/CinerariumGenie.cs +++ b/HarmonySrc/CinerariumGenie.cs @@ -272,8 +272,39 @@ namespace NecromancerTome return p.Key; } } + foreach (KeyValuePair p in _stuckMats) + { + if (p.Value == _ghost) + { + return p.Key; + } + } return _ghost; } + + /// Шейдер материала пропал - дух рисуется пурпурным (23.10.2026, скриншот пользователя: после выхода из + /// питомца в 218 блоках от базы все духи некротехнологов пурпурные; раньше - #70, дух закопанной урны). + public static bool Broken(Material _m) + { + return _m != null && (_m.shader == null || !_m.shader.isSupported || _m.shader.name == "Hidden/InternalErrorShader"); + } + + /// Сломанную копию - из кэша вон и собрать заново из исходного материала модели. + public static Material Repair(Material _broken, bool _stuck) + { + Material src = Source(_broken); + Debug.Log("[NecromancerTome] CinerariumGenie: шейдер духа сломан (" + (_broken.shader != null ? _broken.shader.name : "null") + + ", исходный материал '" + (src != null ? src.name : "null") + "' - шейдер " + + (src != null && src.shader != null ? src.shader.name + (src.shader.isSupported ? "" : " НЕ поддерживается") : "null") + + ", Standard " + (Shader.Find("Standard") != null ? "есть" : "НЕ найден") + ") - материал пересоздан"); + if (src == null || src == _broken) + { + return _broken; + } + _ghostMats.Remove(src); + _stuckMats.Remove(src); + return _stuck ? Stuck(src) : Ghost(src); + } } /// Покачивание и поворот джинна над урной. Только вид - никакой логики. @@ -540,9 +571,47 @@ namespace NecromancerTome float _nextSleepCheck; bool _asleep; bool _hiddenApplied; + float _nextShaderCheck; + Renderer[] _renderers; + + /// Раз в 5 с: не сломан ли шейдер у материалов духа (CinerariumGenie.Broken) - починить на месте. + void CheckShaders() + { + if (_renderers == null) + { + _renderers = GetComponentsInChildren(true); + } + foreach (Renderer r in _renderers) + { + if (r == null || r.name.Contains("eye")) + { + continue; + } + Material[] mats = r.sharedMaterials; + bool fixedAny = false; + for (int i = 0; i < mats.Length; i++) + { + if (CinerariumGenie.Broken(mats[i])) + { + mats[i] = CinerariumGenie.Repair(mats[i], _stuck); + fixedAny = true; + } + } + if (fixedAny) + { + r.sharedMaterials = mats; + _glowing.Clear(); // сохранённые светлые наборы могли быть со сломанными копиями + } + } + } void Update() { + if (Time.time >= _nextShaderCheck) + { + _nextShaderCheck = Time.time + 5f; + CheckShaders(); + } if (Time.time >= _nextSleepCheck) { _nextSleepCheck = Time.time + 0.5f;