From 16fdb8370ed73afed5f492ee762200f636d19f1a Mon Sep 17 00:00:00 2001 From: AlexCube Date: Thu, 22 Oct 2026 23:03:45 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=81=D1=81=D1=83=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B9:=20=D1=81=D0=B2=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=80=D1=83=D0=BD=20=D1=8F=D1=80=D1=87=D0=B5,=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BF=D0=BB=D0=B5=D0=B5=20=D0=B8=20=D1=81=20=D0=BF=D1=83=D0=BB?= =?UTF-8?q?=D1=8C=D1=81=D0=B0=D1=86=D0=B8=D0=B5=D0=B9;=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BD=D1=83=D1=82=D1=8C=20=D1=81=D1=84=D0=B5=D1=80=D1=83=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D0=BE=D0=B9=20(#66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 22.10: «Руны нарисованы красным. Это не выглядит как свечение» - цвет (2, 0.24, 0.12) -> (6, 1.4, 0.35), медленная пульсация ±30%, у соседних котлов не в такт. Подбор без перезапуска: necroossuary color r g b, necroossuary pulse a [speed]. necroossuary put ... none - очистить ячейку. Проверено в test8: без сферы руны гаснут, сфера с крышки пропадает, огонёк не летает; сферу вернул - всё загорается. DLL - после закрытия игры. Co-Authored-By: Claude Opus 5.5 --- HarmonySrc/OssuaryGlow.cs | 62 +++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/HarmonySrc/OssuaryGlow.cs b/HarmonySrc/OssuaryGlow.cs index f7c7a32..c7b8e2f 100644 --- a/HarmonySrc/OssuaryGlow.cs +++ b/HarmonySrc/OssuaryGlow.cs @@ -32,7 +32,11 @@ namespace NecromancerTome return _wispPrefab; } - public static Color GlowColor = new Color(2.0f, 0.24f, 0.12f, 1f); + /// Цвет свечения (HDR). 22.10: было (2, 0.24, 0.12) - «Руны нарисованы красным. Это не выглядит как свечение»: + /// днём смотрелось краской. Теперь ярче и теплее, как раскалённый уголь, с пульсацией. Подбор - necroossuary color / pulse. + public static Color GlowColor = new Color(6f, 1.4f, 0.35f, 1f); + /// Размах пульсации свечения (доля яркости) и её скорость (радиан в секунду). + public static float GlowPulse = 0.3f, GlowPulseSpeed = 1.6f; static readonly MaterialPropertyBlock _block = new MaterialPropertyBlock(); static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor"); @@ -75,6 +79,23 @@ namespace NecromancerTome return true; } + /// Пульсация: свечение рун и нутра - GlowColor с множителем _k (каждый кадр, пока светится). + public static void Pulse(Transform _model, float _k) + { + foreach (string part in new[] { "body", "lid" }) + { + Transform t = _model.Find(part); + Renderer r = t != null ? t.GetComponent() : null; + if (r == null) + { + continue; + } + r.GetPropertyBlock(_block); + _block.SetColor(EmissionColorId, GlowColor * _k); + r.SetPropertyBlock(_block); + } + } + /// Оссуарии (главные блоки) в кубе вокруг точки. public static List Find(World _w, Vector3i _c, int _r, int _ry) { @@ -106,10 +127,16 @@ namespace NecromancerTome public Vector3i Pos; float _next; int _state = -1; + readonly float _phase = Random.Range(0f, 6.28f); // соседние котлы пульсируют не в такт void Update() { - _wisp.Tick(transform, _state > 0 && (_state & 1) != 0 && OssuaryGlow.WispEnabled); // -1 - ещё не смотрели + bool lit = _state > 0 && (_state & 1) != 0 && OssuaryGlow.Enabled; // -1 - ещё не смотрели + _wisp.Tick(transform, lit && OssuaryGlow.WispEnabled); + if (lit && OssuaryGlow.GlowPulse > 0f) + { + OssuaryGlow.Pulse(transform, 1f + OssuaryGlow.GlowPulse * Mathf.Sin(Time.time * OssuaryGlow.GlowPulseSpeed + _phase)); + } if (Time.time < _next) { return; @@ -416,7 +443,9 @@ namespace NecromancerTome "necroossuary on|off - off: sphere and glow no longer follow the ossuary state\n" + "necroossuary wisp on|off - wild spirit wisp flying while the ossuary works\n" + "necroossuary info x y z - slots of the ossuary (samples, fuel, storage) and whether it works\n" + - "necroossuary put x y z mod|fuel [count] - dev: put an item into a slot, hidden ones too"; + "necroossuary put x y z mod|fuel [count] - dev: put an item into a slot (none - empty it)\n" + + "necroossuary color r g b - glow color (HDR, e.g. 6 1.4 0.35)\n" + + "necroossuary pulse a [speed] - glow pulse amplitude (0 - steady) and speed"; } public override void Execute(List _params, CommandSenderInfo _senderInfo) @@ -474,13 +503,14 @@ namespace NecromancerTome { ItemStack[] slots = _params[4] == "fuel" ? te.FuelSlots : te.ModSlots; int i = int.Parse(_params[5]) - 1; - ItemValue iv = ItemClass.GetItem(_params[6]); - if (i < 0 || i >= slots.Length || iv == null || iv.IsEmpty()) + bool none = _params[6] == "none"; + ItemValue iv = none ? ItemValue.None : ItemClass.GetItem(_params[6]); + if (i < 0 || i >= slots.Length || iv == null || (!none && iv.IsEmpty())) { con.Output("necroossuary: нет ячейки " + (i + 1) + " или предмета " + _params[6]); break; } - slots[i] = new ItemStack(iv, _params.Count > 7 ? int.Parse(_params[7]) : 1); + slots[i] = none ? ItemStack.Empty.Clone() : new ItemStack(iv, _params.Count > 7 ? int.Parse(_params[7]) : 1); te.SetModified(); } string S(ItemStack[] _a) @@ -496,6 +526,26 @@ namespace NecromancerTome S(te.Items) + "]; работает " + te.anyEnabled()); break; } + case "color": + if (_params.Count > 3) + { + OssuaryGlow.GlowColor = new Color(float.Parse(_params[1], System.Globalization.CultureInfo.InvariantCulture), + float.Parse(_params[2], System.Globalization.CultureInfo.InvariantCulture), + float.Parse(_params[3], System.Globalization.CultureInfo.InvariantCulture), 1f); + } + con.Output("necroossuary: цвет свечения " + OssuaryGlow.GlowColor); + break; + case "pulse": + if (_params.Count > 1) + { + OssuaryGlow.GlowPulse = float.Parse(_params[1], System.Globalization.CultureInfo.InvariantCulture); + } + if (_params.Count > 2) + { + OssuaryGlow.GlowPulseSpeed = float.Parse(_params[2], System.Globalization.CultureInfo.InvariantCulture); + } + con.Output("necroossuary: пульсация " + OssuaryGlow.GlowPulse + ", скорость " + OssuaryGlow.GlowPulseSpeed); + break; case "wisp": if (_params.Count > 1) {