Commit initial BossHealth, DamageNumbers, Horde, ThirdPerson mods
This commit is contained in:
1 parent
7bd44d1d99
commit
9c123865bc
176 files changed
+10367
No files matched your search
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using Cinemachine;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime;
|
||||
using Il2CppInterop.Runtime.Injection;
|
||||
using Skopje.Modding;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Skopje.ThirdPerson
|
||||
{
|
||||
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
|
||||
public class ThirdPersonPlugin : BasePlugin
|
||||
{
|
||||
public const string PluginGuid = "com.skopje.thirdperson";
|
||||
public const string PluginName = "Skopje Third Person";
|
||||
public const string PluginVersion = "1.0.0";
|
||||
|
||||
internal static ManualLogSource LogSource;
|
||||
|
||||
internal static ConfigEntry<bool> Enabled;
|
||||
internal static ConfigEntry<bool> FaceMovement;
|
||||
internal static ConfigEntry<float> Distance;
|
||||
internal static ConfigEntry<float> Shoulder;
|
||||
internal static ConfigEntry<float> Height;
|
||||
internal static ConfigEntry<float> PivotHeight;
|
||||
internal static ConfigEntry<float> AdsDistance;
|
||||
internal static ConfigEntry<float> AdsShoulder;
|
||||
internal static ConfigEntry<float> FovBonus;
|
||||
internal static ConfigEntry<float> AimDistance;
|
||||
|
||||
static Harmony _harmony;
|
||||
static GameObject _driverHost;
|
||||
|
||||
static Il2CppSystem.Action _onClientStarted;
|
||||
static Il2CppSystem.Action _onClientStopped;
|
||||
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStarted;
|
||||
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStopped;
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
LogSource = Log;
|
||||
Enabled = Config.Bind("Camera", "Enabled", true, "Over-the-shoulder camera on the right. The body keeps its own facing so the camera can orbit around to the face.");
|
||||
FaceMovement = Config.Bind("Camera", "FaceMovement", false, "Turn the body toward the direction you move. Leave this off to keep the body still while the camera orbits.");
|
||||
Distance = Config.Bind("Camera", "Distance", 2.7f, "Meters behind the aim axis.");
|
||||
Shoulder = Config.Bind("Camera", "Shoulder", 0.62f, "Meters to the right of the aim axis.");
|
||||
Height = Config.Bind("Camera", "Height", 0.22f, "Meters above the pivot.");
|
||||
PivotHeight = Config.Bind("Camera", "PivotHeight", 1.25f, "Orbit height above the feet, before crouch.");
|
||||
AdsDistance = Config.Bind("Camera", "AdsDistance", 1.55f, "Distance while aiming down sights.");
|
||||
AdsShoulder = Config.Bind("Camera", "AdsShoulder", 0.4f, "Right offset while aiming down sights.");
|
||||
FovBonus = Config.Bind("Camera", "FovBonus", 8f, "Extra field of view. Drops to zero while aiming.");
|
||||
AimDistance = Config.Bind("Camera", "AimDistance", 80f, "Crosshair trace length when nothing is under the reticle.");
|
||||
|
||||
ClassInjector.RegisterTypeInIl2Cpp<ThirdPersonDriver>();
|
||||
|
||||
_onClientStarted = ToIl2Cpp(new System.Action(ThirdPersonRig.OnClientStarted));
|
||||
_onClientStopped = ToIl2Cpp(new System.Action(ThirdPersonRig.OnClientStopped));
|
||||
_onPlayerStarted = ToIl2Cpp<SkopjePlayer>(new System.Action<SkopjePlayer>(ThirdPersonRig.OnPlayerStarted));
|
||||
_onPlayerStopped = ToIl2Cpp<SkopjePlayer>(new System.Action<SkopjePlayer>(ThirdPersonRig.OnPlayerStopped));
|
||||
|
||||
ModAPI.add_OnClientStarted(_onClientStarted);
|
||||
ModAPI.add_OnClientStopped(_onClientStopped);
|
||||
ModAPI.add_OnPlayerStartedClient(_onPlayerStarted);
|
||||
ModAPI.add_OnPlayerStoppedClient(_onPlayerStopped);
|
||||
|
||||
_driverHost = new GameObject("SkopjeThirdPerson");
|
||||
UnityEngine.Object.DontDestroyOnLoad(_driverHost);
|
||||
_driverHost.hideFlags = HideFlags.HideAndDontSave;
|
||||
_driverHost.AddComponent<ThirdPersonDriver>();
|
||||
|
||||
_harmony = new Harmony(PluginGuid);
|
||||
Patch(AccessTools.Method(typeof(SkopjeFPSCamera), "LateUpdate"), nameof(ThirdPersonPatches.AfterCamera));
|
||||
Patch(AccessTools.Method(typeof(CinemachineBrain), "LateUpdate"), nameof(ThirdPersonPatches.AfterBrain));
|
||||
Patch(AccessTools.Method(typeof(SkopjeCharacterController), "UpdateRotation"), nameof(ThirdPersonPatches.AfterBodyRotation), nameof(ThirdPersonPatches.BeforeBodyRotation));
|
||||
|
||||
LogSource.LogInfo($"{PluginName} {PluginVersion} loaded. Config: {Config.ConfigFilePath}");
|
||||
}
|
||||
|
||||
public override bool Unload()
|
||||
{
|
||||
if (_harmony != null)
|
||||
_harmony.UnpatchSelf();
|
||||
ThirdPersonRig.Shutdown();
|
||||
if (_driverHost != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(_driverHost);
|
||||
_driverHost = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Patch(MethodInfo method, string postfix, string prefix = null)
|
||||
{
|
||||
if (method == null)
|
||||
{
|
||||
LogSource.LogWarning("Third person hook was not found: " + (postfix ?? prefix));
|
||||
return;
|
||||
}
|
||||
|
||||
_harmony.Patch(
|
||||
method,
|
||||
prefix: prefix == null ? null : new HarmonyMethod(typeof(ThirdPersonPatches), prefix),
|
||||
postfix: postfix == null ? null : new HarmonyMethod(typeof(ThirdPersonPatches), postfix));
|
||||
}
|
||||
|
||||
static Il2CppSystem.Action ToIl2Cpp(System.Action action)
|
||||
{
|
||||
return DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(action);
|
||||
}
|
||||
|
||||
static Il2CppSystem.Action<T> ToIl2Cpp<T>(System.Action<T> action)
|
||||
{
|
||||
return DelegateSupport.ConvertDelegate<Il2CppSystem.Action<T>>(action);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThirdPersonPatches
|
||||
{
|
||||
public static void AfterCamera(SkopjeFPSCamera __instance)
|
||||
{
|
||||
ThirdPersonRig.Apply(__instance);
|
||||
}
|
||||
|
||||
public static void AfterBrain()
|
||||
{
|
||||
ThirdPersonRig.Apply(ThirdPersonRig.LocalCamera);
|
||||
}
|
||||
|
||||
public static void BeforeBodyRotation(SkopjeCharacterController __instance, ref Quaternion currentRotation)
|
||||
{
|
||||
ThirdPersonRig.RememberBody(__instance, currentRotation);
|
||||
}
|
||||
|
||||
// The motor turns the capsule toward the look yaw. Put the previous facing back so mouse-look only orbits the camera.
|
||||
public static void AfterBodyRotation(SkopjeCharacterController __instance, ref Quaternion currentRotation, float deltaTime)
|
||||
{
|
||||
ThirdPersonRig.HoldBodyFacing(__instance, ref currentRotation, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>Skopje.ThirdPerson</AssemblyName>
|
||||
<RootNamespace>Skopje.ThirdPerson</RootNamespace>
|
||||
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
|
||||
<GameDir Condition="'$(GameDir)' == ''">D:\SteamLibrary\steamapps\common\Skopje83</GameDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>$(GameDir)\BepInEx\core\0Harmony.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx.Core">
|
||||
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Core.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx.Unity.IL2CPP">
|
||||
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Unity.IL2CPP.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppInterop.Runtime">
|
||||
<HintPath>$(GameDir)\BepInEx\core\Il2CppInterop.Runtime.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2Cppmscorlib">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Il2Cppmscorlib.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="SkopjeAssembly">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\SkopjeAssembly.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="FishNet.Runtime">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\FishNet.Runtime.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Cinemachine">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Cinemachine.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="RootMotion">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\RootMotion.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Archon.SwissArmyLib">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Archon.SwissArmyLib.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,485 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Skopje.ThirdPerson
|
||||
{
|
||||
public class ThirdPersonDriver : MonoBehaviour
|
||||
{
|
||||
void Update()
|
||||
{
|
||||
ThirdPersonRig.TickBody();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
ThirdPersonRig.Apply(ThirdPersonRig.LocalCamera);
|
||||
}
|
||||
}
|
||||
|
||||
static class ThirdPersonRig
|
||||
{
|
||||
const float MoveThreshold = 0.2f;
|
||||
const float ExternalTurn = 35f;
|
||||
|
||||
static readonly List<Renderer> Hidden = new List<Renderer>();
|
||||
static readonly RaycastHit[] Hits = new RaycastHit[24];
|
||||
|
||||
internal static SkopjeFPSCamera LocalCamera;
|
||||
|
||||
static SkopjePlayer _player;
|
||||
static bool _holding;
|
||||
static bool _hasFacing;
|
||||
static Quaternion _facing;
|
||||
static Quaternion _incomingFacing;
|
||||
static bool _hasIncoming;
|
||||
static bool _hasLook;
|
||||
static Quaternion _look = Quaternion.identity;
|
||||
static bool _hasPlacement;
|
||||
static Vector3 _placedPos;
|
||||
static float _baseFov;
|
||||
static float _boom = 2.7f;
|
||||
static float _ads;
|
||||
static bool _capturedIk;
|
||||
static bool _aimWasEnabled;
|
||||
static bool _lookWasEnabled;
|
||||
static bool _followWasEnabled;
|
||||
static bool _disabledFollow;
|
||||
static float _nextScan;
|
||||
static int _errors;
|
||||
static bool _logged;
|
||||
|
||||
public static void OnClientStarted()
|
||||
{
|
||||
}
|
||||
|
||||
public static void OnClientStopped()
|
||||
{
|
||||
Release();
|
||||
_player = null;
|
||||
LocalCamera = null;
|
||||
}
|
||||
|
||||
public static void OnPlayerStarted(SkopjePlayer player)
|
||||
{
|
||||
if (player != null && player.IsOwner)
|
||||
_player = player;
|
||||
}
|
||||
|
||||
public static void OnPlayerStopped(SkopjePlayer player)
|
||||
{
|
||||
if (_player == player)
|
||||
{
|
||||
Release();
|
||||
_player = null;
|
||||
LocalCamera = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Shutdown()
|
||||
{
|
||||
Release();
|
||||
_player = null;
|
||||
LocalCamera = null;
|
||||
}
|
||||
|
||||
public static void TickBody()
|
||||
{
|
||||
if (!CanControl(_player))
|
||||
{
|
||||
if (_holding)
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
HoldPresentation(_player);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Apply(SkopjeFPSCamera fps)
|
||||
{
|
||||
if (fps == null || !CanControl(fps.Player))
|
||||
return;
|
||||
|
||||
Camera cam = fps.mainCamera != null ? fps.mainCamera : Camera.main;
|
||||
if (cam == null)
|
||||
return;
|
||||
|
||||
LocalCamera = fps;
|
||||
if (_player == null)
|
||||
_player = fps.Player;
|
||||
|
||||
try
|
||||
{
|
||||
Place(fps, cam);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RememberBody(SkopjeCharacterController controller, Quaternion currentRotation)
|
||||
{
|
||||
if (!CanControl(controller != null ? controller.Player : null))
|
||||
{
|
||||
_hasIncoming = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_incomingFacing = FlatYaw(currentRotation);
|
||||
_hasIncoming = true;
|
||||
}
|
||||
|
||||
public static void HoldBodyFacing(SkopjeCharacterController controller, ref Quaternion currentRotation, float deltaTime)
|
||||
{
|
||||
if (!_hasIncoming || controller == null || !CanControl(controller.Player))
|
||||
return;
|
||||
|
||||
Quaternion held = _hasFacing ? _facing : _incomingFacing;
|
||||
if (!_hasFacing || Quaternion.Angle(held, _incomingFacing) > ExternalTurn)
|
||||
held = _incomingFacing;
|
||||
|
||||
if (ThirdPersonPlugin.FaceMovement.Value)
|
||||
{
|
||||
Vector3 move = controller.moveInputVector;
|
||||
move.y = 0f;
|
||||
if (move.sqrMagnitude > MoveThreshold * MoveThreshold)
|
||||
{
|
||||
float sharp = controller.OrientationSharpness;
|
||||
if (sharp < 0.01f)
|
||||
sharp = 12f;
|
||||
float blend = 1f - Mathf.Exp(-sharp * Mathf.Max(0f, deltaTime));
|
||||
held = Quaternion.Slerp(held, Quaternion.LookRotation(move.normalized, Vector3.up), blend);
|
||||
}
|
||||
}
|
||||
|
||||
_facing = FlatYaw(held);
|
||||
_hasFacing = true;
|
||||
currentRotation = _facing;
|
||||
}
|
||||
|
||||
static void Place(SkopjeFPSCamera fps, Camera cam)
|
||||
{
|
||||
Quaternion look = ReadLook(fps, cam);
|
||||
_look = look;
|
||||
_hasLook = true;
|
||||
|
||||
bool fresh = !_hasPlacement || (cam.transform.position - _placedPos).sqrMagnitude > 0.0004f;
|
||||
if (fresh)
|
||||
_baseFov = cam.fieldOfView;
|
||||
|
||||
float adsTarget = fps.adsMode ? 1f : 0f;
|
||||
_ads = Mathf.MoveTowards(_ads, adsTarget, Time.deltaTime / 0.12f);
|
||||
|
||||
float distance = Mathf.Lerp(Clamp(ThirdPersonPlugin.Distance.Value, 0.8f, 8f), Clamp(ThirdPersonPlugin.AdsDistance.Value, 0.6f, 6f), _ads);
|
||||
float shoulder = Mathf.Lerp(Clamp(ThirdPersonPlugin.Shoulder.Value, 0f, 2f), Clamp(ThirdPersonPlugin.AdsShoulder.Value, 0f, 1.5f), _ads);
|
||||
float height = Clamp(ThirdPersonPlugin.Height.Value, -1f, 2f);
|
||||
float boom = new Vector3(shoulder, height, -distance).magnitude;
|
||||
if (!_hasPlacement)
|
||||
_boom = boom;
|
||||
_boom = Mathf.Lerp(_boom, boom, 1f - Mathf.Exp(-16f * Time.deltaTime));
|
||||
|
||||
Vector3 pivot = Pivot(fps.Player);
|
||||
Vector3 offset = look * new Vector3(shoulder, height, -distance);
|
||||
if (offset.sqrMagnitude < 0.0001f)
|
||||
offset = look * Vector3.back;
|
||||
Vector3 dir = offset.normalized;
|
||||
float allowed = PullIn(fps.Player, pivot, dir, _boom);
|
||||
Vector3 camPos = pivot + dir * allowed;
|
||||
|
||||
Vector3 aim = AimPoint(fps.Player, pivot, look * Vector3.forward);
|
||||
Vector3 toAim = aim - camPos;
|
||||
Vector3 up = look * Vector3.up;
|
||||
if (toAim.sqrMagnitude < 0.0001f || Mathf.Abs(Vector3.Dot(toAim.normalized, up.normalized)) > 0.995f)
|
||||
cam.transform.rotation = look;
|
||||
else
|
||||
cam.transform.rotation = Quaternion.LookRotation(toAim, up);
|
||||
|
||||
cam.transform.position = camPos;
|
||||
cam.fieldOfView = _baseFov + Clamp(ThirdPersonPlugin.FovBonus.Value, 0f, 40f) * (1f - _ads);
|
||||
_placedPos = camPos;
|
||||
_hasPlacement = true;
|
||||
KeepBodyYaw(fps.Player);
|
||||
|
||||
if (!_logged)
|
||||
{
|
||||
_logged = true;
|
||||
ThirdPersonPlugin.LogSource.LogInfo("Right-shoulder camera is active. The body does not turn with the mouse.");
|
||||
}
|
||||
}
|
||||
|
||||
static void KeepBodyYaw(SkopjePlayer player)
|
||||
{
|
||||
if (!_hasFacing || player == null)
|
||||
return;
|
||||
|
||||
Transform body = player.transform;
|
||||
Vector3 up = body.up;
|
||||
Vector3 forward = Vector3.ProjectOnPlane(_facing * Vector3.forward, up);
|
||||
if (forward.sqrMagnitude < 0.0001f)
|
||||
return;
|
||||
|
||||
body.rotation = Quaternion.LookRotation(forward.normalized, up);
|
||||
}
|
||||
|
||||
static Quaternion ReadLook(SkopjeFPSCamera fps, Camera cam)
|
||||
{
|
||||
if (fps.VCamera != null && fps.VCamera.transform != cam.transform)
|
||||
return fps.VCamera.transform.rotation;
|
||||
if (fps.SocketTransform != null && fps.SocketTransform != cam.transform)
|
||||
return fps.SocketTransform.rotation;
|
||||
if (_hasLook && _hasPlacement && (cam.transform.position - _placedPos).sqrMagnitude < 0.0004f)
|
||||
return _look;
|
||||
return cam.transform.rotation;
|
||||
}
|
||||
|
||||
static Vector3 Pivot(SkopjePlayer player)
|
||||
{
|
||||
float height = Clamp(ThirdPersonPlugin.PivotHeight.Value, 0.4f, 2.4f);
|
||||
var body = player.SkopjeCharacterController;
|
||||
if (body != null)
|
||||
{
|
||||
if (body.standingHeight > 0.5f)
|
||||
height = Mathf.Min(height, body.standingHeight * 0.78f);
|
||||
float crouch = body.CrouchedHeightMult > 0.05f ? body.CrouchedHeightMult : 0.55f;
|
||||
height *= Mathf.Lerp(1f, crouch, Mathf.Clamp01(body.currentCrouch01));
|
||||
}
|
||||
|
||||
return player.transform.position + Vector3.up * height;
|
||||
}
|
||||
|
||||
static Vector3 AimPoint(SkopjePlayer player, Vector3 origin, Vector3 direction)
|
||||
{
|
||||
float reach = Clamp(ThirdPersonPlugin.AimDistance.Value, 5f, 200f);
|
||||
if (direction.sqrMagnitude < 0.0001f)
|
||||
direction = Vector3.forward;
|
||||
direction.Normalize();
|
||||
|
||||
int count = Physics.RaycastNonAlloc(origin, direction, Hits, reach, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore);
|
||||
float best = float.MaxValue;
|
||||
Vector3 point = origin + direction * reach;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (Hits[i].collider == null || IsOwn(player, Hits[i].collider))
|
||||
continue;
|
||||
if (Hits[i].distance < best)
|
||||
{
|
||||
best = Hits[i].distance;
|
||||
point = Hits[i].point;
|
||||
}
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
static float PullIn(SkopjePlayer player, Vector3 origin, Vector3 direction, float distance)
|
||||
{
|
||||
const float radius = 0.18f;
|
||||
int count = Physics.SphereCastNonAlloc(origin, radius, direction, Hits, distance, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore);
|
||||
float best = distance;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (Hits[i].collider == null || IsOwn(player, Hits[i].collider))
|
||||
continue;
|
||||
float room = Mathf.Max(0.35f, Hits[i].distance);
|
||||
if (room < best)
|
||||
best = room;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
static void HoldPresentation(SkopjePlayer player)
|
||||
{
|
||||
GameObject third = player.ThirdPerson;
|
||||
if (third != null && !third.activeSelf)
|
||||
third.SetActive(true);
|
||||
|
||||
GameObject pack = player.ThirdPersonBackpackParent;
|
||||
if (pack != null && !pack.activeSelf)
|
||||
pack.SetActive(true);
|
||||
|
||||
var anim = player.TPAnimationController;
|
||||
if (anim != null)
|
||||
{
|
||||
if (!_capturedIk)
|
||||
{
|
||||
_aimWasEnabled = anim.AimAtMotor != null && anim.AimAtMotor.enabled;
|
||||
_lookWasEnabled = anim.LookAtMotor != null && anim.LookAtMotor.enabled;
|
||||
_capturedIk = true;
|
||||
}
|
||||
|
||||
if (anim.AimAtMotor != null)
|
||||
anim.AimAtMotor.enabled = false;
|
||||
if (anim.LookAtMotor != null)
|
||||
anim.LookAtMotor.enabled = false;
|
||||
}
|
||||
|
||||
var follow = player.ThirdPersonFollowCam;
|
||||
if (follow != null && follow.Look != null && follow.Look.enabled)
|
||||
{
|
||||
_followWasEnabled = true;
|
||||
follow.Look.enabled = false;
|
||||
_disabledFollow = true;
|
||||
}
|
||||
|
||||
if (Time.unscaledTime >= _nextScan)
|
||||
{
|
||||
_nextScan = Time.unscaledTime + 0.25f;
|
||||
RebuildHidden(player);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Hidden.Count; i++)
|
||||
{
|
||||
if (Hidden[i] != null)
|
||||
Hidden[i].forceRenderingOff = true;
|
||||
}
|
||||
|
||||
_holding = true;
|
||||
}
|
||||
|
||||
static void RebuildHidden(SkopjePlayer player)
|
||||
{
|
||||
var next = new List<Renderer>();
|
||||
Transform third = player.ThirdPerson != null ? player.ThirdPerson.transform : null;
|
||||
Collect(player.FirstPerson, third, next);
|
||||
|
||||
var weapons = player.WeaponsController;
|
||||
if (weapons != null)
|
||||
{
|
||||
if (weapons.Socket != null)
|
||||
Collect(weapons.Socket.gameObject, third, next);
|
||||
if (weapons.ThrowSocket != null)
|
||||
Collect(weapons.ThrowSocket.gameObject, third, next);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Hidden.Count; i++)
|
||||
{
|
||||
Renderer old = Hidden[i];
|
||||
if (old != null && !next.Contains(old))
|
||||
old.forceRenderingOff = false;
|
||||
}
|
||||
|
||||
Hidden.Clear();
|
||||
Hidden.AddRange(next);
|
||||
}
|
||||
|
||||
static void Collect(GameObject root, Transform thirdPerson, List<Renderer> into)
|
||||
{
|
||||
if (root == null)
|
||||
return;
|
||||
if (thirdPerson != null && (root.transform == thirdPerson || root.transform.IsChildOf(thirdPerson)))
|
||||
return;
|
||||
|
||||
Renderer[] found = root.GetComponentsInChildren<Renderer>(true);
|
||||
for (int i = 0; i < found.Length; i++)
|
||||
{
|
||||
Renderer renderer = found[i];
|
||||
if (renderer == null)
|
||||
continue;
|
||||
if (thirdPerson != null && renderer.transform.IsChildOf(thirdPerson))
|
||||
continue;
|
||||
if (!into.Contains(renderer))
|
||||
into.Add(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
static void Release()
|
||||
{
|
||||
for (int i = 0; i < Hidden.Count; i++)
|
||||
{
|
||||
if (Hidden[i] != null)
|
||||
Hidden[i].forceRenderingOff = false;
|
||||
}
|
||||
|
||||
Hidden.Clear();
|
||||
|
||||
if (_player != null)
|
||||
{
|
||||
var anim = _player.TPAnimationController;
|
||||
if (_capturedIk && anim != null)
|
||||
{
|
||||
if (anim.AimAtMotor != null)
|
||||
anim.AimAtMotor.enabled = _aimWasEnabled;
|
||||
if (anim.LookAtMotor != null)
|
||||
anim.LookAtMotor.enabled = _lookWasEnabled;
|
||||
}
|
||||
|
||||
if (_disabledFollow && _player.ThirdPersonFollowCam != null && _player.ThirdPersonFollowCam.Look != null)
|
||||
_player.ThirdPersonFollowCam.Look.enabled = _followWasEnabled;
|
||||
|
||||
try
|
||||
{
|
||||
_player.RefreshActiveModels();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
_capturedIk = false;
|
||||
_disabledFollow = false;
|
||||
_holding = false;
|
||||
_hasFacing = false;
|
||||
_hasIncoming = false;
|
||||
_hasPlacement = false;
|
||||
_hasLook = false;
|
||||
_ads = 0f;
|
||||
_logged = false;
|
||||
}
|
||||
|
||||
static bool CanControl(SkopjePlayer player)
|
||||
{
|
||||
if (!ThirdPersonPlugin.Enabled.Value || player == null || !player.IsOwner)
|
||||
return false;
|
||||
if (player.IsDead || player.IsFallen || player.IsSpectating || player.IsPaused || player.InInventory)
|
||||
return false;
|
||||
if (player.InsideVehicle != null)
|
||||
return false;
|
||||
|
||||
var cine = player._cinematicController;
|
||||
if (cine != null && cine.PlayingCinematic != null && cine.PlayingCinematic.PlayingCinematic != null)
|
||||
return false;
|
||||
|
||||
return player.SkopjeFPSCamera != null;
|
||||
}
|
||||
|
||||
static bool IsOwn(SkopjePlayer player, Collider collider)
|
||||
{
|
||||
if (player == null || collider == null)
|
||||
return false;
|
||||
Transform transform = collider.transform;
|
||||
Transform root = player.transform;
|
||||
return transform == root || transform.IsChildOf(root);
|
||||
}
|
||||
|
||||
static Quaternion FlatYaw(Quaternion rotation)
|
||||
{
|
||||
Vector3 forward = Vector3.ProjectOnPlane(rotation * Vector3.forward, Vector3.up);
|
||||
if (forward.sqrMagnitude < 0.0001f)
|
||||
forward = Vector3.ProjectOnPlane(rotation * Vector3.up, Vector3.up);
|
||||
if (forward.sqrMagnitude < 0.0001f)
|
||||
forward = Vector3.forward;
|
||||
return Quaternion.LookRotation(forward.normalized, Vector3.up);
|
||||
}
|
||||
|
||||
static float Clamp(float value, float min, float max)
|
||||
{
|
||||
return Mathf.Clamp(value, min, max);
|
||||
}
|
||||
|
||||
static void Fail(Exception ex)
|
||||
{
|
||||
if (_errors++ < 5 && ThirdPersonPlugin.LogSource != null)
|
||||
ThirdPersonPlugin.LogSource.LogWarning("Third person failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"Skopje.ThirdPerson/1.0.0": {
|
||||
"runtime": {
|
||||
"Skopje.ThirdPerson.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"Skopje.ThirdPerson/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("Skopje.ThirdPerson")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("Skopje.ThirdPerson")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("Skopje.ThirdPerson")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
8ec25d9c2fd66f388ffb60470d85e452afd95523e8f8b9133f1a26f62c293384
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net6.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v6.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = Skopje.ThirdPerson
|
||||
build_property.ProjectDir = c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 6.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
18339d4439978cc6f6c93b5159fc999229a5968512d398389890b72d566d8679
|
||||
@@ -0,0 +1,12 @@
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ThirdPersonPlugin.csproj.AssemblyReference.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ThirdPersonPlugin.GeneratedMSBuildEditorConfig.editorconfig
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ThirdPersonPlugin.AssemblyInfoInputs.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ThirdPersonPlugin.AssemblyInfo.cs
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ThirdPersonPlugin.csproj.CoreCompileInputs.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\bin\Release\net6.0\Skopje.ThirdPerson.deps.json
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\bin\Release\net6.0\Skopje.ThirdPerson.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\bin\Release\net6.0\Skopje.ThirdPerson.pdb
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\Skopje.ThirdPerson.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\refint\Skopje.ThirdPerson.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\Skopje.ThirdPerson.pdb
|
||||
c:\Users\andre\Desktop\SkopjeMods\ThirdPerson\obj\Release\net6.0\ref\Skopje.ThirdPerson.dll
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj",
|
||||
"projectName": "Skopje.ThirdPerson",
|
||||
"projectPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj",
|
||||
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
|
||||
"outputPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"version": 4,
|
||||
"targets": {
|
||||
"net6.0": {}
|
||||
},
|
||||
"libraries": {},
|
||||
"projectFileDependencyGroups": {
|
||||
"net6.0": []
|
||||
},
|
||||
"packageFolders": {
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj",
|
||||
"projectName": "Skopje.ThirdPerson",
|
||||
"projectPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj",
|
||||
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
|
||||
"outputPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "5HEtZERsN5U=",
|
||||
"success": true,
|
||||
"projectFilePath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\ThirdPerson\\ThirdPersonPlugin.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.netcore.app.ref\\6.0.36\\microsoft.netcore.app.ref.6.0.36.nupkg.sha512",
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.windowsdesktop.app.ref\\6.0.36\\microsoft.windowsdesktop.app.ref.6.0.36.nupkg.sha512",
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.aspnetcore.app.ref\\6.0.36\\microsoft.aspnetcore.app.ref.6.0.36.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
Reference in new issue
Block a user