diff --git a/HarmonySrc/CinerariumGenie.cs b/HarmonySrc/CinerariumGenie.cs
index 1648402..9f3c447 100644
--- a/HarmonySrc/CinerariumGenie.cs
+++ b/HarmonySrc/CinerariumGenie.cs
@@ -35,6 +35,11 @@ namespace NecromancerTome
public static float BobHeight = 0.04f;
public static float BobPeriod = 4f;
public static float Alpha = 0.3f;
+ /// Руки (16.10: «Т-поза бесит»): плечо от вертикали вбок и вперёд, локоть согнут вперёд, градусы.
+ /// Модель в позе покоя, аниматора нет - кости ставятся один раз при появлении.
+ public static float ArmOut = 12f;
+ public static float ArmFwd = 15f;
+ public static float Elbow = 35f;
static GameObject _prefab;
static bool _tried;
@@ -84,7 +89,7 @@ namespace NecromancerTome
{
Object.Destroy(c);
}
- g.AddComponent();
+ g.AddComponent().Pose();
return g;
}
@@ -227,6 +232,65 @@ namespace NecromancerTome
public const float VisitSeconds = 2.2f;
/// Почернел и замер (готовое класть некуда, решение 06.10).
bool _stuck;
+ /// Кости рук (плечо, предплечье, кисть по сторонам) и их поворот в позе покоя.
+ Transform[] _arm;
+ Quaternion[] _armRest;
+ static bool _armLogged;
+
+ /// Опустить руки из позы покоя: направление плеча и предплечья задаётся в осях модели (вперёд - +Z),
+ /// поворот - от текущего направления кости к нужному, так что оси самих костей значения не имеют.
+ public void Pose()
+ {
+ if (_arm == null)
+ {
+ string[] names = { "LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand" };
+ _arm = new Transform[names.Length];
+ _armRest = new Quaternion[names.Length];
+ foreach (Transform t in GetComponentsInChildren(true))
+ {
+ for (int i = 0; i < names.Length; i++)
+ {
+ if (_arm[i] == null && t.name.EndsWith(names[i]))
+ {
+ _arm[i] = t;
+ _armRest[i] = t.localRotation;
+ }
+ }
+ }
+ if (!_armLogged)
+ {
+ _armLogged = true;
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ for (int i = 0; i < names.Length; i++)
+ {
+ sb.Append(names[i]).Append('=').Append(_arm[i] != null ? "ok" : "НЕТ").Append(' ');
+ }
+ Debug.Log("[NecromancerTome] CinerariumGenie: кости рук " + sb);
+ }
+ }
+ for (int i = 0; i < _arm.Length; i++)
+ {
+ if (_arm[i] != null)
+ {
+ _arm[i].localRotation = _armRest[i];
+ }
+ }
+ for (int side = 0; side < 2; side++)
+ {
+ Transform up = _arm[side * 3], fore = _arm[side * 3 + 1], hand = _arm[side * 3 + 2];
+ if (up == null || fore == null || hand == null)
+ {
+ continue;
+ }
+ float sign = Mathf.Sign(transform.InverseTransformPoint(up.position).x);
+ float o = CinerariumGenie.ArmOut * Mathf.Deg2Rad, f = CinerariumGenie.ArmFwd * Mathf.Deg2Rad;
+ Vector3 upDir = new Vector3(sign * Mathf.Sin(o), -Mathf.Cos(o) * Mathf.Cos(f), Mathf.Sin(f)).normalized;
+ Vector3 foreDir = Vector3.RotateTowards(upDir, Vector3.forward, CinerariumGenie.Elbow * Mathf.Deg2Rad, 0f);
+ up.rotation = Quaternion.FromToRotation(fore.position - up.position, transform.TransformDirection(upDir)) * up.rotation;
+ fore.rotation = Quaternion.FromToRotation(hand.position - fore.position, transform.TransformDirection(foreDir)) * fore.rotation;
+ }
+ }
+
/// Светящиеся материалы рендереров - вернуть после почернения.
readonly Dictionary _glowing = new Dictionary();
@@ -348,7 +412,8 @@ namespace NecromancerTome
"necrogenie bob - bobbing height and period\n" +
"necrogenie alpha <0-1> - body brightness (the body adds light, it is not alpha-blended)\n" +
"necrogenie glow <0-1> - body's own glow (visible at night)\n" +
- "necrogenie tint - body colour";
+ "necrogenie tint - body colour\n" +
+ "necrogenie arms - arm pose, degrees: upper arm from vertical sideways and forward, elbow bend";
}
public override void Execute(List _params, CommandSenderInfo _senderInfo)
@@ -382,6 +447,21 @@ namespace NecromancerTome
CinerariumGenie.Glow = Mathf.Clamp01(v);
CinerariumGenie.ApplyAlpha();
break;
+ case "arms":
+ CinerariumGenie.ArmOut = v;
+ if (_params.Count >= 3 && float.TryParse(_params[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float af))
+ {
+ CinerariumGenie.ArmFwd = af;
+ }
+ if (_params.Count >= 4 && float.TryParse(_params[3], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float ae))
+ {
+ CinerariumGenie.Elbow = ae;
+ }
+ foreach (CinerariumGenieMotion m in CinerariumGenie.Live)
+ {
+ m.Pose();
+ }
+ break;
case "tint":
if (_params.Count >= 4 &&
float.TryParse(_params[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float g) &&
@@ -399,7 +479,8 @@ namespace NecromancerTome
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") + ", glow " + CinerariumGenie.Glow.ToString("F2") + ", tint " +
- CinerariumGenie.Tint.r.ToString("F2") + " " + CinerariumGenie.Tint.g.ToString("F2") + " " + CinerariumGenie.Tint.b.ToString("F2") + "; spirits on screen: " + CinerariumGenie.Live.Count);
+ CinerariumGenie.Tint.r.ToString("F2") + " " + CinerariumGenie.Tint.g.ToString("F2") + " " + CinerariumGenie.Tint.b.ToString("F2") + ", arms " + CinerariumGenie.ArmOut.ToString("F0") + " " +
+ CinerariumGenie.ArmFwd.ToString("F0") + " " + CinerariumGenie.Elbow.ToString("F0") + "; spirits on screen: " + CinerariumGenie.Live.Count);
}
}
}