Нож-для-нитей: тело держит его хватом ножа (necroheld tphold N)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
87fad62c62
commit
180be18dae
@@ -142,6 +142,10 @@ namespace NecromancerTome
|
|||||||
case "scale" when Num(_params, 1, out float s) && s > 0f:
|
case "scale" when Num(_params, 1, out float s) && s > 0f:
|
||||||
HeldTweak.Scale = s;
|
HeldTweak.Scale = s;
|
||||||
break;
|
break;
|
||||||
|
case "tphold" when Num(_params, 1, out float th):
|
||||||
|
ThreadKnifeBody.TpHold = (int)th;
|
||||||
|
Out("хват тела для ножа-для-нитей: " + ThreadKnifeBody.TpHold + (ThreadKnifeBody.TpHold > 0 ? "" : " (выкл - как у рук)") + "; место в руке - при следующем доставании");
|
||||||
|
return;
|
||||||
case "hold" when Num(_params, 1, out float h):
|
case "hold" when Num(_params, 1, out float h):
|
||||||
Out(HeldTweak.SetHold((int)h));
|
Out(HeldTweak.SetHold((int)h));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NecromancerTome
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тело (вид от третьего лица и для других игроков) держит нож-для-нитей обычным хватом ножа, а не луком (16.10, скрин
|
||||||
|
/// от третьего лица: «у персонажа запястье вывихнуто» - анимация деревянного лука тянет правую кисть с ножом). Хват
|
||||||
|
/// предмета один на все модели (HoldType 68 нужен рукам первого лица - основа позы HandPose.PresetThread), поэтому
|
||||||
|
/// подменяется только параметр аниматора WeaponHoldType/WeaponCarry у тел, кроме рук первого лица, и место ножа в
|
||||||
|
/// руке тела. Подбор на лету: necroheld tphold N (0 - выключить подмену).
|
||||||
|
/// </summary>
|
||||||
|
public static class ThreadKnifeBody
|
||||||
|
{
|
||||||
|
public static int TpHold = 36;
|
||||||
|
|
||||||
|
public static bool Applies(EntityAlive _e)
|
||||||
|
{
|
||||||
|
return TpHold > 0 && _e != null && _e.inventory?.holdingItem?.Name == CinerariumThreads.ThreadKnifeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._setInt), new[] { typeof(int), typeof(int), typeof(bool) })]
|
||||||
|
public static class Patch_AvatarMultiBodyController_setInt_ThreadKnife
|
||||||
|
{
|
||||||
|
public static bool Prefix(AvatarMultiBodyController __instance, int _propertyHash, int _value)
|
||||||
|
{
|
||||||
|
bool hold = _propertyHash == AvatarController.weaponHoldTypeHash;
|
||||||
|
if (!hold && _propertyHash != AvatarController.weaponCarryHash || !ThreadKnifeBody.Applies(__instance.Entity))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BodyAnimator fp = (__instance as AvatarLocalPlayerController)?.FPSArms;
|
||||||
|
int tp = hold ? ThreadKnifeBody.TpHold : AnimationDelayData.AnimationDelay[ThreadKnifeBody.TpHold].Carry;
|
||||||
|
foreach (BodyAnimator b in __instance.BodyAnimators)
|
||||||
|
{
|
||||||
|
Animator a = b.Animator;
|
||||||
|
int v = b == fp ? _value : tp;
|
||||||
|
if (a != null && a.GetInteger(_propertyHash) != v)
|
||||||
|
{
|
||||||
|
a.SetInteger(_propertyHash, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // без рассылки по сети: у других игроков мод ставит то же сам
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Место ножа в руке тела - по хвату ножа (игра берёт смещение по HoldType предмета).</summary>
|
||||||
|
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.SetInRightHand))]
|
||||||
|
public static class Patch_AvatarMultiBodyController_SetInRightHand_ThreadKnife
|
||||||
|
{
|
||||||
|
public static void Postfix(AvatarMultiBodyController __instance, Transform _transform)
|
||||||
|
{
|
||||||
|
EntityAlive e = __instance.Entity;
|
||||||
|
if (_transform == null || !ThreadKnifeBody.Applies(e) || e.emodel.IsFPV && !e.isEntityRemote)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AnimationGunjointOffsetData.AnimationGunjointOffsets o = AnimationGunjointOffsetData.AnimationGunjointOffset[ThreadKnifeBody.TpHold];
|
||||||
|
_transform.localPosition = o.position;
|
||||||
|
_transform.localRotation = Quaternion.Euler(o.rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.SwitchModelAndView))]
|
||||||
|
public static class Patch_AvatarMultiBodyController_SwitchModelAndView_ThreadKnife
|
||||||
|
{
|
||||||
|
public static void Postfix(AvatarMultiBodyController __instance, bool _bFPV)
|
||||||
|
{
|
||||||
|
Transform t = __instance.heldItemTransform;
|
||||||
|
if (t == null || _bFPV || !ThreadKnifeBody.Applies(__instance.Entity))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AnimationGunjointOffsetData.AnimationGunjointOffsets o = AnimationGunjointOffsetData.AnimationGunjointOffset[ThreadKnifeBody.TpHold];
|
||||||
|
t.localPosition = o.position;
|
||||||
|
t.localEulerAngles = o.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user