diff --git a/Config/blocks.xml b/Config/blocks.xml
index 7de1efe..4c7ace6 100644
--- a/Config/blocks.xml
+++ b/Config/blocks.xml
@@ -518,7 +518,9 @@
Составной блок, как земельный камень: TEFeatureStorage - сумка духа (окно хранилища 6x2, «Открыть»),
TEFeatureCinerarium (HarmonySrc/Cinerarium.cs) - череп (положить/забрать), показ зоны 5x5, -1..+4,
лимит ceil(убийств / 500) и запрет пересечения зон при постановке. Всё - в радиальном меню на E (решение 16.10).
- Модель и иконка ВРЕМЕННЫЕ - кастрюля игры; своя урна будет из Blender. -->
+ Модель (16.10) - своя: бандл necrocinerarium (BlenderWork/necroCinerarium, make_urn.py): чёрная глазурь, черепа по
+ четырём сторонам, руны футарка кровью «SERVU ĜIS LA LASTA CINDRO», меандр, бусины; свечение рун и глазниц
+ включает TEFeatureCinerarium по черепу. Иконка - рендер той же модели (make_icon.py). -->
@@ -536,8 +538,9 @@
-
-
+
+
+
diff --git a/Config/recipes.xml b/Config/recipes.xml
index fe285b7..681f293 100644
--- a/Config/recipes.xml
+++ b/Config/recipes.xml
@@ -606,12 +606,20 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/HarmonySrc/Cinerarium.cs b/HarmonySrc/Cinerarium.cs
index 7511c83..6311ef4 100644
--- a/HarmonySrc/Cinerarium.cs
+++ b/HarmonySrc/Cinerarium.cs
@@ -245,6 +245,7 @@ namespace NecromancerTome
/// _sound - череп только что положили или вынули (порыв); при загрузке чанка дух появляется молча.
public void SyncGenie(bool _sound)
{
+ SyncGlow();
if (HasSkull && _genie == null)
{
_genie = CinerariumGenie.Spawn(ModelTransform());
@@ -259,6 +260,37 @@ namespace NecromancerTome
}
}
+ /// Руны кровью и глазницы черепов светятся, только когда в урне череп (16.10): _EmissionColor через
+ /// MaterialPropertyBlock на рендерерах модели урны (материал общий не трогается), духа не задевает.
+ public static Color GlowColor = new Color(2.2f, 2.2f, 2.2f, 1f);
+ static readonly MaterialPropertyBlock _glowBlock = new MaterialPropertyBlock();
+ static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor");
+ int _glowState = -1; // -1 - не ставили на эту модель
+
+ void SyncGlow()
+ {
+ Transform t = ModelTransform();
+ int want = HasSkull ? 1 : 0;
+ if (t == null || (_glowState == want && _glowModel == t))
+ {
+ return;
+ }
+ foreach (Renderer r in t.GetComponentsInChildren(true))
+ {
+ if (_genie != null && r.transform.IsChildOf(_genie.transform) || _bounds != null && r.transform.IsChildOf(_bounds.transform))
+ {
+ continue;
+ }
+ r.GetPropertyBlock(_glowBlock);
+ _glowBlock.SetColor(EmissionColorId, HasSkull ? GlowColor : Color.black);
+ r.SetPropertyBlock(_glowBlock);
+ }
+ _glowState = want;
+ _glowModel = t;
+ }
+
+ Transform _glowModel;
+
void RemoveGenie(bool _sound)
{
if (_genie == null)
diff --git a/HarmonySrc/CinerariumGenie.cs b/HarmonySrc/CinerariumGenie.cs
index e8761d5..83124f7 100644
--- a/HarmonySrc/CinerariumGenie.cs
+++ b/HarmonySrc/CinerariumGenie.cs
@@ -22,8 +22,13 @@ namespace NecromancerTome
{
public const string ModelPath = "#@modfolder(NecromancerTome):Resources/necrotechnologist?necroTechnologistPrefab.prefab";
- /// Высота корня модели над низом блока урны, м (кончик хвоста в модели - на 0.45 м). Подгоняется командой necrogenie.
- public static float OffsetY = -0.25f;
+ /// Высота корня модели над низом блока урны, м. 16.10 в Blender по модели урны: -0.15 («духа чуть приподними»).
+ /// Подгоняется командой necrogenie.
+ public static float OffsetY = -0.15f;
+ /// Сдвиг вперёд в системе самого духа, м (16.10: «чуть вперёд, чтобы хвост не просвечивал сквозь урну сзади»
+ /// - загнутый назад кончик хвоста; в Blender 0.06 - ни одной вершины за стенкой, взято 0.07). Поворачивается вместе
+ /// с духом, поэтому хвост всегда в горлышке. Знак проверить в игре: necrogenie fwd.
+ public static float Forward = 0.07f;
/// Поворот без работы, градусов в секунду.
public static float TurnSpeed = 6f;
/// Покачивание: размах (м) и период (с).
@@ -203,14 +208,14 @@ namespace NecromancerTome
{
return; // замер как был
}
- Vector3 home = new Vector3(0f, CinerariumGenie.OffsetY, 0f);
float yawTarget = _yaw + CinerariumGenie.TurnSpeed * Time.deltaTime;
+ Vector3 home = new Vector3(0f, CinerariumGenie.OffsetY, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
if (_visitLeft > 0f)
{
// Туда и обратно по синусу: на полпути - над местом работы, лицом к нему.
_visitLeft -= Time.deltaTime;
float k = Mathf.Sin(Mathf.Clamp01(1f - _visitLeft / VisitSeconds) * Mathf.PI);
- Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + 0.6f, 0f);
+ Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + 0.6f, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
transform.localPosition = Vector3.Lerp(home, over, k);
Vector3 d = _visit - home;
if (d.x * d.x + d.z * d.z > 0.01f)
@@ -252,7 +257,8 @@ namespace NecromancerTome
public override string getHelp()
{
return "necrogenie - show the current values and how many spirits are on screen\n" +
- "necrogenie y - model root height above the urn block's bottom (tail tip is 0.45 m above the root)\n" +
+ "necrogenie y - model root height above the urn block's bottom (tail tip is 0.47 m above the root)\n" +
+ "necrogenie fwd - shift along the spirit's own forward (keeps the curled tail inside the neck)\n" +
"necrogenie turn - idle turning speed\n" +
"necrogenie bob - bobbing height and period\n" +
"necrogenie alpha <0-1> - body opacity";
@@ -268,6 +274,9 @@ namespace NecromancerTome
case "y":
CinerariumGenie.OffsetY = v;
break;
+ case "fwd":
+ CinerariumGenie.Forward = v;
+ break;
case "turn":
CinerariumGenie.TurnSpeed = v;
break;
@@ -287,7 +296,7 @@ namespace NecromancerTome
return;
}
}
- con.Output("necrogenie: y " + CinerariumGenie.OffsetY.ToString("F2") + ", turn " + CinerariumGenie.TurnSpeed.ToString("F1") +
+ con.Output("necrogenie: y " + CinerariumGenie.OffsetY.ToString("F2") + ", fwd " + CinerariumGenie.Forward.ToString("F2") + ", turn " + CinerariumGenie.TurnSpeed.ToString("F1") +
", bob " + CinerariumGenie.BobHeight.ToString("F2") + " / " + CinerariumGenie.BobPeriod.ToString("F1") + " s, alpha " +
CinerariumGenie.Alpha.ToString("F2") + "; spirits on screen: " + CinerariumGenie.Live.Count);
}
diff --git a/HarmonySrc/DecorColliderTagPatch.cs b/HarmonySrc/DecorColliderTagPatch.cs
index cc4d901..2ff82e1 100644
--- a/HarmonySrc/DecorColliderTagPatch.cs
+++ b/HarmonySrc/DecorColliderTagPatch.cs
@@ -20,7 +20,7 @@ namespace NecromancerTome
static bool Ours(string _name)
{
- return _name == "necroBookMindPrefab" || _name == "necroKnifeDecorPrefab" || _name == "necroMortarPrefab" || _name.StartsWith("necroBloodRose") || _name.StartsWith("necroPoster") || _name == "necroBookDoorPrefab" || _name.StartsWith("necroSkullDecor");
+ return _name == "necroBookMindPrefab" || _name == "necroKnifeDecorPrefab" || _name == "necroMortarPrefab" || _name.StartsWith("necroBloodRose") || _name.StartsWith("necroPoster") || _name == "necroBookDoorPrefab" || _name.StartsWith("necroSkullDecor") || _name == "necroCinerariumPrefab";
}
public static void Postfix(Transform __result)
diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll
index 6c23567..beba47c 100644
Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ
diff --git a/Resources/necrocinerarium b/Resources/necrocinerarium
new file mode 100644
index 0000000..b73eab6
Binary files /dev/null and b/Resources/necrocinerarium differ
diff --git a/UIAtlases/ItemIconAtlas/necroCinerarium.png b/UIAtlases/ItemIconAtlas/necroCinerarium.png
new file mode 100644
index 0000000..ce19455
Binary files /dev/null and b/UIAtlases/ItemIconAtlas/necroCinerarium.png differ