Руки одержимого: пол по звукам zombiefemale, сдвиг -1.7 м под камеру, команда necroarms (состояние, pos, parent)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f5f4d92cef
commit
a27caefc34
+97
-3
@@ -1,4 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace NecromancerTome
|
||||
{
|
||||
@@ -31,6 +34,11 @@ namespace NecromancerTome
|
||||
};
|
||||
|
||||
public static readonly Color Tint = new Color(0.55f, 0.56f, 0.55f, 1f);
|
||||
/// <summary>Сдвиг рук от камеры (подбор necroarms pos). У персонажа игра опускает руки на 1.7 м: начало их
|
||||
/// скелета - у ног (vp_FPWeapon PositionOffset 0,-1.7,0.02 для SDCS).</summary>
|
||||
public static Vector3 Offset = new Vector3(0f, -1.7f, 0.02f);
|
||||
/// <summary>Родитель: true - сама камера, false - её UFPSRoot (как у персонажа).</summary>
|
||||
public static bool ParentCamera = true;
|
||||
|
||||
static GameObject _rig;
|
||||
static SDCSUtils.TransformCatalog _bones;
|
||||
@@ -38,6 +46,18 @@ namespace NecromancerTome
|
||||
|
||||
public static bool Active => _rig != null;
|
||||
|
||||
/// <summary>Пол зомби. IsMale у зомби в entityclasses.xml не задан (все «мужчины» по умолчанию, тест 13.10:
|
||||
/// Арлин получила мужские руки) - женщину выдают звуки zombiefemale*.</summary>
|
||||
public static bool IsFemale(EntityAlive _z)
|
||||
{
|
||||
if (_z == null || !EntityClass.list.TryGetValue(_z.entityClass, out EntityClass cls) || cls?.Properties == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
string s = cls.Properties.GetString("SoundAlert");
|
||||
return s != null && s.ToLowerInvariant().Contains("female");
|
||||
}
|
||||
|
||||
public static bool Allows(EntityAlive _z)
|
||||
{
|
||||
if (_z == null || !EntityClass.list.TryGetValue(_z.entityClass, out EntityClass cls) || cls?.entityClassName == null)
|
||||
@@ -65,14 +85,14 @@ namespace NecromancerTome
|
||||
{
|
||||
return;
|
||||
}
|
||||
Archetype arch = Archetype.GetArchetype(_z.IsMale ? "BaseMale" : "BaseFemale");
|
||||
Archetype arch = Archetype.GetArchetype(IsFemale(_z) ? "BaseFemale" : "BaseMale");
|
||||
Transform cam = _player.cameraTransform;
|
||||
if (arch == null || cam == null)
|
||||
{
|
||||
Debug.LogWarning("[NecromancerTome] FpArms: нет архетипа или камеры - рук не будет");
|
||||
return;
|
||||
}
|
||||
Transform parent = cam.FindInChildren("UFPSRoot") ?? cam;
|
||||
Transform parent = ParentCamera ? cam : cam.FindInChildren("UFPSRoot") ?? cam;
|
||||
Archetype wasArch = SDCSUtils.tmpArchetype;
|
||||
SDCSUtils.AssetRefs wasOwner = SDCSUtils.tmpAssetsOwner;
|
||||
try
|
||||
@@ -87,7 +107,7 @@ namespace NecromancerTome
|
||||
SDCSUtils.tmpArchetype = wasArch;
|
||||
SDCSUtils.tmpAssetsOwner = wasOwner;
|
||||
}
|
||||
_rig.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
_rig.transform.SetLocalPositionAndRotation(Offset, Quaternion.identity);
|
||||
_rig.name = "necroZombieArmsFP";
|
||||
int layer = LayerMask.NameToLayer("HoldingItem");
|
||||
int tinted = 0;
|
||||
@@ -123,6 +143,43 @@ namespace NecromancerTome
|
||||
", родитель " + parent.name);
|
||||
}
|
||||
|
||||
/// <summary>Состояние рук для necroarms: где они относительно камеры, видны ли, кто рисует их слой.</summary>
|
||||
public static string Dump()
|
||||
{
|
||||
if (_rig == null)
|
||||
{
|
||||
return "рук нет (вид от третьего лица или зомби не из списка)";
|
||||
}
|
||||
Camera main = Camera.main;
|
||||
Transform par = _rig.transform.parent;
|
||||
string s = "активны " + _rig.activeInHierarchy + ", родитель " + (par != null ? par.name + (par.gameObject.activeInHierarchy ? "" : " (ВЫКЛЮЧЕН)") : "нет") +
|
||||
", сдвиг " + _rig.transform.localPosition.ToString("F2");
|
||||
foreach (SkinnedMeshRenderer smr in _rig.GetComponentsInChildren<SkinnedMeshRenderer>(true))
|
||||
{
|
||||
Vector3 c = main != null ? main.transform.InverseTransformPoint(smr.bounds.center) : smr.bounds.center;
|
||||
s += "\n " + smr.name + ": вкл " + smr.enabled + "/" + smr.gameObject.activeInHierarchy + ", виден " + smr.isVisible +
|
||||
", слой " + LayerMask.LayerToName(smr.gameObject.layer) + ", центр от камеры " + c.ToString("F2") + ", размер " + smr.bounds.size.ToString("F2");
|
||||
}
|
||||
foreach (Camera c in Camera.allCameras)
|
||||
{
|
||||
s += "\n камера " + c.name + (c == main ? " (main)" : "") + ": слой HoldingItem " +
|
||||
((c.cullingMask & (1 << LayerMask.NameToLayer("HoldingItem"))) != 0 ? "рисует" : "нет") + ", near " + c.nearClipPlane.ToString("F3");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>Пересобрать руки на месте (после necroarms pos/parent).</summary>
|
||||
public static void Rebuild()
|
||||
{
|
||||
if (_rig == null || !Possession.Active || Possession.Zombie == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
EntityPlayerLocal p = Possession.Player;
|
||||
Hide(p);
|
||||
Show(p, Possession.Zombie);
|
||||
}
|
||||
|
||||
public static void Hide(EntityPlayerLocal _player)
|
||||
{
|
||||
if (_rig == null)
|
||||
@@ -139,4 +196,41 @@ namespace NecromancerTome
|
||||
Debug.Log("[NecromancerTome] FpArms: руки убраны");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// necroarms - руки одержимого от первого лица (13.10): без параметров - состояние; pos x y z - сдвиг от камеры;
|
||||
/// parent cam|ufps - к чему крепить. Сдвиг и родитель применяются сразу (руки пересобираются).
|
||||
/// </summary>
|
||||
[Preserve]
|
||||
public class ConsoleCmdNecroArms : ConsoleCmdAbstract
|
||||
{
|
||||
public override string[] getCommands() => new[] { "necroarms" };
|
||||
public override string getDescription() => "NecromancerTome: руки одержимого от первого лица - [pos x y z | parent cam|ufps]";
|
||||
|
||||
void Out(string _s)
|
||||
{
|
||||
SdtdConsole.Instance.Output(_s);
|
||||
Debug.Log("[NecromancerTome] necroarms: " + _s);
|
||||
}
|
||||
|
||||
public override void Execute(List<string> _params, CommandSenderInfo _senderInfo)
|
||||
{
|
||||
string cmd = _params.Count > 0 ? _params[0] : "";
|
||||
if (cmd == "pos" && _params.Count >= 4 &&
|
||||
float.TryParse(_params[1].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float x) &&
|
||||
float.TryParse(_params[2].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float y) &&
|
||||
float.TryParse(_params[3].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float z))
|
||||
{
|
||||
FpArms.Offset = new Vector3(x, y, z);
|
||||
FpArms.Rebuild();
|
||||
}
|
||||
else if (cmd == "parent" && _params.Count >= 2)
|
||||
{
|
||||
FpArms.ParentCamera = _params[1] != "ufps";
|
||||
FpArms.Rebuild();
|
||||
}
|
||||
Out(FpArms.Dump());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user