Skip to content

Commit

Permalink
Merge pull request stayintarkov#4 from belettee/hide-extracted-players
Browse files Browse the repository at this point in the history
disable extracted players renderer and collider (ty @JimWails)
  • Loading branch information
mihaicm93 authored Apr 8, 2024
2 parents e5de2e1 + 0a63344 commit 23ee5b1
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 92 deletions.
186 changes: 97 additions & 89 deletions Source/Coop/Components/CoopGameComponents/SITGameComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,132 +397,140 @@ private IEnumerator EverySecondCoroutine()
{
yield return waitSeconds;

if (!Singleton<ISITGame>.Instantiated)
continue;
try
{
if (!Singleton<ISITGame>.Instantiated)
continue;

if (!Singleton<GameWorld>.Instantiated)
continue;
if (!Singleton<GameWorld>.Instantiated)
continue;

if (!GameWorldGameStarted)
continue;
if (!GameWorldGameStarted)
continue;

//Logger.LogDebug($"DEBUG: {nameof(EverySecondCoroutine)}");
//Logger.LogDebug($"DEBUG: {nameof(EverySecondCoroutine)}");

var coopGame = Singleton<ISITGame>.Instance;
var coopGame = Singleton<ISITGame>.Instance;

var playersToExtract = new HashSet<string>();
foreach (var exfilPlayer in coopGame.ExtractingPlayers)
{
var exfilTime = new TimeSpan(0, 0, (int)exfilPlayer.Value.Item1);
var timeInExfil = new TimeSpan(DateTime.Now.Ticks - exfilPlayer.Value.Item2);
if (timeInExfil >= exfilTime)
var playersToExtract = new HashSet<string>();
foreach (var exfilPlayer in coopGame.ExtractingPlayers)
{
if (!playersToExtract.Contains(exfilPlayer.Key))
var exfilTime = new TimeSpan(0, 0, (int)exfilPlayer.Value.Item1);
var timeInExfil = new TimeSpan(DateTime.Now.Ticks - exfilPlayer.Value.Item2);
if (timeInExfil >= exfilTime)
{
Logger.LogDebug(exfilPlayer.Key + " should extract");
playersToExtract.Add(exfilPlayer.Key);
if (!playersToExtract.Contains(exfilPlayer.Key))
{
Logger.LogDebug(exfilPlayer.Key + " should extract");
playersToExtract.Add(exfilPlayer.Key);
}
}
}
else
{
Logger.LogDebug(exfilPlayer.Key + " extracting " + timeInExfil);
else
{
Logger.LogDebug(exfilPlayer.Key + " extracting " + timeInExfil);

}
}
}

// Trigger all countdown exfils (e.g. car), clients are responsible for their own extract
// since exfilpoint.Entered is local because of collision logic being local
// we start from the end because we remove as we go in `CoopSITGame.ExfiltrationPoint_OnStatusChanged`
for (int i = coopGame.EnabledCountdownExfils.Count - 1; i >= 0; i--)
{
var ep = coopGame.EnabledCountdownExfils[i];
if (coopGame.PastTime - ep.ExfiltrationStartTime >= ep.Settings.ExfiltrationTime)
// Trigger all countdown exfils (e.g. car), clients are responsible for their own extract
// since exfilpoint.Entered is local because of collision logic being local
// we start from the end because we remove as we go in `CoopSITGame.ExfiltrationPoint_OnStatusChanged`
for (int i = coopGame.EnabledCountdownExfils.Count - 1; i >= 0; i--)
{
var game = Singleton<ISITGame>.Instance;
foreach (var player in ep.Entered)
var ep = coopGame.EnabledCountdownExfils[i];
if (coopGame.PastTime - ep.ExfiltrationStartTime >= ep.Settings.ExfiltrationTime)
{
var hasUnmetRequirements = ep.UnmetRequirements(player).Any();
if (player != null && player.HealthController.IsAlive && !hasUnmetRequirements)
var game = Singleton<ISITGame>.Instance;
foreach (var player in ep.Entered)
{
game.ExtractingPlayers.Remove(player.ProfileId);
game.ExtractedPlayers.Add(player.ProfileId);
var hasUnmetRequirements = ep.UnmetRequirements(player).Any();
if (player != null && player.HealthController.IsAlive && !hasUnmetRequirements)
{
game.ExtractingPlayers.Remove(player.ProfileId);
game.ExtractedPlayers.Add(player.ProfileId);
}
}
ep.SetStatusLogged(ep.Reusable ? EExfiltrationStatus.UncompleteRequirements : EExfiltrationStatus.NotPresent, nameof(EverySecondCoroutine));
}
ep.SetStatusLogged(ep.Reusable ? EExfiltrationStatus.UncompleteRequirements : EExfiltrationStatus.NotPresent, nameof(EverySecondCoroutine));
}
}

foreach (var player in playersToExtract)
{
coopGame.ExtractingPlayers.Remove(player);
coopGame.ExtractedPlayers.Add(player);
}

var world = Singleton<GameWorld>.Instance;
foreach (var player in playersToExtract)
{
coopGame.ExtractingPlayers.Remove(player);
coopGame.ExtractedPlayers.Add(player);
}

// Hide extracted Players
foreach (var profileId in coopGame.ExtractedPlayers)
{
var player = world.RegisteredPlayers.Find(x => x.ProfileId == profileId) as EFT.Player;
if (player == null)
continue;
var world = Singleton<GameWorld>.Instance;

if (!ExtractedProfilesSent.Contains(profileId))
// Hide extracted Players
foreach (var profileId in coopGame.ExtractedPlayers)
{
ExtractedProfilesSent.Add(profileId);
if (player.Profile.Side == EPlayerSide.Savage)
var player = world.RegisteredPlayers.Find(x => x.ProfileId == profileId) as EFT.Player;
if (player == null)
continue;

if (!ExtractedProfilesSent.Contains(profileId))
{
player.Profile.EftStats.SessionCounters.AddDouble(0.01,
[
CounterTag.FenceStanding,
ExtractedProfilesSent.Add(profileId);
if (player.Profile.Side == EPlayerSide.Savage)
{
player.Profile.EftStats.SessionCounters.AddDouble(0.01,
[
CounterTag.FenceStanding,
EFenceStandingSource.ExitStanding
]);
]);
}
AkiBackendCommunicationCoop.PostLocalPlayerData(player
, new Dictionary<string, object>() { { "m", "Extraction" }, { "Extracted", true } }
);
}
AkiBackendCommunicationCoop.PostLocalPlayerData(player
, new Dictionary<string, object>() { { "m", "Extraction" }, { "Extracted", true } }
);
}

if (player.ActiveHealthController != null)
{
if (!player.ActiveHealthController.MetabolismDisabled)
if (player.ActiveHealthController != null)
{
player.ActiveHealthController.AddDamageMultiplier(0);
player.ActiveHealthController.SetDamageCoeff(0);
player.ActiveHealthController.DisableMetabolism();
player.ActiveHealthController.PauseAllEffects();
if (!player.ActiveHealthController.MetabolismDisabled)
{
player.ActiveHealthController.AddDamageMultiplier(0);
player.ActiveHealthController.SetDamageCoeff(0);
player.ActiveHealthController.DisableMetabolism();
player.ActiveHealthController.PauseAllEffects();

//player.SwitchRenderer(false);
//player.SwitchRenderer(false);

// TODO: Currently. Destroying your own Player just breaks the game and it appears to be "frozen". Need to learn a new way to do a FreeCam!
//if (Singleton<GameWorld>.Instance.MainPlayer.ProfileId != profileId)
// Destroy(player);
// TODO: Currently. Destroying your own Player just breaks the game and it appears to be "frozen". Need to learn a new way to do a FreeCam!
//if (Singleton<GameWorld>.Instance.MainPlayer.ProfileId != profileId)
// Destroy(player);
}
}
//force close all screens to disallow looting open crates after extract
if (profileId == world.MainPlayer.ProfileId)
{
ScreenManager instance = ScreenManager.Instance;
instance.CloseAllScreensForced();
}

PlayerUtils.MakeVisible(player, false);
}
//force close all screens to disallow looting open crates after extract
if (profileId == world.MainPlayer.ProfileId)

// Add players who have joined to the AI Enemy Lists
var botController = (BotsController)ReflectionHelpers.GetFieldFromTypeByFieldType(typeof(BaseLocalGame<GamePlayerOwner>), typeof(BotsController)).GetValue(Singleton<ISITGame>.Instance);
if (botController != null)
{
ScreenManager instance = ScreenManager.Instance;
instance.CloseAllScreensForced();
while (PlayersForAIToTarget.TryDequeue(out var otherPlayer))
{
Logger.LogDebug($"Adding {otherPlayer.Profile.Nickname} to Enemy list");
botController.AddActivePLayer(otherPlayer);
botController.AddEnemyToAllGroups(otherPlayer, otherPlayer, otherPlayer);
}
}
}


// Add players who have joined to the AI Enemy Lists
var botController = (BotsController)ReflectionHelpers.GetFieldFromTypeByFieldType(typeof(BaseLocalGame<GamePlayerOwner>), typeof(BotsController)).GetValue(Singleton<ISITGame>.Instance);
if (botController != null)
{
while (PlayersForAIToTarget.TryDequeue(out var otherPlayer))
if (Singleton<ISITGame>.Instance.GameClient is GameClientUDP udp)
{
Logger.LogDebug($"Adding {otherPlayer.Profile.Nickname} to Enemy list");
botController.AddActivePLayer(otherPlayer);
botController.AddEnemyToAllGroups(otherPlayer, otherPlayer, otherPlayer);
udp.ResetStats();
}
}

if (Singleton<ISITGame>.Instance.GameClient is GameClientUDP udp)
catch (Exception ex)
{
udp.ResetStats();
Logger.LogError($"{nameof(EverySecondCoroutine)}: caught exception:\n{ex}");
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions Source/Coop/Players/CoopPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public class CoopPlayer : LocalPlayer
{
public virtual ManualLogSource BepInLogger { get; } = BepInEx.Logging.Logger.CreateLogSource("CoopPlayer");

public IEnumerable<TacticalComboVisualController> HelmetLightControllers
{
get
{
return _helmetLightControllers;
}
}

public static async Task<LocalPlayer>
Create(int playerId
, Vector3 position
Expand Down
84 changes: 84 additions & 0 deletions Source/Coop/Players/PlayerUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using EFT.AssetsManager;
using StayInTarkov.Coop.Controllers.HandControllers;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.ParticleSystem.PlaybackState;

namespace StayInTarkov.Coop.Players
{
public static class PlayerUtils
{
public static void MakeVisible(EFT.Player player, bool isVisible)
{
// Turn off all weapon lights
if (!isVisible && player.HandsController is SITFirearmController fac)
{
var lights = new List<LightsStates>();

foreach (var x in fac.GetAllLightMods())
{
var state = x.GetLightState();
state.IsActive = false;
lights.Add(state);
}

fac.SetLightsState([.. lights], force: true);
}

// Turn off helmet lights
if (!isVisible && player is CoopPlayer p)
{
foreach (var x in p.HelmetLightControllers)
{
if (x.LightMod.GetLightState().IsActive)
{
player.SwitchHeadLights(togglesActive: true, changesState: false);
}
}
}

// Toggle any animators and colliders
if (player.HealthController.IsAlive)
{
IAnimator bodyAnimatorCommon = player.GetBodyAnimatorCommon();
if (bodyAnimatorCommon.enabled != isVisible)
{
bool flag = !bodyAnimatorCommon.enabled;
bodyAnimatorCommon.enabled = isVisible;
FirearmsAnimator firearmsAnimator = player.HandsController.FirearmsAnimator;
if (firearmsAnimator != null && firearmsAnimator.Animator.enabled != isVisible)
{
firearmsAnimator.Animator.enabled = isVisible;
}
}

PlayerPoolObject component = player.gameObject.GetComponent<PlayerPoolObject>();
foreach (Collider collider in component.Colliders)
{
if (collider.enabled != isVisible)
{
collider.enabled = isVisible;
}
}

player._characterController.GetCollider().enabled = isVisible;
}

// Build a list of renderers for this player object and set their rendering state
List<Renderer> rendererList = new(256);
player.PlayerBody.GetRenderersNonAlloc(rendererList);

var firearmsController = player.gameObject.GetComponent<EFT.Player.FirearmController>();
if (firearmsController != null)
{
var weaponPrefab = (WeaponPrefab)ReflectionHelpers.GetFieldFromType(typeof(EFT.Player.FirearmController), "weaponPrefab_0").GetValue(firearmsController);
if (weaponPrefab != null)
{
rendererList.AddRange(weaponPrefab.Renderers);
}
}

rendererList.ForEach(renderer => renderer.forceRenderingOff = !isVisible);
}
}
}
3 changes: 0 additions & 3 deletions Source/Coop/SITGameModes/CoopSITGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1403,9 +1403,6 @@ public override void Stop(string profileId, ExitStatus exitStatus, string exitNa

}.ToJson());




if (BossWaveManager != null)
BossWaveManager.Stop();

Expand Down

0 comments on commit 23ee5b1

Please sign in to comment.