Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have freecam on death and also allow for first person following of pmcs #322

Merged
merged 6 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/Configuration/PluginConfigSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ public bool SETTING_DEBUGShowPlayerList

public int WaitingTimeBeforeStart { get; private set; }

public int BlackScreenOnDeathTime
public float BlackScreenOnDeathTime
{
get
{
return StayInTarkovPlugin.Instance.Config.Bind
("Coop", "BlackScreenOnDeathTime", 500, new ConfigDescription("How long to wait until your death waits to become a Free Camera")).Value;
("Coop", "BlackScreenOnDeathTime", 5F, new ConfigDescription("How long to wait after death until you become a Free Camera")).Value;
}
}

Expand Down
210 changes: 173 additions & 37 deletions Source/Coop/FreeCamera/FreeCamera.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
using JetBrains.Annotations;
#nullable enable

using StayInTarkov.Coop.Components.CoopGameComponents;
using StayInTarkov.Coop.Players;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace StayInTarkov.Coop.FreeCamera
Expand All @@ -10,85 +15,216 @@ namespace StayInTarkov.Coop.FreeCamera
/// https://gist.github.com/ashleydavis/f025c03a9221bc840a2b
///
/// This is HEAVILY based on Terkoiz's work found here. Thanks for your work Terkoiz!
/// https://dev.sp-tarkov.com/Terkoiz/Freecam/raw/branch/master/project/Terkoiz.Freecam/FreecamController.cs
/// https://dev.sp-tarkov.com/Terkoiz/Freecam/raw/branch/master/project/Terkoiz.Freecam/Freecam.cs
/// </summary>
public class FreeCamera : MonoBehaviour
{
public bool IsActive = false;
private CoopPlayer? _playerSpectating;
private bool _isSpectatingPlayer = false;
private bool _spectateRightShoulder = true;

public bool IsActive { get; set; } = false;

[UsedImplicitly]
public void Update()
private void StopSpectatingPlayer()
{
if (!IsActive)
if (_playerSpectating != null)
{
return;
_playerSpectating = null;
}
if (transform.parent != null)
{
transform.parent = null;
}
_isSpectatingPlayer = false;
}

private void SpectateNextPlayer()
{
UpdatePlayerSpectator(true);
}

private void SpectatePreviousPlayer()
{
UpdatePlayerSpectator(false);
}

/// <summary>
/// Updates the player beign followed by the camera
/// </summary>
/// <param name="nextPlayer">True for the next player and false for the previous player</param>
private void UpdatePlayerSpectator(bool nextPlayer)
{
SITGameComponent coopGameComponent = SITGameComponent.GetCoopGameComponent();
List<CoopPlayer> players = [.. coopGameComponent
.Players
.Values
.Where(x => !x.IsYourPlayer && x.HealthController.IsAlive && x.GroupId?.Contains("SIT") == true)
];

if (players.Count > 0)
{
if (_playerSpectating == null)
{
if (players[0] != null)
{
_playerSpectating = players[0];
}
}
else
{
int playerIndex = 0;
if (nextPlayer)
{
// We want to look for the next player in the list
playerIndex = players.IndexOf(_playerSpectating) + 1;
if (playerIndex > players.Count - 1)
{
playerIndex = 0;
}
}
else
{
// We want to find the previous player
playerIndex = players.IndexOf(_playerSpectating) - 1;
if (playerIndex < 0)
{
playerIndex = players.Count - 1;
}
}

// Update the player we are spectating
_playerSpectating = players[playerIndex];
}

if (_playerSpectating != null)
{
_isSpectatingPlayer = true;

// Attach the camera to the player we are spectating;
SetPlayerSpectateShoulder();
}
}
else
{
StopSpectatingPlayer();
}
}

var fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
var movementSpeed = fastMode ? 20f : 3f;
private void MoveAndRotateCamera()
{
bool fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
float movementSpeed = fastMode ? 20f : 3f;

// Strafe Right
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
transform.position += (-transform.right * (movementSpeed * Time.deltaTime));
}

// Strafe Left
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.position += (transform.right * (movementSpeed * Time.deltaTime));
}

// Forwards
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.position += (transform.forward * (movementSpeed * Time.deltaTime));
}

// Backwards
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.position += (-transform.forward * (movementSpeed * Time.deltaTime));
}

if (true)
// Up
if (Input.GetKey(KeyCode.Q))
{
if (Input.GetKey(KeyCode.Q))
{
transform.position += (transform.up * (movementSpeed * Time.deltaTime));
}
transform.position += (transform.up * (movementSpeed * Time.deltaTime));
}

if (Input.GetKey(KeyCode.E))
{
transform.position += (-transform.up * (movementSpeed * Time.deltaTime));
}
// Down
if (Input.GetKey(KeyCode.E))
{
transform.position += (-transform.up * (movementSpeed * Time.deltaTime));
}

if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp))
{
transform.position += (Vector3.up * (movementSpeed * Time.deltaTime));
}
// Up
if (Input.GetKey(KeyCode.R) || Input.GetKey(KeyCode.PageUp))
{
transform.position += (Vector3.up * (movementSpeed * Time.deltaTime));
}

if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown))
{
transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime));
}
// Down
if (Input.GetKey(KeyCode.F) || Input.GetKey(KeyCode.PageDown))
{
transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime));
}

float newRotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * 3f;
float newRotationY = transform.localEulerAngles.x - Input.GetAxis("Mouse Y") * 3f;
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
}

//if (FreecamPlugin.CameraMousewheelZoom.Value)
//{
// float axis = Input.GetAxis("Mouse ScrollWheel");
// if (axis != 0)
// {
// var zoomSensitivity = fastMode ? FreecamPlugin.CameraFastZoomSpeed.Value : FreecamPlugin.CameraZoomSpeed.Value;
// transform.position += transform.forward * (axis * zoomSensitivity);
// }
//}
private void SetPlayerSpectateShoulder()
{
if (_isSpectatingPlayer)
{
if (_spectateRightShoulder)
{
transform.parent = _playerSpectating?.PlayerBones.RightShoulder.Original;
transform.localEulerAngles = new Vector3(250, 270, 270);
transform.localPosition = new Vector3(-0.12f, 0.04f, 0.16f);
}
else
{
transform.parent = _playerSpectating?.PlayerBones.LeftShoulder.Original;
transform.localEulerAngles = new Vector3(250, 90, 270);
transform.localPosition = new Vector3(-0.12f, -0.04f, -0.16f);
}
}
}

[UsedImplicitly]
private void OnDestroy()
protected void OnDestroy()
{
Destroy(this);
}

protected void Update()
{
if (!IsActive)
{
return;
}

// Spectate the next player
if (Input.GetKeyDown(KeyCode.Mouse0))
{
SpectateNextPlayer();
}
// Spectate the previous player
else if (Input.GetKeyDown(KeyCode.Mouse1))
{
SpectatePreviousPlayer();
}
// Stop following the currently selected player
else if (Input.GetKeyDown(KeyCode.End))
{
StopSpectatingPlayer();
}
else if (Input.GetKeyDown(KeyCode.Home))
{
_spectateRightShoulder = !_spectateRightShoulder;
SetPlayerSpectateShoulder();
}

// If we aren't spectating anyone then just update the camera normally
if (!_isSpectatingPlayer)
{
MoveAndRotateCamera();
}
}
}
}
Loading
Loading