diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index a647a612..00000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "References"]
- path = References
- url = https://github.com/project-fika/References.git
diff --git a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropParametersModel.cs b/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropParametersModel.cs
deleted file mode 100644
index dd3f8ba6..00000000
--- a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropParametersModel.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Aki.Custom.Airdrops.Models;
-using Newtonsoft.Json;
-using UnityEngine;
-
-namespace Fika.Core.AkiSupport.Airdrops.Models
-{
- ///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/Models
- /// Paulov: Property instead of Fields so I can easily Json the Model
- ///
- public class FikaAirdropParametersModel
- {
- public FikaAirdropConfigModel Config { get; set; }
- public bool AirdropAvailable { get; set; }
- public bool PlaneSpawned { get; set; }
- public bool BoxSpawned { get; set; }
- public float DistanceTraveled { get; set; }
- public float DistanceToTravel { get; set; }
- public float DistanceToDrop { get; set; }
- public float Timer { get; set; }
- public int DropHeight { get; set; }
- public int TimeToStart { get; set; }
- public Vector3 StartPosition { get; set; }
- public Vector3 SpawnPoint { get; set; }
- public Vector3 LookPoint { get; set; }
-
- [JsonIgnore]
- public Vector3 RandomAirdropPoint { get; set; } = Vector3.zero;
-
- public float RandomAirdropPointX { get { return RandomAirdropPoint.x; } set { RandomAirdropPoint = new Vector3(value, RandomAirdropPoint.y, RandomAirdropPoint.z); } }
- public float RandomAirdropPointY { get { return RandomAirdropPoint.y; } set { RandomAirdropPoint = new Vector3(RandomAirdropPoint.x, value, RandomAirdropPoint.z); } }
- public float RandomAirdropPointZ { get { return RandomAirdropPoint.z; } set { RandomAirdropPoint = new Vector3(RandomAirdropPoint.x, RandomAirdropPoint.y, value); } }
- }
-}
\ No newline at end of file
diff --git a/Fika.Core/AkiSupport/Overrides/MaxBotPatch_Override.cs b/Fika.Core/AkiSupport/Overrides/MaxBotPatch_Override.cs
deleted file mode 100644
index f6e7edac..00000000
--- a/Fika.Core/AkiSupport/Overrides/MaxBotPatch_Override.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Aki.Common.Http;
-using Aki.Reflection.Patching;
-using Aki.Reflection.Utils;
-using Fika.Core.Coop.Matchmaker;
-using System.Reflection;
-
-namespace Fika.Core.AkiSupport.Overrides
-{
- internal class MaxBotPatch_Override : ModulePatch
- {
- protected override MethodBase GetTargetMethod()
- {
- const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
- const string methodName = "SetSettings";
- var desiredType = PatchConstants.EftTypes.SingleCustom(x => x.GetMethod(methodName, flags) != null && IsTargetMethod(x.GetMethod(methodName, flags)));
- var desiredMethod = desiredType.GetMethod(methodName, flags);
-
- Logger.LogDebug($"{this.GetType().Name} Type: {desiredType?.Name}");
- Logger.LogDebug($"{this.GetType().Name} Method: {desiredMethod?.Name}");
-
- return desiredMethod;
- }
-
- private static bool IsTargetMethod(MethodInfo mi)
- {
- var parameters = mi.GetParameters();
- return parameters.Length == 3 && parameters[0].Name == "maxCount" && parameters[1].Name == "botPresets" && parameters[2].Name == "botScatterings";
- }
-
- [PatchPrefix]
- private static void PatchPreFix(ref int maxCount)
- {
- if (MatchmakerAcceptPatches.IsServer)
- {
- if (int.TryParse(RequestHandler.GetJson("/singleplayer/settings/bot/maxCap"), out int parsedMaxCount))
- {
- Logger.LogWarning($"Set max bot cap to: {parsedMaxCount}");
- maxCount = parsedMaxCount;
- }
- else
- {
- Logger.LogWarning($"Unable to parse data from singleplayer/settings/bot/maxCap, using existing map max of {maxCount}");
- }
- }
- else
- {
- maxCount = 0;
- }
- }
- }
-}
diff --git a/Fika.Core/Bundles/Files/newmatchmakerui.bundle b/Fika.Core/Bundles/Files/newmatchmakerui.bundle
index b4ebb1cb..b904ac13 100644
Binary files a/Fika.Core/Bundles/Files/newmatchmakerui.bundle and b/Fika.Core/Bundles/Files/newmatchmakerui.bundle differ
diff --git a/Fika.Core/Console/FikaCommands.cs b/Fika.Core/Console/FikaCommands.cs
index 3da46551..59e6bfa5 100644
--- a/Fika.Core/Console/FikaCommands.cs
+++ b/Fika.Core/Console/FikaCommands.cs
@@ -4,13 +4,14 @@
using EFT.UI;
using Fika.Core.Coop.Components;
using Fika.Core.Coop.GameMode;
-using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
namespace Fika.Core.Console
{
public class FikaCommands
{
+#if DEBUG
[ConsoleCommand("bring", "", null, "Teleports all AI to yourself as the host", [])]
public static void Bring()
{
@@ -30,7 +31,7 @@ public static void Bring()
if (CoopHandler.TryGetCoopHandler(out CoopHandler coopHandler))
{
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
int count = 0;
foreach (CoopPlayer player in coopHandler.Players.Values)
@@ -56,7 +57,7 @@ public static void Bring()
}
[ConsoleCommand("god", "", null, "Set god mode on/off", [])]
- public static void God(bool state)
+ public static void God([ConsoleArgument(false, "true or false to toggle god mode")] bool state)
{
CoopGame coopGame = (CoopGame)Singleton.Instance;
@@ -90,6 +91,27 @@ public static void God(bool state)
ConsoleScreen.LogWarning("Could not find CoopHandler.");
}
}
+#endif
+
+ [ConsoleCommand("debug", "", null, "Toggle debug window", [])]
+ public static void Debug(bool state)
+ {
+ CoopGame coopGame = (CoopGame)Singleton.Instance;
+
+ if (coopGame == null)
+ {
+ ConsoleScreen.LogWarning("You are not in a game.");
+ return;
+ }
+
+ if (coopGame.Status != GameStatus.Started)
+ {
+ ConsoleScreen.LogWarning("Game is not running.");
+ return;
+ }
+
+ coopGame.ToggleDebug(state);
+ }
[ConsoleCommand("clear", "", null, "Clears the console output", [])]
public static void Clear()
diff --git a/Fika.Core/AkiSupport/Airdrops/FikaAirdropBox.cs b/Fika.Core/Coop/Airdrops/FikaAirdropBox.cs
similarity index 95%
rename from Fika.Core/AkiSupport/Airdrops/FikaAirdropBox.cs
rename to Fika.Core/Coop/Airdrops/FikaAirdropBox.cs
index 3a2ee31c..1be4574e 100644
--- a/Fika.Core/AkiSupport/Airdrops/FikaAirdropBox.cs
+++ b/Fika.Core/Coop/Airdrops/FikaAirdropBox.cs
@@ -2,18 +2,18 @@
using EFT.Airdrop;
using EFT.Interactive;
using EFT.SynchronizableObjects;
-using Fika.Core.Coop.Matchmaker;
+using Fika.Core.Coop.Utils;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AI;
-namespace Fika.Core.AkiSupport.Airdrops
+namespace Fika.Core.Coop.Airdrops
{
///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/AirdropBox.cs
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/AirdropBox.cs
///
public class FikaAirdropBox : MonoBehaviour
{
@@ -79,7 +79,7 @@ private static async Task LoadCrate()
IEasyAssets easyAssets = Singleton.Instance.EasyAssets;
await easyAssets.Retain(AIRDROP_SOUNDS_PATH, null, null).LoadingJob;
- Dictionary soundsDictionary = new Dictionary();
+ Dictionary soundsDictionary = new();
AirdropSurfaceSet[] sets = easyAssets.GetAsset(AIRDROP_SOUNDS_PATH).Sets;
foreach (AirdropSurfaceSet set in sets)
{
@@ -151,7 +151,7 @@ private void OnBoxLand(out float clipLength)
Volume = surfaceSet.LandingSoundBank.BaseVolume
});
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
AddNavMeshObstacle();
}
@@ -171,7 +171,7 @@ private bool RaycastBoxDistance(LayerMask layerMask, out RaycastHit hitInfo)
private bool RaycastBoxDistance(LayerMask layerMask, out RaycastHit hitInfo, Vector3 origin)
{
- Ray ray = new Ray(origin, Vector3.down);
+ Ray ray = new(origin, Vector3.down);
bool raycast = Physics.Raycast(ray, out hitInfo, Mathf.Infinity, layerMask);
if (!raycast) return false;
diff --git a/Fika.Core/AkiSupport/Airdrops/FikaAirdropPlane.cs b/Fika.Core/Coop/Airdrops/FikaAirdropPlane.cs
similarity index 94%
rename from Fika.Core/AkiSupport/Airdrops/FikaAirdropPlane.cs
rename to Fika.Core/Coop/Airdrops/FikaAirdropPlane.cs
index 84a275f4..17d80385 100644
--- a/Fika.Core/AkiSupport/Airdrops/FikaAirdropPlane.cs
+++ b/Fika.Core/Coop/Airdrops/FikaAirdropPlane.cs
@@ -5,11 +5,11 @@
using System.Threading.Tasks;
using UnityEngine;
-namespace Fika.Core.AkiSupport.Airdrops
+namespace Fika.Core.Coop.Airdrops
{
///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/AirdropPlane.cs
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/AirdropPlane.cs
///
public class FikaAirdropPlane : MonoBehaviour
{
@@ -82,7 +82,7 @@ private void SetPosition(int dropHeight, Vector3 airdropPoint)
transform.position = new Vector3(pointOnCircle.x, dropHeight, pointOnCircle.y);
newPosition = transform.position;
- Vector3 lookPoint = new Vector3(airdropPoint.x, dropHeight, airdropPoint.z);
+ Vector3 lookPoint = new(airdropPoint.x, dropHeight, airdropPoint.z);
transform.LookAt(lookPoint);
newRotation = lookPoint;
}
@@ -154,7 +154,7 @@ private IEnumerator ChangeHeading()
private float EasingSmoothSquared(float x)
{
- return x < 0.5 ? x * x * 2 : (1 - (1 - x) * (1 - x) * 2);
+ return x < 0.5 ? x * x * 2 : 1 - (1 - x) * (1 - x) * 2;
}
}
}
\ No newline at end of file
diff --git a/Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs b/Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs
index 32bc1dbd..596b3fc7 100644
--- a/Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs
+++ b/Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs
@@ -1,15 +1,13 @@
-using Aki.Custom.Airdrops.Models;
-using Aki.Custom.Airdrops.Utils;
-using BepInEx.Logging;
+using BepInEx.Logging;
using Comfort.Common;
using EFT;
using EFT.InventoryLogic;
-using Fika.Core.AkiSupport.Airdrops;
-using Fika.Core.AkiSupport.Airdrops.Models;
-using Fika.Core.AkiSupport.Airdrops.Utils;
+using Fika.Core.Coop.Airdrops;
+using Fika.Core.Coop.Airdrops.Models;
+using Fika.Core.Coop.Airdrops.Utils;
using Fika.Core.Coop.Components;
using Fika.Core.Coop.GameMode;
-using Fika.Core.Coop.Matchmaker;
+using Fika.Core.Coop.Utils;
using Fika.Core.Networking;
using LiteNetLib;
using LiteNetLib.Utils;
@@ -17,11 +15,11 @@
using System.Collections;
using UnityEngine;
-namespace Aki.Custom.Airdrops
+namespace Coop.Airdrops
{
///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/AirdropsManager.cs
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/AirdropsManager.cs
/// Modified by Lacyway and nexus4880: Uses BSG code to serialize/deserialize data from host to clients
///
public class FikaAirdropsManager : MonoBehaviour
@@ -84,7 +82,7 @@ protected async void Start()
}
// If this is not the server, then this manager will have to wait for the packet to initialize stuff.
- if (MatchmakerAcceptPatches.IsClient)
+ if (FikaBackendUtils.IsClient)
{
return;
}
@@ -110,17 +108,15 @@ protected async void Start()
try
{
- airdropPlane = await FikaAirdropPlane.Init(
- AirdropParameters.RandomAirdropPoint,
- AirdropParameters.DropHeight,
- AirdropParameters.Config.PlaneVolume,
+ airdropPlane = await FikaAirdropPlane.Init(AirdropParameters.RandomAirdropPoint,
+ AirdropParameters.DropHeight, AirdropParameters.Config.PlaneVolume,
AirdropParameters.Config.PlaneSpeed);
AirdropBox = await FikaAirdropBox.Init(AirdropParameters.Config.CrateFallSpeed);
factory = new FikaItemFactoryUtil();
}
catch
{
- Logger.LogError("[AKI-AIRDROPS]: Unable to create plane or crate, airdrop won't occur");
+ Logger.LogError("[SPT-AIRDROPS]: Unable to create plane or crate, airdrop won't occur");
Destroy(this);
throw;
}
@@ -132,7 +128,7 @@ protected async void Start()
public void SendParamsToClients()
{
- if (!MatchmakerAcceptPatches.IsServer)
+ if (!FikaBackendUtils.IsServer)
{
return;
}
@@ -166,13 +162,13 @@ protected async void FixedUpdate()
}
// If we are a client. Wait until the server has sent all the data.
- if (MatchmakerAcceptPatches.IsClient && rootItem == null)
+ if (FikaBackendUtils.IsClient && rootItem == null)
{
return;
}
// If we have all the parameters sent from the Server. Lets build the plane, box, container and loot
- if (MatchmakerAcceptPatches.IsClient && !ClientLootBuilt)
+ if (FikaBackendUtils.IsClient && !ClientLootBuilt)
{
ClientLootBuilt = true;
@@ -212,7 +208,7 @@ protected async void FixedUpdate()
return;
}
- if (MatchmakerAcceptPatches.IsServer || MatchmakerAcceptPatches.IsSinglePlayer)
+ if (FikaBackendUtils.IsServer || FikaBackendUtils.IsSinglePlayer)
{
AirdropParameters.Timer += 0.02f;
@@ -273,7 +269,7 @@ private void StartBox()
private void BuildLootContainer(FikaAirdropConfigModel config)
{
- if (MatchmakerAcceptPatches.IsClient)
+ if (FikaBackendUtils.IsClient)
{
return;
}
@@ -301,7 +297,7 @@ private void BuildLootContainer(FikaAirdropConfigModel config)
}
// Get the lootData. Send to clients.
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
StartCoroutine(SendLootToClients(isFlareDrop));
}
diff --git a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropConfigModel.cs b/Fika.Core/Coop/Airdrops/Models/FikaAirdropConfigModel.cs
similarity index 90%
rename from Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropConfigModel.cs
rename to Fika.Core/Coop/Airdrops/Models/FikaAirdropConfigModel.cs
index 44eb19b4..db7c677b 100644
--- a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropConfigModel.cs
+++ b/Fika.Core/Coop/Airdrops/Models/FikaAirdropConfigModel.cs
@@ -1,11 +1,11 @@
using Newtonsoft.Json;
using System.Collections.Generic;
-namespace Aki.Custom.Airdrops.Models
+namespace Fika.Core.Coop.Airdrops.Models
{
///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/Models
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/Models
///
public class FikaAirdropConfigModel
{
diff --git a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropLootModel.cs b/Fika.Core/Coop/Airdrops/Models/FikaAirdropLootModel.cs
similarity index 79%
rename from Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropLootModel.cs
rename to Fika.Core/Coop/Airdrops/Models/FikaAirdropLootModel.cs
index b089f877..fa7ae4f1 100644
--- a/Fika.Core/AkiSupport/Airdrops/Models/FikaAirdropLootModel.cs
+++ b/Fika.Core/Coop/Airdrops/Models/FikaAirdropLootModel.cs
@@ -1,11 +1,11 @@
using Newtonsoft.Json;
using System.Collections.Generic;
-namespace Aki.Custom.Airdrops.Models
+namespace Fika.Core.Coop.Airdrops.Models
{
///
- /// Created by: SPT-Aki team
- /// Link: https://dev.sp-tarkov.com/SPT-AKI/Modules/src/branch/master/project/Aki.Custom/Airdrops/Models
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/Models
///
public class FikaAirdropLootResultModel
{
diff --git a/Fika.Core/Coop/Airdrops/Models/FikaAirdropParametersModel.cs b/Fika.Core/Coop/Airdrops/Models/FikaAirdropParametersModel.cs
new file mode 100644
index 00000000..f5f444da
--- /dev/null
+++ b/Fika.Core/Coop/Airdrops/Models/FikaAirdropParametersModel.cs
@@ -0,0 +1,29 @@
+using Newtonsoft.Json;
+using UnityEngine;
+
+namespace Fika.Core.Coop.Airdrops.Models
+{
+ ///
+ /// Created by: SPT team
+ /// Link: https://dev.sp-tarkov.com/SPT/Modules/src/branch/master/project/SPT.Custom/Airdrops/Models
+ ///
+ public class FikaAirdropParametersModel
+ {
+ public FikaAirdropConfigModel Config;
+ public bool AirdropAvailable;
+ public bool PlaneSpawned;
+ public bool BoxSpawned;
+ public float DistanceTraveled;
+ public float DistanceToTravel;
+ public float DistanceToDrop;
+ public float Timer;
+ public int DropHeight;
+ public int TimeToStart;
+ public Vector3 StartPosition;
+ public Vector3 SpawnPoint;
+ public Vector3 LookPoint;
+
+ [JsonIgnore]
+ public Vector3 RandomAirdropPoint = Vector3.zero;
+ }
+}
\ No newline at end of file
diff --git a/Fika.Core/AkiSupport/Airdrops/Utils/FikaAirdropUtil.cs b/Fika.Core/Coop/Airdrops/Utils/FikaAirdropUtil.cs
similarity index 93%
rename from Fika.Core/AkiSupport/Airdrops/Utils/FikaAirdropUtil.cs
rename to Fika.Core/Coop/Airdrops/Utils/FikaAirdropUtil.cs
index 2ddf970b..acef3c5b 100644
--- a/Fika.Core/AkiSupport/Airdrops/Utils/FikaAirdropUtil.cs
+++ b/Fika.Core/Coop/Airdrops/Utils/FikaAirdropUtil.cs
@@ -1,17 +1,19 @@
-using Aki.Common.Http;
-using Aki.Custom.Airdrops.Models;
-using EFT;
+using EFT;
using EFT.Airdrop;
-using Fika.Core.AkiSupport.Airdrops.Models;
+using Fika.Core.Coop.Airdrops.Models;
using Newtonsoft.Json;
+using SPT.Common.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
-namespace Fika.Core.AkiSupport.Airdrops.Utils
+namespace Fika.Core.Coop.Airdrops.Utils
{
+ ///
+ /// Originally developed by SPT
+ ///
public static class FikaAirdropUtil
{
public static FikaAirdropConfigModel AirdropConfigModel { get; private set; }
@@ -119,7 +121,7 @@ public static FikaAirdropParametersModel InitAirdropParams(GameWorld gameWorld,
if (flareAirdropPoints.Count == 0 && isFlare)
{
- Debug.LogError($"[AKI-AIRDROPS]: Airdrop called in by flare, Unable to find an airdropPoint within 100m, defaulting to normal drop");
+ Debug.LogError($"[SPT-AIRDROPS]: Airdrop called in by flare, Unable to find an airdropPoint within 100m, defaulting to normal drop");
flareAirdropPoints.Add(allAirdropPoints.OrderBy(_ => Guid.NewGuid()).FirstOrDefault());
}
diff --git a/Fika.Core/AkiSupport/Airdrops/Utils/FikaItemFactoryUtil.cs b/Fika.Core/Coop/Airdrops/Utils/FikaItemFactoryUtil.cs
similarity index 87%
rename from Fika.Core/AkiSupport/Airdrops/Utils/FikaItemFactoryUtil.cs
rename to Fika.Core/Coop/Airdrops/Utils/FikaItemFactoryUtil.cs
index ad94d25e..b913db85 100644
--- a/Fika.Core/AkiSupport/Airdrops/Utils/FikaItemFactoryUtil.cs
+++ b/Fika.Core/Coop/Airdrops/Utils/FikaItemFactoryUtil.cs
@@ -1,16 +1,19 @@
-using Aki.Common.Http;
-using Aki.Custom.Airdrops.Models;
-using BepInEx.Logging;
+using BepInEx.Logging;
using Comfort.Common;
+using Coop.Airdrops;
using EFT;
using EFT.Interactive;
using EFT.InventoryLogic;
-using Fika.Core;
+using Fika.Core.Coop.Airdrops.Models;
using Newtonsoft.Json;
+using SPT.Common.Http;
using System.Linq;
-namespace Aki.Custom.Airdrops.Utils
+namespace Fika.Core.Coop.Airdrops.Utils
{
+ ///
+ /// Originally developed by SPT
+ ///
public class FikaItemFactoryUtil
{
private readonly ItemFactory itemFactory;
@@ -28,12 +31,12 @@ public void BuildContainer(LootableContainer container, FikaAirdropConfigModel c
if (itemFactory.ItemTemplates.TryGetValue(containerId, out ItemTemplate template))
{
Item item = itemFactory.CreateItem(containerId, template._id, null);
- item.Id = Singleton.Instance.MainPlayer.GClass2761_0.NextId;
+ item.Id = Singleton.Instance.MainPlayer.InventoryControllerClass.NextId;
LootItem.CreateLootContainer(container, item, "CRATE", Singleton.Instance);
}
else
{
- logSource.LogError($"[AKI-AIRDROPS]: unable to find template: {containerId}");
+ logSource.LogError($"[SPT-AIRDROPS]: unable to find template: {containerId}");
}
}
diff --git a/Fika.Core/Coop/BTR/FikaBTRManager_Client.cs b/Fika.Core/Coop/BTR/FikaBTRManager_Client.cs
index 1f06af9d..d709a9d8 100644
--- a/Fika.Core/Coop/BTR/FikaBTRManager_Client.cs
+++ b/Fika.Core/Coop/BTR/FikaBTRManager_Client.cs
@@ -1,7 +1,4 @@
-using Aki.Custom.BTR;
-using Aki.Custom.BTR.Utils;
-using Aki.SinglePlayer.Utils.TraderServices;
-using BepInEx.Logging;
+using BepInEx.Logging;
using Comfort.Common;
using EFT;
using EFT.AssetsManager;
@@ -13,6 +10,9 @@
using Fika.Core.Networking;
using HarmonyLib;
using LiteNetLib.Utils;
+using SPT.Custom.BTR;
+using SPT.Custom.BTR.Utils;
+using SPT.SinglePlayer.Utils.TraderServices;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -25,6 +25,9 @@
namespace Fika.Core.Coop.BTR
{
+ ///
+ /// Based on
+ ///
internal class FikaBTRManager_Client : MonoBehaviour
{
private GameWorld gameWorld;
@@ -37,9 +40,6 @@ internal class FikaBTRManager_Client : MonoBehaviour
private BTRDataPacket btrDataPacket = default;
private bool btrBotShooterInitialized = false;
- private Coroutine _coverFireTimerCoroutine;
-
- private Coroutine _shootingTargetCoroutine;
private BTRTurretServer btrTurretServer;
private bool isTurretInDefaultRotation;
private BulletClass btrMachineGunAmmo;
@@ -86,7 +86,7 @@ private void Awake()
}
catch
{
- btrLogger.LogError("[AKI-BTR] Unable to spawn BTR. Check logs.");
+ btrLogger.LogError("[SPT-BTR] Unable to spawn BTR. Check logs.");
Destroy(this);
throw;
}
@@ -112,7 +112,7 @@ public void OnPlayerInteractDoor(Player player, PlayerInteractPacket interactPac
// Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)`
private bool IsUpdateTaxiPriceMethod(MethodInfo method)
{
- return (method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination));
+ return method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination);
}
private void Update()
@@ -173,7 +173,7 @@ public void AttachBot(int netId)
weaponPrefab.transform.SetPositionAndRotation(turretView.GunRoot.position, turretView.GunRoot.rotation);
weaponTransform.SetPositionAndRotation(turretView.GunRoot.position, turretView.GunRoot.rotation);
- string[] gunModsToDisable = Traverse.Create(turretView).Field("_gunModsToDisable").GetValue();
+ string[] gunModsToDisable = Traverse.Create(turretView).Field("_gunModsToDisable").Value;
if (gunModsToDisable != null)
{
foreach (Transform child in weaponTransform)
@@ -234,7 +234,7 @@ private void InitBtr()
{
// Initial setup
botEventHandler = Singleton.Instance;
- var botsController = Singleton.Instance.BotsController;
+ BotsController botsController = Singleton.Instance.BotsController;
btrBotService = botsController.BotTradersServices.BTRServices;
btrController.method_3(); // spawns server-side BTR game object
//botsController.BotSpawner.SpawnBotBTR(); // spawns the scav bot which controls the BTR's turret
@@ -257,7 +257,7 @@ private void InitBtr()
btrServerSide.Initialization(btrMapConfig);*/
btrController.method_14(); // creates and assigns the BTR a fake stash
- DisableServerSideRenderers();
+ DisableServerSideObjects();
/*btrServerSide.MoveEnable();*/
btrServerSide.IncomingToDestinationEvent += ToDestinationEvent;
@@ -269,7 +269,7 @@ private void InitBtr()
// Initialise turret variables
btrTurretServer = btrServerSide.BTRTurret;
- var btrTurretDefaultTargetTransform = (Transform)AccessTools.Field(btrTurretServer.GetType(), "defaultTargetTransform").GetValue(btrTurretServer);
+ Transform btrTurretDefaultTargetTransform = (Transform)AccessTools.Field(btrTurretServer.GetType(), "defaultTargetTransform").GetValue(btrTurretServer);
isTurretInDefaultRotation = btrTurretServer.targetTransform == btrTurretDefaultTargetTransform
&& btrTurretServer.targetPosition == btrTurretServer.defaultAimingPosition;
btrMachineGunAmmo = (BulletClass)BTRUtil.CreateItem(BTRUtil.BTRMachineGunAmmoTplId);
@@ -281,7 +281,7 @@ private void InitBtr()
private void ConfigureSettingsFromServer()
{
- var serverConfig = BTRUtil.GetConfigFromServer();
+ SPT.Custom.BTR.Models.BTRConfigModel serverConfig = BTRUtil.GetConfigFromServer();
btrServerSide.moveSpeed = serverConfig.MoveSpeed;
btrServerSide.pauseDurationRange.x = serverConfig.PointWaitTime.Min;
@@ -360,8 +360,8 @@ private BTRDataPacket UpdateDataPacket()
btrDataPacket.rotation = btrServerSide.transform.rotation;
if (btrTurretServer != null && btrTurretServer.gunsBlockRoot != null)
{
- btrDataPacket.turretRotation = btrTurretServer.transform.rotation;
- btrDataPacket.gunsBlockRotation = btrTurretServer.gunsBlockRoot.rotation;
+ btrDataPacket.turretRotation = btrTurretServer.transform.localEulerAngles.y;
+ btrDataPacket.gunsBlockRotation = btrTurretServer.gunsBlockRoot.localEulerAngles.x;
}
btrDataPacket.State = (byte)btrServerSide.BtrState;
btrDataPacket.RouteState = (byte)btrServerSide.VehicleRouteState;
@@ -383,15 +383,28 @@ private BTRDataPacket UpdateDataPacket()
return btrDataPacket;
}
- private void DisableServerSideRenderers()
+ private void DisableServerSideObjects()
{
- var meshRenderers = btrServerSide.transform.GetComponentsInChildren();
- foreach (var renderer in meshRenderers)
+ MeshRenderer[] meshRenderers = btrServerSide.transform.GetComponentsInChildren();
+ foreach (MeshRenderer renderer in meshRenderers)
{
renderer.enabled = false;
}
btrServerSide.turnCheckerObject.GetComponent().enabled = false; // Disables the red debug sphere
+
+ // For some reason the client BTR collider is disabled but the server collider is enabled.
+ // Initially we assumed there was a reason for this so it was left as is.
+ // Turns out disabling the server collider in favour of the client collider fixes the "BTR doing a wheelie" bug,
+ // while preventing the player from walking through the BTR.
+ const string exteriorColliderName = "BTR_82_exterior_COLLIDER";
+ Collider serverExteriorCollider = btrServerSide.GetComponentsInChildren(true)
+ .First(x => x.gameObject.name == exteriorColliderName);
+ Collider clientExteriorCollider = btrClientSide.GetComponentsInChildren(true)
+ .First(x => x.gameObject.name == exteriorColliderName);
+
+ serverExteriorCollider.gameObject.SetActive(false);
+ clientExteriorCollider.gameObject.SetActive(true);
}
public void ClientInteraction(Player player, PlayerInteractPacket packet)
@@ -399,7 +412,7 @@ public void ClientInteraction(Player player, PlayerInteractPacket packet)
BTRView btrView = gameWorld.BtrController.BtrView;
if (btrView == null)
{
- btrLogger.LogError("[AKI-BTR] BTRInteractionPatch - btrView is null");
+ btrLogger.LogError("[SPT-BTR] BTRInteractionPatch - btrView is null");
return;
}
@@ -448,9 +461,6 @@ private void OnDestroy()
return;
}
- StaticManager.KillCoroutine(ref _shootingTargetCoroutine);
- StaticManager.KillCoroutine(ref _coverFireTimerCoroutine);
-
if (TraderServicesManager.Instance != null)
{
TraderServicesManager.Instance.OnTraderServicePurchased -= BtrTraderServicePurchased;
@@ -458,13 +468,13 @@ private void OnDestroy()
if (btrClientSide != null)
{
- Debug.LogWarning("[AKI-BTR] BTRManager - Destroying btrClientSide");
+ Debug.LogWarning("[SPT-BTR] BTRManager - Destroying btrClientSide");
Destroy(btrClientSide.gameObject);
}
if (btrServerSide != null)
{
- Debug.LogWarning("[AKI-BTR] BTRManager - Destroying btrServerSide");
+ Debug.LogWarning("[SPT-BTR] BTRManager - Destroying btrServerSide");
Destroy(btrServerSide.gameObject);
}
}
diff --git a/Fika.Core/Coop/BTR/FikaBTRManager_Host.cs b/Fika.Core/Coop/BTR/FikaBTRManager_Host.cs
index b5bcbb52..b199b8f2 100644
--- a/Fika.Core/Coop/BTR/FikaBTRManager_Host.cs
+++ b/Fika.Core/Coop/BTR/FikaBTRManager_Host.cs
@@ -1,7 +1,4 @@
-using Aki.Custom.BTR;
-using Aki.Custom.BTR.Utils;
-using Aki.SinglePlayer.Utils.TraderServices;
-using BepInEx.Logging;
+using BepInEx.Logging;
using Comfort.Common;
using EFT;
using EFT.GlobalEvents;
@@ -13,6 +10,9 @@
using HarmonyLib;
using LiteNetLib;
using LiteNetLib.Utils;
+using SPT.Custom.BTR;
+using SPT.Custom.BTR.Utils;
+using SPT.SinglePlayer.Utils.TraderServices;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -24,6 +24,9 @@
namespace Fika.Core.Coop.BTR
{
+ ///
+ /// Based on
+ ///
internal class FikaBTRManager_Host : MonoBehaviour
{
private GameWorld gameWorld;
@@ -108,7 +111,7 @@ private void Awake()
}
catch
{
- btrLogger.LogError("[AKI-BTR] Unable to spawn BTR. Check logs.");
+ btrLogger.LogError("[SPT-BTR] Unable to spawn BTR. Check logs.");
Destroy(this);
throw;
}
@@ -223,7 +226,7 @@ public void OnPlayerInteractDoor(Player player, PlayerInteractPacket interactPac
// Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)`
private bool IsUpdateTaxiPriceMethod(MethodInfo method)
{
- return (method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination));
+ return method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination);
}
private void Update()
@@ -260,7 +263,7 @@ private void InitBtr()
{
// Initial setup
botEventHandler = Singleton.Instance;
- var botsController = Singleton.Instance.BotsController;
+ BotsController botsController = Singleton.Instance.BotsController;
btrBotService = botsController.BotTradersServices.BTRServices;
btrController.method_3(); // spawns server-side BTR game object
botsController.BotSpawner.SpawnBotBTR(); // spawns the scav bot which controls the BTR's turret
@@ -278,12 +281,12 @@ private void InitBtr()
// Get config from server and initialise respective settings
ConfigureSettingsFromServer();
- var btrMapConfig = btrController.MapPathsConfiguration;
+ MapPathConfig btrMapConfig = btrController.MapPathsConfiguration;
btrServerSide.CurrentPathConfig = btrMapConfig.PathsConfiguration.pathsConfigurations.RandomElement();
btrServerSide.Initialization(btrMapConfig);
btrController.method_14(); // creates and assigns the BTR a fake stash
- DisableServerSideRenderers();
+ DisableServerSideObjects();
gameWorld.MainPlayer.OnBtrStateChanged += HandleBtrDoorState;
@@ -297,7 +300,7 @@ private void InitBtr()
// Initialise turret variables
btrTurretServer = btrServerSide.BTRTurret;
- var btrTurretDefaultTargetTransform = (Transform)AccessTools.Field(btrTurretServer.GetType(), "defaultTargetTransform").GetValue(btrTurretServer);
+ Transform btrTurretDefaultTargetTransform = (Transform)AccessTools.Field(btrTurretServer.GetType(), "defaultTargetTransform").GetValue(btrTurretServer);
isTurretInDefaultRotation = btrTurretServer.targetTransform == btrTurretDefaultTargetTransform
&& btrTurretServer.targetPosition == btrTurretServer.defaultAimingPosition;
btrMachineGunAmmo = (BulletClass)BTRUtil.CreateItem(BTRUtil.BTRMachineGunAmmoTplId);
@@ -311,7 +314,7 @@ private void InitBtr()
private void ConfigureSettingsFromServer()
{
- var serverConfig = BTRUtil.GetConfigFromServer();
+ SPT.Custom.BTR.Models.BTRConfigModel serverConfig = BTRUtil.GetConfigFromServer();
btrServerSide.moveSpeed = serverConfig.MoveSpeed;
btrServerSide.pauseDurationRange.x = serverConfig.PointWaitTime.Min;
@@ -327,7 +330,7 @@ private void InitBtrBotService()
{
btrBotShooter = btrController.BotShooterBtr;
firearmController = btrBotShooter.GetComponent();
- var weaponPrefab = (WeaponPrefab)AccessTools.Field(firearmController.GetType(), "weaponPrefab_0").GetValue(firearmController);
+ WeaponPrefab weaponPrefab = (WeaponPrefab)AccessTools.Field(firearmController.GetType(), "weaponPrefab_0").GetValue(firearmController);
weaponSoundPlayer = weaponPrefab.GetComponent();
btrBotService.Reset(); // Player will be added to Neutrals list and removed from Enemies list
@@ -434,7 +437,7 @@ private void StartCoverFireTimer(float time)
private IEnumerator CoverFireTimer(float time)
{
- yield return new WaitForSecondsRealtime(time);
+ yield return new WaitForSeconds(time);
botEventHandler.StopTraderServiceBtrSupport();
}
@@ -470,7 +473,7 @@ private void UpdateBTRSideDoorState(byte state)
}
catch
{
- btrLogger.LogError("[AKI-BTR] lastInteractedBtrSide is null when it shouldn't be. Check logs.");
+ btrLogger.LogError("[SPT-BTR] lastInteractedBtrSide is null when it shouldn't be. Check logs.");
throw;
}
}
@@ -481,8 +484,8 @@ private BTRDataPacket UpdateDataPacket()
btrDataPacket.rotation = btrServerSide.transform.rotation;
if (btrTurretServer != null && btrTurretServer.gunsBlockRoot != null)
{
- btrDataPacket.turretRotation = btrTurretServer.transform.rotation;
- btrDataPacket.gunsBlockRotation = btrTurretServer.gunsBlockRoot.rotation;
+ btrDataPacket.turretRotation = btrTurretServer.transform.localEulerAngles.y;
+ btrDataPacket.gunsBlockRotation = btrTurretServer.gunsBlockRoot.localEulerAngles.x;
}
btrDataPacket.State = (byte)btrServerSide.BtrState;
btrDataPacket.RouteState = (byte)btrServerSide.VehicleRouteState;
@@ -520,15 +523,28 @@ private BTRDataPacket UpdateDataPacket()
return btrDataPacket;
}
- private void DisableServerSideRenderers()
+ private void DisableServerSideObjects()
{
- var meshRenderers = btrServerSide.transform.GetComponentsInChildren();
- foreach (var renderer in meshRenderers)
+ MeshRenderer[] meshRenderers = btrServerSide.transform.GetComponentsInChildren();
+ foreach (MeshRenderer renderer in meshRenderers)
{
renderer.enabled = false;
}
btrServerSide.turnCheckerObject.GetComponent().enabled = false; // Disables the red debug sphere
+
+ // For some reason the client BTR collider is disabled but the server collider is enabled.
+ // Initially we assumed there was a reason for this so it was left as is.
+ // Turns out disabling the server collider in favour of the client collider fixes the "BTR doing a wheelie" bug,
+ // while preventing the player from walking through the BTR.
+ const string exteriorColliderName = "BTR_82_exterior_COLLIDER";
+ Collider serverExteriorCollider = btrServerSide.GetComponentsInChildren(true)
+ .First(x => x.gameObject.name == exteriorColliderName);
+ Collider clientExteriorCollider = btrClientSide.GetComponentsInChildren(true)
+ .First(x => x.gameObject.name == exteriorColliderName);
+
+ serverExteriorCollider.gameObject.SetActive(false);
+ clientExteriorCollider.gameObject.SetActive(true);
}
private void UpdateTarget()
@@ -596,7 +612,7 @@ private IEnumerator ShootMachineGun()
{
isShooting = true;
- yield return new WaitForSecondsRealtime(machineGunAimDelay);
+ yield return new WaitForSeconds(machineGunAimDelay);
if (currentTarget?.Person == null || currentTarget?.IsVisible == false || !btrBotShooter.BotBtrData.CanShoot())
{
isShooting = false;
@@ -604,7 +620,7 @@ private IEnumerator ShootMachineGun()
}
Transform machineGunMuzzle = btrTurretServer.machineGunLaunchPoint;
- var ballisticCalculator = gameWorld.SharedBallisticsCalculator;
+ ISharedBallisticsCalculator ballisticCalculator = gameWorld.SharedBallisticsCalculator;
int burstMin = Mathf.FloorToInt(machineGunBurstCount.x);
int burstMax = Mathf.FloorToInt(machineGunBurstCount.y);
@@ -622,11 +638,11 @@ private IEnumerator ShootMachineGun()
firearmController.method_54(weaponSoundPlayer, btrMachineGunAmmo, machineGunMuzzle.position, aimDirection, false);
burstCount--;
shotQueue.Enqueue(new(machineGunMuzzle.position, aimDirection));
- yield return new WaitForSecondsRealtime(0.092308f); // 650 RPM
+ yield return new WaitForSeconds(0.092308f); // 650 RPM
}
float waitTime = Random.Range(machineGunRecoveryTime.x, machineGunRecoveryTime.y);
- yield return new WaitForSecondsRealtime(waitTime);
+ yield return new WaitForSeconds(waitTime);
isShooting = false;
}
@@ -649,7 +665,7 @@ public bool HostInteraction(Player player, PlayerInteractPacket packet)
BTRView btrView = gameWorld.BtrController.BtrView;
if (btrView == null)
{
- btrLogger.LogError("[AKI-BTR] BTRInteractionPatch - btrView is null");
+ btrLogger.LogError("[SPT-BTR] BTRInteractionPatch - btrView is null");
return false;
}
@@ -668,7 +684,7 @@ public void HostObservedInteraction(Player player, PlayerInteractPacket packet)
BTRView btrView = gameWorld.BtrController.BtrView;
if (btrView == null)
{
- btrLogger.LogError("[AKI-BTR] BTRInteractionPatch - btrView is null");
+ btrLogger.LogError("[SPT-BTR] BTRInteractionPatch - btrView is null");
return;
}
@@ -736,13 +752,13 @@ private void OnDestroy()
if (btrClientSide != null)
{
- Debug.LogWarning("[AKI-BTR] BTRManager - Destroying btrClientSide");
+ Debug.LogWarning("[SPT-BTR] BTRManager - Destroying btrClientSide");
Destroy(btrClientSide.gameObject);
}
if (btrServerSide != null)
{
- Debug.LogWarning("[AKI-BTR] BTRManager - Destroying btrServerSide");
+ Debug.LogWarning("[SPT-BTR] BTRManager - Destroying btrServerSide");
Destroy(btrServerSide.gameObject);
}
}
diff --git a/Fika.Core/Coop/BotClasses/CoopBotHealthController.cs b/Fika.Core/Coop/BotClasses/CoopBotHealthController.cs
index 15c779f2..4f105cb4 100644
--- a/Fika.Core/Coop/BotClasses/CoopBotHealthController.cs
+++ b/Fika.Core/Coop/BotClasses/CoopBotHealthController.cs
@@ -6,7 +6,7 @@
namespace Fika.Core.Coop.ClientClasses
{
- public sealed class CoopBotHealthController(Profile.GClass1756 healthInfo, Player player, InventoryControllerClass inventoryController, SkillManager skillManager, bool aiHealth)
+ public sealed class CoopBotHealthController(Profile.ProfileHealthClass healthInfo, Player player, InventoryControllerClass inventoryController, SkillManager skillManager, bool aiHealth)
: PlayerHealthController(healthInfo, player, inventoryController, skillManager, aiHealth)
{
private readonly CoopBot coopBot = (CoopBot)player;
diff --git a/Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs b/Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs
index 03410663..8afa6310 100644
--- a/Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs
+++ b/Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs
@@ -14,7 +14,7 @@ public class CoopBotInventoryController(Player player, Profile profile, bool exa
{
private readonly CoopBot CoopBot = (CoopBot)player;
- public override void Execute(GClass2837 operation, [CanBeNull] Callback callback)
+ public override void Execute(GClass2854 operation, [CanBeNull] Callback callback)
{
base.Execute(operation, callback);
@@ -25,7 +25,7 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
- binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
+ binaryWriter.WritePolymorph(FromObjectAbstractClass.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
{
diff --git a/Fika.Core/Coop/ClientClasses/CoopClientHealthController.cs b/Fika.Core/Coop/ClientClasses/CoopClientHealthController.cs
index 1263336e..849dcce2 100644
--- a/Fika.Core/Coop/ClientClasses/CoopClientHealthController.cs
+++ b/Fika.Core/Coop/ClientClasses/CoopClientHealthController.cs
@@ -6,7 +6,7 @@
namespace Fika.Core.Coop.ClientClasses
{
- public sealed class CoopClientHealthController(Profile.GClass1756 healthInfo, Player player, InventoryControllerClass inventoryController, SkillManager skillManager, bool aiHealth)
+ public sealed class CoopClientHealthController(Profile.ProfileHealthClass healthInfo, Player player, InventoryControllerClass inventoryController, SkillManager skillManager, bool aiHealth)
: PlayerHealthController(healthInfo, player, inventoryController, skillManager, aiHealth)
{
private readonly CoopPlayer coopPlayer = (CoopPlayer)player;
diff --git a/Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs b/Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs
index ae5d9882..9409d432 100644
--- a/Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs
+++ b/Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs
@@ -3,9 +3,10 @@
using EFT;
using EFT.InventoryLogic;
using EFT.UI;
-using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
using Fika.Core.Networking;
+using Fika.Core.Networking.Packets;
using JetBrains.Annotations;
using System.IO;
using UnityEngine;
@@ -15,9 +16,7 @@ namespace Fika.Core.Coop.ClientClasses
public sealed class CoopClientInventoryController(Player player, Profile profile, bool examined) : Player.PlayerOwnerInventoryController(player, profile, examined)
{
public override bool HasDiscardLimits => false;
-
ManualLogSource BepInLogger { get; set; } = BepInEx.Logging.Logger.CreateLogSource(nameof(CoopClientInventoryController));
-
private readonly Player Player = player;
private CoopPlayer CoopPlayer => (CoopPlayer)Player;
@@ -30,27 +29,44 @@ public override void CallMalfunctionRepaired(Weapon weapon)
}
}
- public override void Execute(GClass2837 operation, [CanBeNull] Callback callback)
+ public override void Execute(GClass2854 operation, [CanBeNull] Callback callback)
{
- // Do not replicate picking up quest items, throws an error on the other clients
- if (operation is GClass2839 pickupOperation)
+#if DEBUG
+ ConsoleScreen.Log("InvOperation: " + operation.GetType().Name);
+#endif
+
+ // Do not replicate picking up quest items, throws an error on the other clients
+ if (operation is InventoryItemFromToClass moveOperation)
{
- if (pickupOperation.Item.Template.QuestItem)
+ Item lootedItem = moveOperation.Item;
+ if (lootedItem.Template.QuestItem)
{
+ if (CoopPlayer.AbstractQuestControllerClass is CoopClientSharedQuestController sharedQuestController)
+ {
+ if (!sharedQuestController.CheckForTemplateId(lootedItem.TemplateId))
+ {
+ sharedQuestController.AddLootedTemplateId(lootedItem.TemplateId);
+
+ // We use templateId because each client gets a unique itemId
+ QuestItemPacket packet = new(CoopPlayer.Profile.Info.MainProfileNickname, lootedItem.TemplateId);
+ CoopPlayer.PacketSender.SendQuestItemPacket(ref packet);
+ }
+ }
base.Execute(operation, callback);
return;
}
}
- if (MatchmakerAcceptPatches.IsServer)
+ // Do not replicate quest operations
+ // Check for GClass increments
+ if (operation is GClass2897 or GClass2898 or QuestHandoverOperationClass)
{
- // Do not replicate quest operations
- if (operation is GClass2866 or GClass2879)
- {
- base.Execute(operation, callback);
- return;
- }
+ base.Execute(operation, callback);
+ return;
+ }
+ if (FikaBackendUtils.IsServer)
+ {
HostInventoryOperationManager operationManager = new(this, operation, callback);
if (vmethod_0(operationManager.operation))
{
@@ -63,7 +79,7 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
- binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
+ binaryWriter.WritePolymorph(FromObjectAbstractClass.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
{
@@ -78,15 +94,8 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
operationManager.operation.Dispose();
operationManager.callback?.Fail($"Can't execute {operationManager.operation}", 1);
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else if (FikaBackendUtils.IsClient)
{
- // Do not replicate quest operations
- if (operation is GClass2866 or GClass2879)
- {
- base.Execute(operation, callback);
- return;
- }
-
InventoryPacket packet = new()
{
HasItemControllerExecutePacket = true
@@ -99,12 +108,12 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
inventoryController = this
};
- clientOperationManager.callback ??= new Callback(ClientPlayer.Control0.Class1400.class1400_0.method_0);
+ clientOperationManager.callback ??= new Callback(ClientPlayer.Control0.Class1426.class1426_0.method_0);
uint operationNum = AddOperationCallback(operation, new Callback(clientOperationManager.HandleResult));
using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
- binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
+ binaryWriter.WritePolymorph(FromObjectAbstractClass.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
{
@@ -116,17 +125,17 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
}
}
- private uint AddOperationCallback(GClass2837 operation, Callback callback)
+ private uint AddOperationCallback(GClass2854 operation, Callback callback)
{
ushort id = operation.Id;
CoopPlayer.OperationCallbacks.Add(id, callback);
return id;
}
- private class HostInventoryOperationManager(CoopClientInventoryController inventoryController, GClass2837 operation, Callback callback)
+ private class HostInventoryOperationManager(CoopClientInventoryController inventoryController, GClass2854 operation, Callback callback)
{
public readonly CoopClientInventoryController inventoryController = inventoryController;
- public GClass2837 operation = operation;
+ public GClass2854 operation = operation;
public readonly Callback callback = callback;
public void HandleResult(IResult result)
@@ -143,7 +152,7 @@ private class ClientInventoryOperationManager
{
public EOperationStatus? serverOperationStatus;
public EOperationStatus? localOperationStatus;
- public GClass2837 operation;
+ public GClass2854 operation;
public Callback callback;
public CoopClientInventoryController inventoryController;
diff --git a/Fika.Core/Coop/ClientClasses/CoopClientSharedQuestController.cs b/Fika.Core/Coop/ClientClasses/CoopClientSharedQuestController.cs
new file mode 100644
index 00000000..56380e36
--- /dev/null
+++ b/Fika.Core/Coop/ClientClasses/CoopClientSharedQuestController.cs
@@ -0,0 +1,177 @@
+using EFT;
+using EFT.InventoryLogic;
+using EFT.Quests;
+using Fika.Core.Coop.Players;
+using Fika.Core.Networking.Packets;
+using System;
+using System.Collections.Generic;
+
+namespace Fika.Core.Coop.ClientClasses
+{
+ public sealed class CoopClientSharedQuestController(Profile profile, InventoryControllerClass inventoryController,
+ IQuestActions session, CoopPlayer player, bool fromServer = true) : LocalQuestControllerClass(profile, inventoryController, session, fromServer)
+ {
+ private readonly CoopPlayer player = player;
+ private readonly List lastFromNetwork = [];
+ private readonly HashSet acceptedTypes = [];
+ private readonly HashSet lootedTemplateIds = [];
+
+ public override void Init()
+ {
+ base.Init();
+ foreach (FikaPlugin.EQuestSharingTypes shareType in (FikaPlugin.EQuestSharingTypes[])Enum.GetValues(typeof(FikaPlugin.EQuestSharingTypes)))
+ {
+ if (FikaPlugin.QuestTypesToShareAndReceive.Value.HasFlag(shareType))
+ {
+ switch (shareType)
+ {
+ case FikaPlugin.EQuestSharingTypes.Kill:
+ acceptedTypes.Add("Elimination");
+ acceptedTypes.Add(shareType.ToString());
+ break;
+ case FikaPlugin.EQuestSharingTypes.Item:
+ acceptedTypes.Add("FindItem");
+ break;
+ case FikaPlugin.EQuestSharingTypes.Location:
+ acceptedTypes.Add("Exploration");
+ acceptedTypes.Add("Discover");
+ acceptedTypes.Add("VisitPlace");
+ acceptedTypes.Add(shareType.ToString());
+ break;
+ case FikaPlugin.EQuestSharingTypes.PlaceBeacon:
+ acceptedTypes.Add(shareType.ToString());
+ break;
+ }
+ }
+ }
+ }
+
+ public override void OnConditionValueChanged(IConditionCounter conditional, EQuestStatus status, Condition condition, bool notify = true)
+ {
+ base.OnConditionValueChanged(conditional, status, condition, notify);
+ if (lastFromNetwork.Contains(condition.id))
+ {
+ lastFromNetwork.Remove(condition.id);
+ return;
+ }
+ SendQuestPacket(conditional, condition);
+ }
+
+ public void AddNetworkId(string id)
+ {
+ if (!lastFromNetwork.Contains(id))
+ {
+ lastFromNetwork.Add(id);
+ }
+ }
+
+ public void AddLootedTemplateId(string templateId)
+ {
+ if (!lootedTemplateIds.Contains(templateId))
+ {
+ lootedTemplateIds.Add(templateId);
+ }
+ }
+
+ public bool CheckForTemplateId(string templateId)
+ {
+ return lootedTemplateIds.Contains(templateId);
+ }
+
+ private void SendQuestPacket(IConditionCounter conditional, Condition condition)
+ {
+ if (conditional is QuestClass quest)
+ {
+ TaskConditionCounterClass counter = quest.ConditionCountersManager.GetCounter(condition.id);
+ if (counter != null)
+ {
+ if (!ValidateQuestType(counter))
+ {
+ return;
+ }
+
+ QuestConditionPacket packet = new(player.Profile.Info.MainProfileNickname, counter.Id, counter.SourceId);
+#if DEBUG
+ FikaPlugin.Instance.FikaLogger.LogInfo("SendQuestPacket: Sending quest progress");
+#endif
+ player.PacketSender.SendQuestPacket(ref packet);
+ }
+ }
+ }
+
+ internal void ReceiveQuestPacket(ref QuestConditionPacket packet)
+ {
+ AddNetworkId(packet.Id);
+ foreach (QuestClass quest in Quests)
+ {
+ if (quest.Id == packet.SourceId && quest.QuestStatus == EQuestStatus.Started)
+ {
+ TaskConditionCounterClass counter = quest.ConditionCountersManager.GetCounter(packet.Id);
+ if (counter != null && !quest.CompletedConditions.Contains(counter.Id))
+ {
+ if (!ValidateQuestType(counter))
+ {
+ return;
+ }
+
+ counter.Value++;
+ NotificationManagerClass.DisplayMessageNotification($"Received shared quest progression from {packet.Nickname}",
+ iconType: EFT.Communications.ENotificationIconType.Quest);
+ }
+ }
+ }
+ }
+
+ internal void ReceiveQuestItemPacket(ref QuestItemPacket packet)
+ {
+ if (!string.IsNullOrEmpty(packet.ItemId))
+ {
+ Item item = player.FindItem(packet.ItemId, true);
+ if (item != null)
+ {
+ InventoryControllerClass playerInventory = player.InventoryControllerClass;
+ GStruct414 pickupResult = InteractionsHandlerClass.QuickFindAppropriatePlace(item, playerInventory,
+ playerInventory.Inventory.Equipment.ToEnumerable(),
+ InteractionsHandlerClass.EMoveItemOrder.PickUp, true);
+
+ if (pickupResult.Succeeded && playerInventory.CanExecute(pickupResult.Value))
+ {
+ AddLootedTemplateId(item.TemplateId);
+ playerInventory.RunNetworkTransaction(pickupResult.Value);
+ NotificationManagerClass.DisplayMessageNotification($"{packet.Nickname} picked up {item.Name.Localized()}",
+ iconType: EFT.Communications.ENotificationIconType.Quest);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Validates quest typing, some quests use CounterCreator which we also need to validate.
+ ///
+ /// The counter to validate
+ /// Returns true if the quest type is valid, returns false if not
+ internal bool ValidateQuestType(TaskConditionCounterClass counter)
+ {
+ if (acceptedTypes.Contains(counter.Type))
+ {
+ return true;
+ }
+
+ if (counter.Type == "CounterCreator")
+ {
+ ConditionCounterCreator CounterCreator = (ConditionCounterCreator)counter.Template;
+
+#if DEBUG
+ FikaPlugin.Instance.FikaLogger.LogInfo($"CoopClientSharedQuestController:: ValidateQuestType: CounterCreator Type {CounterCreator.type}");
+#endif
+
+ if (acceptedTypes.Contains(CounterCreator.type.ToString()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/Fika.Core/Coop/ClientClasses/CoopClientStatisticsManager.cs b/Fika.Core/Coop/ClientClasses/CoopClientStatisticsManager.cs
index ee90a2ee..3aedb6c2 100644
--- a/Fika.Core/Coop/ClientClasses/CoopClientStatisticsManager.cs
+++ b/Fika.Core/Coop/ClientClasses/CoopClientStatisticsManager.cs
@@ -3,7 +3,7 @@
namespace Fika.Core.Coop.ClientClasses
{
- public sealed class CoopClientStatisticsManager(Profile profile) : GClass1790()
+ public sealed class CoopClientStatisticsManager(Profile profile) : LocationStatisticsCollectorAbstractClass()
{
public Profile Profile = profile;
@@ -17,7 +17,7 @@ public override void ShowStatNotification(LocalizationKey localizationKey1, Loca
{
if (value > 0)
{
- NotificationManagerClass.DisplayNotification(new GClass2040(localizationKey1, localizationKey2, value));
+ NotificationManagerClass.DisplayNotification(new StatNotificationClass(localizationKey1, localizationKey2, value));
}
}
}
diff --git a/Fika.Core/Coop/ClientClasses/HandsControllers/CoopClientFirearmController.cs b/Fika.Core/Coop/ClientClasses/HandsControllers/CoopClientFirearmController.cs
index d9db7d8b..819418e0 100644
--- a/Fika.Core/Coop/ClientClasses/HandsControllers/CoopClientFirearmController.cs
+++ b/Fika.Core/Coop/ClientClasses/HandsControllers/CoopClientFirearmController.cs
@@ -47,7 +47,7 @@ public override Dictionary GetOperationFactoryDe
return operationFactoryDelegates;
}
- public Player.GClass1583 Weapon1()
+ public Player.GClass1594 Weapon1()
{
if (Item.ReloadMode == Weapon.EReloadMode.InternalMagazine && Item.Chambers.Length == 0)
{
@@ -60,32 +60,32 @@ public Player.GClass1583 Weapon1()
return new FirearmClass2(this);
}
- public Player.GClass1583 Weapon2()
+ public Player.GClass1594 Weapon2()
{
return new FirearmClass1(this);
}
- public Player.GClass1583 Weapon3()
+ public Player.GClass1594 Weapon3()
{
if (Item.IsFlareGun)
{
- return new GClass1605(this);
+ return new GClass1616(this);
}
if (Item.IsOneOff)
{
- return new GClass1607(this);
+ return new GClass1618(this);
}
if (Item.ReloadMode == Weapon.EReloadMode.OnlyBarrel)
{
- return new GClass1604(this);
+ return new GClass1615(this);
}
- if (Item is GClass2696)
+ if (Item is GClass2711)
{
- return new GClass1603(this);
+ return new GClass1614(this);
}
if (!Item.BoltAction)
{
- return new GClass1601(this);
+ return new GClass1612(this);
}
return new FirearmClass4(this);
}
@@ -176,7 +176,6 @@ public override void DryShot(int chamberIndex = 0, bool underbarrelShot = false)
HasShotInfo = true,
ShotInfoPacket = new()
{
- IsPrimaryActive = true,
ShotType = EShotType.DryFire,
AmmoAfterShot = underbarrelShot ? 0 : Item.GetCurrentMagazineCount(),
ChamberIndex = chamberIndex,
@@ -198,9 +197,9 @@ public override bool ExamineWeapon()
return flag;
}
- public override void InitiateShot(GInterface322 weapon, BulletClass ammo, Vector3 shotPosition, Vector3 shotDirection, Vector3 fireportPosition, int chamberIndex, float overheat)
+ public override void InitiateShot(IWeapon weapon, BulletClass ammo, Vector3 shotPosition, Vector3 shotDirection, Vector3 fireportPosition, int chamberIndex, float overheat)
{
- EShotType shotType = new();
+ EShotType shotType = default;
switch (weapon.MalfState.State)
{
@@ -229,7 +228,6 @@ public override void InitiateShot(GInterface322 weapon, BulletClass ammo, Vector
HasShotInfo = true,
ShotInfoPacket = new()
{
- IsPrimaryActive = (weapon == Item),
ShotType = shotType,
AmmoAfterShot = weapon.GetCurrentMagazineCount(),
ShotPosition = shotPosition,
@@ -270,7 +268,7 @@ public override void QuickReloadMag(MagazineClass magazine, Callback callback)
});
}
- public override void ReloadBarrels(GClass2495 ammoPack, GClass2769 placeToPutContainedAmmoMagazine, Callback callback)
+ public override void ReloadBarrels(AmmoPackReloadingClass ammoPack, ItemAddressClass placeToPutContainedAmmoMagazine, Callback callback)
{
if (!CanStartReload() && ammoPack.AmmoCount < 1)
{
@@ -281,7 +279,7 @@ public override void ReloadBarrels(GClass2495 ammoPack, GClass2769 placeToPutCon
CurrentOperation.ReloadBarrels(ammoPack, placeToPutContainedAmmoMagazine, callback, new Callback(handler.Process));
}
- public override void ReloadCylinderMagazine(GClass2495 ammoPack, Callback callback, bool quickReload = false)
+ public override void ReloadCylinderMagazine(AmmoPackReloadingClass ammoPack, Callback callback, bool quickReload = false)
{
if (Blindfire)
{
@@ -301,46 +299,28 @@ public override void ReloadCylinderMagazine(GClass2495 ammoPack, Callback callba
CurrentOperation.ReloadCylinderMagazine(ammoPack, callback, new Callback(handler.Process), handler.quickReload);
}
- public override void ReloadGrenadeLauncher(GClass2495 ammoPack, Callback callback)
+ public override void ReloadGrenadeLauncher(AmmoPackReloadingClass ammoPack, Callback callback)
{
if (!CanStartReload())
{
return;
}
+ CurrentOperation.ReloadGrenadeLauncher(ammoPack, callback);
+
string[] reloadingAmmoIds = ammoPack.GetReloadingAmmoIds();
+
coopPlayer.PacketSender.FirearmPackets.Enqueue(new()
{
- HasReloadLauncherPacket = true,
ReloadLauncher = new()
{
Reload = true,
AmmoIds = reloadingAmmoIds
}
});
-
- CurrentOperation.ReloadGrenadeLauncher(ammoPack, callback);
- }
-
- public override void UnderbarrelSightingRangeUp()
- {
- coopPlayer.PacketSender.FirearmPackets.Enqueue(new()
- {
- UnderbarrelSightingRangeUp = true
- });
- base.UnderbarrelSightingRangeUp();
- }
-
- public override void UnderbarrelSightingRangeDown()
- {
- coopPlayer.PacketSender.FirearmPackets.Enqueue(new()
- {
- UnderbarrelSightingRangeDown = true
- });
- base.UnderbarrelSightingRangeDown();
}
- public override void ReloadMag(MagazineClass magazine, GClass2769 gridItemAddress, Callback callback)
+ public override void ReloadMag(MagazineClass magazine, ItemAddressClass gridItemAddress, Callback callback)
{
if (!CanStartReload() || Blindfire)
{
@@ -351,7 +331,7 @@ public override void ReloadMag(MagazineClass magazine, GClass2769 gridItemAddres
CurrentOperation.ReloadMag(magazine, gridItemAddress, callback, new Callback(handler.Process));
}
- public override void ReloadWithAmmo(GClass2495 ammoPack, Callback callback)
+ public override void ReloadWithAmmo(AmmoPackReloadingClass ammoPack, Callback callback)
{
if (Item.GetCurrentMagazine() == null)
{
@@ -366,7 +346,7 @@ public override void ReloadWithAmmo(GClass2495 ammoPack, Callback callback)
CurrentOperation.ReloadWithAmmo(ammoPack, callback, new Callback(handler.Process));
}
- public override void SetLightsState(GStruct163[] lightsStates, bool force = false)
+ public override void SetLightsState(FirearmLightStateStruct[] lightsStates, bool force = false)
{
if (force || CurrentOperation.CanChangeLightState(lightsStates))
{
@@ -383,7 +363,24 @@ public override void SetLightsState(GStruct163[] lightsStates, bool force = fals
base.SetLightsState(lightsStates, force);
}
- public override void SetScopeMode(GStruct164[] scopeStates)
+ public override void SetScopeMode(FirearmScopeStateStruct[] scopeStates)
+ {
+ SendScopeStates(scopeStates);
+ base.SetScopeMode(scopeStates);
+ }
+ public override void OpticCalibrationSwitchUp(FirearmScopeStateStruct[] scopeStates)
+ {
+ SendScopeStates(scopeStates);
+ base.OpticCalibrationSwitchUp(scopeStates);
+ }
+
+ public override void OpticCalibrationSwitchDown(FirearmScopeStateStruct[] scopeStates)
+ {
+ SendScopeStates(scopeStates);
+ base.OpticCalibrationSwitchDown(scopeStates);
+ }
+
+ private void SendScopeStates(FirearmScopeStateStruct[] scopeStates)
{
SendScopeStates(scopeStates);
base.SetScopeMode(scopeStates);
@@ -413,7 +410,7 @@ private void SendScopeStates(GStruct164[] scopeStates)
ScopeStatesPacket = new()
{
Amount = scopeStates.Length,
- GStruct164 = scopeStates
+ FirearmScopeStateStruct = scopeStates
}
});
}
@@ -446,7 +443,6 @@ public override void ShotMisfired(BulletClass ammo, Weapon.EMalfunctionState mal
HasShotInfo = true,
ShotInfoPacket = new()
{
- IsPrimaryActive = true,
ShotType = shotType,
AmmoAfterShot = Item.GetCurrentMagazineCount(),
Overheat = overheat,
@@ -571,7 +567,7 @@ private void SendBoltActionReloadPacket()
});
}
- private class FirearmClass1(Player.FirearmController controller) : GClass1589(controller)
+ private class FirearmClass1(Player.FirearmController controller) : GClass1600(controller)
{
public override void SetTriggerPressed(bool pressed)
{
@@ -593,7 +589,7 @@ public override void SwitchToIdle()
private CoopClientFirearmController coopClientFirearmController = (CoopClientFirearmController)controller;
}
- private class FirearmClass2(Player.FirearmController controller) : GClass1590(controller)
+ private class FirearmClass2(Player.FirearmController controller) : GClass1600(controller)
{
public override void SetTriggerPressed(bool pressed)
{
@@ -614,7 +610,7 @@ public override void SwitchToIdle()
private readonly CoopClientFirearmController coopClientFirearmController = (CoopClientFirearmController)controller;
}
- private class FirearmClass3(Player.FirearmController controller) : GClass1591(controller)
+ private class FirearmClass3(Player.FirearmController controller) : GClass1601(controller)
{
public override void SetTriggerPressed(bool pressed)
{
@@ -635,7 +631,7 @@ public override void SwitchToIdle()
private readonly CoopClientFirearmController coopClientFirearmController = (CoopClientFirearmController)controller;
}
- private class FirearmClass4(Player.FirearmController controller) : GClass1602(controller)
+ private class FirearmClass4(Player.FirearmController controller) : GClass1612(controller)
{
public override void Start()
{
@@ -655,7 +651,7 @@ public override void SetInventoryOpened(bool opened)
SendBoltActionReloadPacket(true);
}
- public override void ReloadMag(MagazineClass magazine, GClass2769 gridItemAddress, Callback finishCallback, Callback startCallback)
+ public override void ReloadMag(MagazineClass magazine, ItemAddressClass gridItemAddress, Callback finishCallback, Callback startCallback)
{
base.ReloadMag(magazine, gridItemAddress, finishCallback, startCallback);
SendBoltActionReloadPacket(true);
@@ -667,7 +663,7 @@ public override void QuickReloadMag(MagazineClass magazine, Callback finishCallb
SendBoltActionReloadPacket(true);
}
- public override void ReloadWithAmmo(GClass2495 ammoPack, Callback finishCallback, Callback startCallback)
+ public override void ReloadWithAmmo(AmmoPackReloadingClass ammoPack, Callback finishCallback, Callback startCallback)
{
base.ReloadWithAmmo(ammoPack, finishCallback, startCallback);
SendBoltActionReloadPacket(true);
@@ -692,15 +688,15 @@ public override void Reset()
private bool hasSent;
}
- private class ReloadMagHandler(CoopPlayer coopPlayer, GClass2769 gridItemAddress, MagazineClass magazine)
+ private class ReloadMagHandler(CoopPlayer coopPlayer, ItemAddressClass gridItemAddress, MagazineClass magazine)
{
private readonly CoopPlayer coopPlayer = coopPlayer;
- private readonly GClass2769 gridItemAddress = gridItemAddress;
+ private readonly ItemAddressClass gridItemAddress = gridItemAddress;
private readonly MagazineClass magazine = magazine;
public void Process(IResult error)
{
- GClass1528 gridItemAddressDescriptor = (gridItemAddress == null) ? null : GClass1632.FromGridItemAddress(gridItemAddress);
+ GridItemAddressDescriptorClass gridItemAddressDescriptor = (gridItemAddress == null) ? null : FromObjectAbstractClass.FromGridItemAddress(gridItemAddress);
using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
@@ -762,15 +758,15 @@ public void Process(IResult error)
}
}
- private class ReloadBarrelsHandler(CoopPlayer coopPlayer, GClass2769 placeToPutContainedAmmoMagazine, GClass2495 ammoPack)
+ private class ReloadBarrelsHandler(CoopPlayer coopPlayer, ItemAddressClass placeToPutContainedAmmoMagazine, AmmoPackReloadingClass ammoPack)
{
private readonly CoopPlayer coopPlayer = coopPlayer;
- private readonly GClass2769 placeToPutContainedAmmoMagazine = placeToPutContainedAmmoMagazine;
- private readonly GClass2495 ammoPack = ammoPack;
+ private readonly ItemAddressClass placeToPutContainedAmmoMagazine = placeToPutContainedAmmoMagazine;
+ private readonly AmmoPackReloadingClass ammoPack = ammoPack;
public void Process(IResult error)
{
- GClass1528 gridItemAddressDescriptor = (placeToPutContainedAmmoMagazine == null) ? null : GClass1632.FromGridItemAddress(placeToPutContainedAmmoMagazine);
+ GridItemAddressDescriptorClass gridItemAddressDescriptor = (placeToPutContainedAmmoMagazine == null) ? null : FromObjectAbstractClass.FromGridItemAddress(placeToPutContainedAmmoMagazine);
string[] ammoIds = ammoPack.GetReloadingAmmoIds();
diff --git a/Fika.Core/Coop/ClientClasses/NoInertiaPhysical.cs b/Fika.Core/Coop/ClientClasses/NoInertiaPhysical.cs
new file mode 100644
index 00000000..6b0d1792
--- /dev/null
+++ b/Fika.Core/Coop/ClientClasses/NoInertiaPhysical.cs
@@ -0,0 +1,59 @@
+using Comfort.Common;
+using EFT;
+using Fika.Core.Coop.Players;
+using UnityEngine;
+
+namespace Fika.Core.Coop.ClientClasses
+{
+ public class NoInertiaPhysical : PlayerPhysicalClass
+ {
+ private CoopPlayer coopPlayer;
+
+ public override void Init(IPlayer player)
+ {
+ base.Init(player);
+ coopPlayer = (CoopPlayer)player;
+ }
+
+ public override void OnWeightUpdated()
+ {
+ BackendConfigSettingsClass.InertiaSettings inertia = Singleton.Instance.Inertia;
+ float num = iobserverToPlayerBridge_0.Skills.StrengthBuffElite ? coopPlayer.InventoryControllerClass.Inventory.TotalWeightEliteSkill : coopPlayer.InventoryControllerClass.Inventory.TotalWeight;
+ Inertia = 0.0113f;
+ SprintAcceleration = 0.9887f;
+ PreSprintAcceleration = 2.9853f;
+ float num2 = Mathf.Lerp(inertia.MinMovementAccelerationRangeRight.x, inertia.MaxMovementAccelerationRangeRight.x, Inertia);
+ float num3 = Mathf.Lerp(inertia.MinMovementAccelerationRangeRight.y, inertia.MaxMovementAccelerationRangeRight.y, Inertia);
+ EFTHardSettings.Instance.MovementAccelerationRange.MoveKey(1, new Keyframe(num2, num3));
+ Overweight = BaseOverweightLimits.InverseLerp(num);
+ WalkOverweight = WalkOverweightLimits.InverseLerp(num);
+ WalkSpeedLimit = 1f;
+ float_3 = SprintOverweightLimits.InverseLerp(num);
+ MoveSideInertia = 1.9887f;
+ MoveDiagonalInertia = 1.3955f;
+ if (coopPlayer.IsAI)
+ {
+ float_3 = 0f;
+ }
+ MaxPoseLevel = (Overweight >= 1f) ? 0.9f : 1f;
+ Consumptions[EConsumptionType.OverweightIdle].SetActive(this, Overweight >= 1f);
+ Consumptions[EConsumptionType.OverweightIdle].Delta.SetDirty();
+ Consumptions[EConsumptionType.SitToStand].AllowsRestoration = Overweight >= 1f;
+ Consumptions[EConsumptionType.StandUp].AllowsRestoration = Overweight >= 1f;
+ Consumptions[EConsumptionType.Walk].Delta.SetDirty();
+ Consumptions[EConsumptionType.Sprint].Delta.SetDirty();
+ Consumptions[EConsumptionType.VaultLegs].Delta.SetDirty();
+ Consumptions[EConsumptionType.VaultHands].Delta.SetDirty();
+ Consumptions[EConsumptionType.ClimbLegs].Delta.SetDirty();
+ Consumptions[EConsumptionType.ClimbHands].Delta.SetDirty();
+ TransitionSpeed.SetDirty();
+ PoseLevelDecreaseSpeed.SetDirty();
+ PoseLevelIncreaseSpeed.SetDirty();
+ FallDamageMultiplier = Mathf.Lerp(1f, StaminaParameters.FallDamageMultiplier, Overweight);
+ SoundRadius = StaminaParameters.SoundRadius.Evaluate(Overweight);
+ MinStepSound.SetDirty();
+ method_3();
+ method_7(num);
+ }
+ }
+}
diff --git a/Fika.Core/Coop/Components/CoopExfilManager.cs b/Fika.Core/Coop/Components/CoopExfilManager.cs
index 66bfc26c..6abd8740 100644
--- a/Fika.Core/Coop/Components/CoopExfilManager.cs
+++ b/Fika.Core/Coop/Components/CoopExfilManager.cs
@@ -2,8 +2,8 @@
using EFT;
using EFT.Interactive;
using Fika.Core.Coop.GameMode;
-using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
using Fika.Core.Networking;
using LiteNetLib;
using LiteNetLib.Utils;
@@ -99,9 +99,9 @@ public void Run(ExfiltrationPoint[] exfilPoints)
exfiltrationPoint.OnCancelExtraction += ExfiltrationPoint_OnCancelExtraction;
exfiltrationPoint.OnStatusChanged += ExfiltrationPoint_OnStatusChanged;
game.UpdateExfiltrationUi(exfiltrationPoint, false, true);
- if (FikaPlugin.Instance.DynamicVExfils && exfiltrationPoint.Settings.PlayersCount > 0 && exfiltrationPoint.Settings.PlayersCount < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers)
+ if (FikaPlugin.Instance.DynamicVExfils && exfiltrationPoint.Settings.PlayersCount > 0 && exfiltrationPoint.Settings.PlayersCount < FikaBackendUtils.HostExpectedNumberOfPlayers)
{
- exfiltrationPoint.Settings.PlayersCount = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers;
+ exfiltrationPoint.Settings.PlayersCount = FikaBackendUtils.HostExpectedNumberOfPlayers;
}
}
@@ -204,11 +204,11 @@ private void ExfiltrationPoint_OnStatusChanged(ExfiltrationPoint point, EExfiltr
NetDataWriter writer = mainPlayer.PacketSender.Writer;
writer.Reset();
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
mainPlayer.PacketSender.Server.SendDataToAll(writer, ref packet, DeliveryMethod.ReliableOrdered);
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else if (FikaBackendUtils.IsClient)
{
mainPlayer.PacketSender.Client.SendData(writer, ref packet, DeliveryMethod.ReliableOrdered);
}
diff --git a/Fika.Core/Coop/Components/CoopHandler.cs b/Fika.Core/Coop/Components/CoopHandler.cs
index b881b263..8361ae79 100644
--- a/Fika.Core/Coop/Components/CoopHandler.cs
+++ b/Fika.Core/Coop/Components/CoopHandler.cs
@@ -5,11 +5,9 @@
using EFT.InventoryLogic;
using Fika.Core.Coop.BTR;
using Fika.Core.Coop.GameMode;
-using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
using Fika.Core.Networking;
-using Fika.Core.Networking.Http;
-using Fika.Core.Networking.Http.Models;
using LiteNetLib;
using LiteNetLib.Utils;
using System;
@@ -28,22 +26,16 @@ public class CoopHandler : MonoBehaviour
{
#region Fields/Properties
public Dictionary ListOfInteractiveObjects { get; private set; } = [];
+ public CoopGame LocalGameInstance { get; internal set; }
public string ServerId { get; set; } = null;
- ///
- /// ProfileId to Player instance
- ///
- public Dictionary Players { get; } = new();
+ public Dictionary Players = [];
public int HumanPlayers = 1;
- public List ExtractedPlayers { get; set; } = [];
+ public List ExtractedPlayers = [];
ManualLogSource Logger;
public CoopPlayer MyPlayer => (CoopPlayer)Singleton.Instance.MainPlayer;
-
public List queuedProfileIds = [];
private Queue spawnQueue = new(50);
- //private Thread loopThread;
- //private CancellationTokenSource loopToken;
-
public class SpawnObject(Profile profile, Vector3 position, bool isAlive, bool isAI, int netId)
{
public Profile Profile { get; set; } = profile;
@@ -60,8 +52,6 @@ public class SpawnObject(Profile profile, Vector3 position, bool isAlive, bool i
internal static GameObject CoopHandlerParent;
- private Coroutine PingRoutine;
-
#endregion
#region Public Voids
@@ -93,7 +83,7 @@ public static string GetServerId()
CoopHandler coopGC = GetCoopHandler();
if (coopGC == null)
{
- return MatchmakerAcceptPatches.GetGroupId();
+ return FikaBackendUtils.GetGroupId();
}
return coopGC.ServerId;
@@ -117,12 +107,7 @@ protected void Awake()
///
protected void Start()
{
- if (MatchmakerAcceptPatches.IsServer)
- {
- PingRoutine = StartCoroutine(PingServer());
- }
-
- if (MatchmakerAcceptPatches.IsClient)
+ if (FikaBackendUtils.IsClient)
{
_ = Task.Run(ReadFromServerCharactersLoop);
}
@@ -136,23 +121,6 @@ protected void Start()
}
}
- private IEnumerator PingServer()
- {
- //string serialized = new PingRequest().ToJson();
- PingRequest pingRequest = new();
-
- while (true)
- {
- yield return new WaitForSeconds(30);
- //RequestHandler.PutJson("/fika/update/ping", serialized);
- Task pingTask = FikaRequestHandler.UpdatePing(pingRequest);
- while (!pingTask.IsCompleted)
- {
- yield return null;
- }
- }
- }
-
protected void OnDestroy()
{
Players.Clear();
@@ -160,10 +128,6 @@ protected void OnDestroy()
RunAsyncTasks = false;
StopCoroutine(ProcessSpawnQueue());
- if (PingRoutine != null)
- {
- StopCoroutine(PingRoutine);
- }
}
private bool requestQuitGame = false;
@@ -233,9 +197,10 @@ void ProcessQuitting()
if (FikaPlugin.ExtractKey.Value.IsDown() && quitState != EQuitState.NONE && !requestQuitGame)
{
requestQuitGame = true;
+ CoopGame coopGame = (CoopGame)Singleton.Instance;
// If you are the server / host
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
// A host needs to wait for the team to extract or die!
if ((Singleton.Instance.NetServer.ConnectedPeersCount > 0) && quitState != EQuitState.NONE)
@@ -244,7 +209,9 @@ void ProcessQuitting()
requestQuitGame = false;
return;
}
- else if (Singleton.Instance.NetServer.ConnectedPeersCount == 0 && Singleton.Instance.timeSinceLastPeerDisconnected > DateTime.Now.AddSeconds(-5) && Singleton.Instance.hasHadPeer)
+ else if (Singleton.Instance.NetServer.ConnectedPeersCount == 0
+ && Singleton.Instance.timeSinceLastPeerDisconnected > DateTime.Now.AddSeconds(-5)
+ && Singleton.Instance.hasHadPeer)
{
NotificationManagerClass.DisplayWarningNotification($"HOSTING: Please wait at least 5 seconds after the last peer disconnected before quitting.");
requestQuitGame = false;
@@ -252,16 +219,12 @@ void ProcessQuitting()
}
else
{
- Singleton.Instance.Stop(Singleton.Instance.MainPlayer.ProfileId,
- Singleton.Instance.MyExitStatus,
- MyPlayer.ActiveHealthController.IsAlive ? Singleton.Instance.MyExitLocation : null, 0);
+ coopGame.Stop(Singleton.Instance.MainPlayer.ProfileId, coopGame.MyExitStatus, MyPlayer.ActiveHealthController.IsAlive ? coopGame.MyExitLocation : null, 0);
}
}
else
{
- Singleton.Instance.Stop(Singleton.Instance.MainPlayer.ProfileId,
- Singleton.Instance.MyExitStatus,
- MyPlayer.ActiveHealthController.IsAlive ? Singleton.Instance.MyExitLocation : null, 0);
+ coopGame.Stop(Singleton.Instance.MainPlayer.ProfileId, coopGame.MyExitStatus, MyPlayer.ActiveHealthController.IsAlive ? coopGame.MyExitLocation : null, 0);
}
return;
}
@@ -283,7 +246,7 @@ private async Task ReadFromServerCharactersLoop()
{
while (RunAsyncTasks)
{
- CoopGame coopGame = (CoopGame)Singleton.Instance;
+ CoopGame coopGame = LocalGameInstance;
int waitTime = 2500;
if (coopGame.Status == GameStatus.Started)
{
@@ -321,24 +284,31 @@ private void ReadFromServerCharacters()
private async void SpawnPlayer(SpawnObject spawnObject)
{
- if (Singleton.Instance.RegisteredPlayers.Any(x => x.ProfileId == spawnObject.Profile.ProfileId))
+ if (spawnObject.Profile == null)
{
+ Logger.LogError("SpawnPlayer Profile is NULL!");
+ queuedProfileIds.Remove(spawnObject.Profile.ProfileId);
return;
}
- if (Singleton.Instance.AllAlivePlayersList.Any(x => x.ProfileId == spawnObject.Profile.ProfileId))
+ foreach (IPlayer player in Singleton.Instance.RegisteredPlayers)
{
- return;
+ if (player.ProfileId == spawnObject.Profile.ProfileId)
+ {
+ return;
+ }
}
- int playerId = Players.Count + Singleton.Instance.RegisteredPlayers.Count + 1;
- if (spawnObject.Profile == null)
+ foreach (IPlayer player in Singleton.Instance.AllAlivePlayersList)
{
- Logger.LogError("SpawnPlayer Profile is NULL!");
- queuedProfileIds.Remove(spawnObject.Profile.ProfileId);
- return;
+ if (player.ProfileId == spawnObject.Profile.ProfileId)
+ {
+ return;
+ }
}
+ int playerId = Players.Count + Singleton.Instance.RegisteredPlayers.Count + 1;
+
IEnumerable allPrefabPaths = spawnObject.Profile.GetAllPrefabPaths();
if (allPrefabPaths.Count() == 0)
{
@@ -347,9 +317,7 @@ private async void SpawnPlayer(SpawnObject spawnObject)
}
await Singleton.Instance.LoadBundlesAndCreatePools(PoolManager.PoolsCategory.Raid,
- PoolManager.AssemblyType.Local,
- allPrefabPaths.ToArray(),
- JobPriority.General).ContinueWith(x =>
+ PoolManager.AssemblyType.Local, allPrefabPaths.ToArray(), JobPriority.General).ContinueWith(x =>
{
if (x.IsCompleted)
{
@@ -372,12 +340,11 @@ await Singleton.Instance.LoadBundlesAndCreatePools(PoolManager.Pool
// TODO: Spawn them as corpses?
}
- if (MatchmakerAcceptPatches.IsServer)
+ if (FikaBackendUtils.IsServer)
{
if (LocalGameInstance != null)
{
- CoopGame coopGame = (CoopGame)LocalGameInstance;
- BotsController botController = coopGame.BotsController;
+ BotsController botController = LocalGameInstance.BotsController;
if (botController != null)
{
// Start Coroutine as botController might need a while to start sometimes...
@@ -424,14 +391,20 @@ private IEnumerator ProcessSpawnQueue()
public void QueueProfile(Profile profile, Vector3 position, int netId, bool isAlive = true, bool isAI = false)
{
- if (Singleton.Instance.RegisteredPlayers.Any(x => x.ProfileId == profile.ProfileId))
+ foreach (IPlayer player in Singleton.Instance.RegisteredPlayers)
{
- return;
+ if (player.ProfileId == profile.ProfileId)
+ {
+ return;
+ }
}
- if (Singleton.Instance.AllAlivePlayersList.Any(x => x.ProfileId == profile.ProfileId))
+ foreach (IPlayer player in Singleton.Instance.AllAlivePlayersList)
{
- return;
+ if (player.ProfileId == profile.ProfileId)
+ {
+ return;
+ }
}
if (queuedProfileIds.Contains(profile.ProfileId))
@@ -455,13 +428,13 @@ public WorldInteractiveObject GetInteractiveObject(string objectId, out WorldInt
private ObservedCoopPlayer SpawnObservedPlayer(Profile profile, Vector3 position, int playerId, bool isAI, int netId)
{
- ObservedCoopPlayer otherPlayer = ObservedCoopPlayer.CreateObservedPlayer(playerId, position, Quaternion.identity,
- "Player", isAI == true ? "Bot_" : $"Player_{profile.Nickname}_", EPointOfView.ThirdPerson, profile, isAI,
- EUpdateQueue.Update, Player.EUpdateMode.Manual, Player.EUpdateMode.Auto,
- GClass549.Config.CharacterController.ObservedPlayerMode,
+ ObservedCoopPlayer otherPlayer = ObservedCoopPlayer.CreateObservedPlayer(playerId, position,
+ Quaternion.identity, "Player", isAI == true ? "Bot_" : $"Player_{profile.Nickname}_",
+ EPointOfView.ThirdPerson, profile, isAI, EUpdateQueue.Update, Player.EUpdateMode.Manual,
+ Player.EUpdateMode.Auto, BackendConfigAbstractClass.Config.CharacterController.ObservedPlayerMode,
() => Singleton.Instance.Control.Settings.MouseSensitivity,
() => Singleton.Instance.Control.Settings.MouseAimingSensitivity,
- GClass1446.Default).Result;
+ GClass1457.Default).Result;
if (otherPlayer == null)
{
@@ -501,7 +474,7 @@ private ObservedCoopPlayer SpawnObservedPlayer(Profile profile, Vector3 position
if (playerCollider != null && otherCollider != null)
{
- GClass649.IgnoreCollision(playerCollider, otherCollider);
+ EFTPhysicsClass.IgnoreCollision(playerCollider, otherCollider);
}
}
@@ -510,7 +483,9 @@ private ObservedCoopPlayer SpawnObservedPlayer(Profile profile, Vector3 position
if (profile.Info.Side is EPlayerSide.Bear or EPlayerSide.Usec)
{
Item backpack = profile.Inventory.Equipment.GetSlot(EquipmentSlot.Backpack).ContainedItem;
- backpack?.GetAllItems().Where(i => i != backpack).ExecuteForEach(i => i.SpawnedInSession = true);
+ backpack?.GetAllItems()
+ .Where(i => i != backpack)
+ .ExecuteForEach(i => i.SpawnedInSession = true);
// We still want DogTags to be 'FiR'
Item item = otherPlayer.Inventory.Equipment.GetSlot(EquipmentSlot.Dogtag).ContainedItem;
@@ -536,14 +511,14 @@ private ObservedCoopPlayer SpawnObservedPlayer(Profile profile, Vector3 position
Logger.LogDebug($"CreateLocalPlayer::{profile.Info.Nickname}::Spawned.");
- SetWeaponInHandsOfNewPlayer(otherPlayer, () => { });
+ SetWeaponInHandsOfNewPlayer(otherPlayer);
return otherPlayer;
}
private IEnumerator AddClientToBotEnemies(BotsController botController, LocalPlayer playerToAdd)
{
- CoopGame coopGame = (CoopGame)LocalGameInstance;
+ CoopGame coopGame = LocalGameInstance;
Logger.LogInfo($"AddClientToBotEnemies: " + playerToAdd.Profile.Nickname);
@@ -584,13 +559,13 @@ private IEnumerator AddClientToBotEnemies(BotsController botController, LocalPla
///
/// Attempts to set up the New Player with the current weapon after spawning
///
- /// The player to set the item on
- public void SetWeaponInHandsOfNewPlayer(Player person, Action successCallback)
+ /// The player to set the item on
+ public void SetWeaponInHandsOfNewPlayer(Player player)
{
- EquipmentClass equipment = person.Profile.Inventory.Equipment;
+ EquipmentClass equipment = player.Profile.Inventory.Equipment;
if (equipment == null)
{
- Logger.LogError($"SetWeaponInHandsOfNewPlayer: {person.Profile.ProfileId} has no Equipment!");
+ Logger.LogError($"SetWeaponInHandsOfNewPlayer: {player.Profile.Nickname}, {player.Profile.ProfileId} has no Equipment!");
}
Item item = null;
@@ -616,38 +591,16 @@ public void SetWeaponInHandsOfNewPlayer(Player person, Action successCallback)
if (item == null)
{
- Logger.LogError($"SetWeaponInHandsOfNewPlayer:Unable to find any weapon for {person.Profile.ProfileId}");
+ Logger.LogError($"SetWeaponInHandsOfNewPlayer: Unable to find any weapon for {player.Profile.Nickname}, {player.Profile.ProfileId}");
}
- person.SetItemInHands(item, (IResult) =>
+ player.SetItemInHands(item, (IResult) =>
{
if (IResult.Failed == true)
{
- Logger.LogError($"SetWeaponInHandsOfNewPlayer:Unable to set item {item} in hands for {person.Profile.ProfileId}");
- }
-
- if (IResult.Succeed == true)
- {
- successCallback?.Invoke();
- }
-
- if (person.TryGetItemInHands- () != null)
- {
- successCallback?.Invoke();
+ Logger.LogError($"SetWeaponInHandsOfNewPlayer: Unable to set item {item} in hands for {player.Profile.Nickname}, {player.Profile.ProfileId}");
}
});
}
-
- public BaseLocalGame LocalGameInstance { get; internal set; }
- }
-
- public enum ESpawnState
- {
- None = 0,
- Loading = 1,
- Spawning = 2,
- Spawned = 3,
- Ignore = 98,
- Error = 99,
}
}
diff --git a/Fika.Core/Coop/Components/CoopTimeManager.cs b/Fika.Core/Coop/Components/CoopTimeManager.cs
new file mode 100644
index 00000000..1dfb9f95
--- /dev/null
+++ b/Fika.Core/Coop/Components/CoopTimeManager.cs
@@ -0,0 +1,33 @@
+using Comfort.Common;
+using EFT;
+using Fika.Core.Coop.GameMode;
+using Fika.Core.Coop.Players;
+using UnityEngine;
+
+namespace Fika.Core.Coop.Components
+{
+ internal class CoopTimeManager : MonoBehaviour
+ {
+ public CoopGame CoopGame;
+ public GameTimerClass GameTimer;
+
+ public static CoopTimeManager Create(CoopGame game)
+ {
+ CoopTimeManager timeManager = game.gameObject.AddComponent();
+ timeManager.CoopGame = game;
+ timeManager.GameTimer = game.GameTimer;
+ return timeManager;
+ }
+
+ protected void Update()
+ {
+ if (CoopGame.Status == GameStatus.Started && GameTimer != null && GameTimer.SessionTime != null && GameTimer.PastTime >= GameTimer.SessionTime)
+ {
+ CoopGame.MyExitStatus = ExitStatus.MissingInAction;
+ CoopPlayer coopPlayer = (CoopPlayer)Singleton.Instance.MainPlayer;
+ CoopGame.Extract(coopPlayer, null);
+ enabled = false;
+ }
+ }
+ }
+}
diff --git a/Fika.Core/Coop/Components/FikaPinger.cs b/Fika.Core/Coop/Components/FikaPinger.cs
new file mode 100644
index 00000000..aa32d7e4
--- /dev/null
+++ b/Fika.Core/Coop/Components/FikaPinger.cs
@@ -0,0 +1,50 @@
+using Fika.Core.Networking.Http;
+using Fika.Core.Networking.Http.Models;
+using System.Collections;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace Fika.Core.Coop.Components
+{
+ ///
+ /// Used to ping the backend every 30 seconds to keep the session alive
+ ///
+ public class FikaPinger : MonoBehaviour
+ {
+ private Coroutine pingRoutine;
+
+ public void StartPingRoutine()
+ {
+ pingRoutine = StartCoroutine(PingServer());
+ }
+
+ public void StopPingRoutine()
+ {
+ if (pingRoutine != null)
+ {
+ StopCoroutine(pingRoutine);
+ pingRoutine = null;
+ }
+ }
+
+ private IEnumerator PingServer()
+ {
+ PingRequest pingRequest = new();
+
+ while (true)
+ {
+ Task pingTask = FikaRequestHandler.UpdatePing(pingRequest);
+ while (!pingTask.IsCompleted)
+ {
+ yield return null;
+ }
+ yield return new WaitForSeconds(30);
+ }
+ }
+
+ private void OnDestroy()
+ {
+ StopPingRoutine();
+ }
+ }
+}
diff --git a/Fika.Core/Coop/Custom/FikaChat.cs b/Fika.Core/Coop/Custom/FikaChat.cs
new file mode 100644
index 00000000..5fa4a36e
--- /dev/null
+++ b/Fika.Core/Coop/Custom/FikaChat.cs
@@ -0,0 +1,138 @@
+using Comfort.Common;
+using EFT.UI;
+using Fika.Core.Coop.Utils;
+using Fika.Core.Networking;
+using Fika.Core.Networking.Packets.Communication;
+using HarmonyLib;
+using LiteNetLib.Utils;
+using UnityEngine;
+
+namespace Fika.Core.Coop.Custom
+{
+ internal class FikaChat : MonoBehaviour
+ {
+ private Rect windowRect;
+ private string nickname;
+ private string chatText;
+ private string textField;
+ private bool show;
+ private bool isServer;
+ private NetDataWriter writer;
+ private UISoundsWrapper soundsWrapper;
+
+ protected void Awake()
+ {
+ windowRect = new(20, Screen.height - 260, 600, 250);
+ nickname = FikaBackendUtils.PMCName;
+ chatText = string.Empty;
+ textField = string.Empty;
+ show = false;
+ isServer = FikaBackendUtils.IsServer;
+ writer = new();
+ GUISounds guiSounds = Singleton.Instance;
+ soundsWrapper = Traverse.Create(guiSounds).Field("uisoundsWrapper_0").Value;
+ }
+
+ protected void Update()
+ {
+ if (Input.GetKeyDown(FikaPlugin.ChatKey.Value.MainKey))
+ {
+ ToggleVisibility();
+ }
+ }
+
+ protected void OnGUI()
+ {
+ if (!show)
+ {
+ return;
+ }
+
+ GUI.skin.label.alignment = TextAnchor.LowerLeft;
+ GUI.skin.window.alignment = TextAnchor.UpperLeft;
+ GUI.Window(0, windowRect, DrawWindow, "Fika Chat");
+
+ if (Event.current.isKey)
+ {
+ if (Event.current.keyCode is KeyCode.Return or KeyCode.KeypadEnter && show)
+ {
+ SendMessage();
+ GUI.UnfocusWindow();
+ GUI.FocusControl(null);
+ }
+ }
+ }
+
+ private void ToggleVisibility()
+ {
+ show = !show;
+ }
+
+ private void SendMessage()
+ {
+ if (!show)
+ {
+ return;
+ }
+
+ if (!string.IsNullOrEmpty(textField))
+ {
+ string message = textField;
+ textField = string.Empty;
+
+ if (message.Length > 100)
+ {
+ message = message.Substring(0, 100);
+ }
+
+ TextMessagePacket packet = new(nickname, message);
+ writer.Reset();
+
+ if (isServer)
+ {
+ Singleton.Instance.SendDataToAll(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
+ }
+ else
+ {
+ Singleton.Instance.SendData(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
+ }
+ AudioClip outgoingClip = soundsWrapper.GetSocialNetworkClip(ESocialNetworkSoundType.OutgoingMessage);
+ Singleton.Instance.PlaySound(outgoingClip);
+ AddMessage(nickname + ": " + message);
+ }
+ }
+
+ public void ReceiveMessage(string nickname, string message)
+ {
+ AudioClip incomingClip = soundsWrapper.GetSocialNetworkClip(ESocialNetworkSoundType.IncomingMessage);
+ Singleton.Instance.PlaySound(incomingClip);
+ AddMessage(nickname + ": " + message);
+ }
+
+ private void AddMessage(string message)
+ {
+ chatText = string.Concat(chatText, message, "\n");
+ if (chatText.Length > 1000)
+ {
+ chatText = chatText.Substring(500);
+ }
+ }
+
+ private void DrawWindow(int windowId)
+ {
+ Rect rect = new(5, 15, 580, 200);
+ GUI.Label(rect, chatText);
+ rect.y += rect.height;
+ Rect textRect = new(rect.x, rect.y, rect.width - 55, 25);
+ textField = GUI.TextField(textRect, textField);
+ rect.x += 535;
+ Rect buttonRect = new(rect.x, rect.y, 50, 25);
+ if (GUI.Button(buttonRect, "SEND"))
+ {
+ SendMessage();
+ GUI.UnfocusWindow();
+ GUI.FocusControl(null);
+ }
+ }
+ }
+}
diff --git a/Fika.Core/Coop/Custom/FikaDebug.cs b/Fika.Core/Coop/Custom/FikaDebug.cs
new file mode 100644
index 00000000..dc945d5c
--- /dev/null
+++ b/Fika.Core/Coop/Custom/FikaDebug.cs
@@ -0,0 +1,163 @@
+using Comfort.Common;
+using Fika.Core.Coop.Components;
+using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
+using Fika.Core.Networking;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Fika.Core.Coop.Custom
+{
+ internal class FikaDebug : MonoBehaviour
+ {
+ private CoopHandler coopHandler;
+ private Rect windowRect = new(20, 20, 200, 200);
+ private int frameCounter = 0;
+
+ private int Ping
+ {
+ get
+ {
+ return Singleton.Instance.Ping;
+ }
+ }
+
+ private int RTT
+ {
+ get
+ {
+ return Singleton.Instance.NetClient.FirstPeer.RoundTripTime;
+ }
+ }
+
+ private bool isServer = false;
+
+ private List alivePlayers;
+ private List aliveBots;
+
+ protected void Awake()
+ {
+ coopHandler = CoopHandler.GetCoopHandler();
+ if (coopHandler == null)
+ {
+ FikaPlugin.Instance.FikaLogger.LogError("FikaDebug: CoopHandlera was null!");
+ Destroy(this);
+ }
+
+ if (FikaBackendUtils.IsServer)
+ {
+ isServer = true;
+ }
+
+ alivePlayers = [];
+ aliveBots = [];
+
+ enabled = false;
+ }
+
+ protected void Update()
+ {
+ frameCounter++;
+ if (frameCounter % 300 == 0)
+ {
+ frameCounter = 0;
+
+ CheckAndAdd();
+ }
+ }
+
+ private void CheckAndAdd()
+ {
+ foreach (CoopPlayer player in coopHandler.Players.Values)
+ {
+ if (player.gameObject.name.StartsWith("Player_") || player.IsYourPlayer)
+ {
+ if (!alivePlayers.Contains(player) && player.HealthController.IsAlive)
+ {
+ AddPlayer(player);
+ }
+ }
+ else
+ {
+ if (!aliveBots.Contains(player) && player.HealthController.IsAlive)
+ {
+ AddBot(player);
+ }
+ }
+ }
+ }
+
+ protected void OnEnable()
+ {
+ CheckAndAdd();
+ }
+
+ protected void OnDisable()
+ {
+ foreach (CoopPlayer player in alivePlayers)
+ {
+ player.OnPlayerDead -= PlayerDied;
+ }
+ alivePlayers.Clear();
+
+ foreach (CoopPlayer bot in aliveBots)
+ {
+ bot.OnPlayerDead -= BotDied;
+ }
+ aliveBots.Clear();
+ }
+
+ private void AddPlayer(CoopPlayer player)
+ {
+ player.OnPlayerDead += PlayerDied;
+ alivePlayers.Add(player);
+ }
+
+ private void PlayerDied(EFT.Player player, EFT.IPlayer lastAggressor, DamageInfo damageInfo, EBodyPart part)
+ {
+ player.OnPlayerDead -= PlayerDied;
+ alivePlayers.Remove((CoopPlayer)player);
+ }
+
+ private void AddBot(CoopPlayer bot)
+ {
+ bot.OnPlayerDead += BotDied;
+ aliveBots.Add(bot);
+ }
+
+ private void BotDied(EFT.Player player, EFT.IPlayer lastAggressor, DamageInfo damageInfo, EBodyPart part)
+ {
+ player.OnPlayerDead -= BotDied;
+ aliveBots.Remove((CoopPlayer)player);
+ }
+
+ protected void OnGUI()
+ {
+ GUI.skin.label.alignment = TextAnchor.MiddleLeft;
+ GUI.skin.window.alignment = TextAnchor.UpperCenter;
+
+ GUI.Window(0, windowRect, DrawWindow, "Fika Debug");
+ }
+
+ private void DrawWindow(int windowId)
+ {
+ GUILayout.BeginArea(new(5, 15, 150, 150));
+ GUILayout.BeginVertical();
+
+ GUILayout.Label($"Alive Players: {alivePlayers.Count}");
+ GUILayout.Label($"Alive Bots: {aliveBots.Count}");
+ if (isServer)
+ {
+ GUILayout.Label($"Clients: {Singleton.Instance.NetServer.ConnectedPeersCount}");
+ }
+ else
+ {
+ GUILayout.Label($"Ping: {Ping}");
+ GUILayout.Label($"RTT: {RTT}");
+ }
+
+ GUILayout.EndVertical();
+ GUILayout.EndArea();
+ }
+ }
+}
diff --git a/Fika.Core/Coop/Custom/FikaDynamicAI.cs b/Fika.Core/Coop/Custom/FikaDynamicAI.cs
index 82e4db45..a0b8eea4 100644
--- a/Fika.Core/Coop/Custom/FikaDynamicAI.cs
+++ b/Fika.Core/Coop/Custom/FikaDynamicAI.cs
@@ -6,7 +6,6 @@
using Fika.Core.Coop.Components;
using Fika.Core.Coop.Players;
using System.Collections.Generic;
-using System.Linq;
using UnityEngine;
namespace Fika.Core.Coop.Custom
@@ -39,9 +38,9 @@ protected void Awake()
resetCounter = FikaPlugin.DynamicAIRate.Value switch
{
- FikaPlugin.DynamicAIRates.Low => 600,
- FikaPlugin.DynamicAIRates.Medium => 300,
- FikaPlugin.DynamicAIRates.High => 120,
+ FikaPlugin.EDynamicAIRates.Low => 600,
+ FikaPlugin.EDynamicAIRates.Medium => 300,
+ FikaPlugin.EDynamicAIRates.High => 120,
_ => 300,
};
@@ -159,6 +158,7 @@ private void CheckForPlayers(CoopBot bot)
}
int notInRange = 0;
+ float range = FikaPlugin.DynamicAIRange.Value;
foreach (CoopPlayer humanPlayer in humanPlayers)
{
@@ -175,7 +175,6 @@ private void CheckForPlayers(CoopBot bot)
}
float distance = Vector3.SqrMagnitude(bot.Position - humanPlayer.Position);
- float range = FikaPlugin.DynamicAIRange.Value;
if (distance > range * range)
{
@@ -207,13 +206,13 @@ public void EnabledChange(bool value)
}
}
- internal void RateChanged(FikaPlugin.DynamicAIRates value)
+ internal void RateChanged(FikaPlugin.EDynamicAIRates value)
{
resetCounter = value switch
{
- FikaPlugin.DynamicAIRates.Low => 600,
- FikaPlugin.DynamicAIRates.Medium => 300,
- FikaPlugin.DynamicAIRates.High => 120,
+ FikaPlugin.EDynamicAIRates.Low => 600,
+ FikaPlugin.EDynamicAIRates.Medium => 300,
+ FikaPlugin.EDynamicAIRates.High => 120,
_ => 300,
};
}
diff --git a/Fika.Core/Coop/Custom/FikaHealthBar.cs b/Fika.Core/Coop/Custom/FikaHealthBar.cs
index 177caabf..6612a4ed 100644
--- a/Fika.Core/Coop/Custom/FikaHealthBar.cs
+++ b/Fika.Core/Coop/Custom/FikaHealthBar.cs
@@ -23,8 +23,6 @@ public class FikaHealthBar : MonoBehaviour
private CoopPlayer mainPlayer;
private PlayerPlateUI playerPlate;
private float screenScale = 1f;
- private int frameCounter = 0;
- private readonly int throttleInterval = 60; // throttle to 1 update per 60 frames
protected void Awake()
{
@@ -37,29 +35,7 @@ protected void Update()
{
if (currentPlayer != null)
{
- bool throttleUpdate = IsThrottleUpdate();
- if (throttleUpdate)
- {
- // Handling the visibility of elements
- if (!FikaPlugin.UseNamePlates.Value)
- {
- playerPlate.gameObject.SetActive(false);
- return;
- }
- else if (playerPlate.gameObject.active == false)
- {
- playerPlate.gameObject.SetActive(true);
- }
- SetPlayerPlateFactionVisibility(FikaPlugin.UsePlateFactionSide.Value);
- SetPlayerPlateHealthVisibility(FikaPlugin.HideHealthBar.Value);
- }
- // Finally, update the screen space position
- UpdateScreenSpacePosition(throttleUpdate);
- // Destroy if this player is dead
- if (!currentPlayer.HealthController.IsAlive)
- {
- Destroy(this);
- }
+ UpdateScreenSpacePosition();
}
else
{
@@ -67,7 +43,7 @@ protected void Update()
}
}
- private void UpdateScreenSpacePosition(bool throttleUpdate)
+ private void UpdateScreenSpacePosition()
{
// ADS opacity handling
float opacityMultiplier = 1f;
@@ -100,7 +76,7 @@ private void UpdateScreenSpacePosition(bool throttleUpdate)
float processedDistance = Mathf.Clamp(sqrDistance / 625, 0.6f, 1f);
Vector3 position = new(currentPlayer.PlayerBones.Neck.position.x, currentPlayer.PlayerBones.Neck.position.y + (1f * processedDistance), currentPlayer.PlayerBones.Neck.position.z);
- if (!WorldToScreen.GetScreenPoint(position, mainPlayer, out Vector3 screenPoint))
+ if (!WorldToScreen.GetScreenPoint(position, mainPlayer, out Vector3 screenPoint, FikaPlugin.NamePlateUseOpticZoom.Value))
{
UpdateColorTextMeshProUGUI(playerPlate.playerNameScreen, 0);
UpdateColorImage(playerPlate.healthBarScreen, 0);
@@ -138,12 +114,12 @@ private void UpdateScreenSpacePosition(bool throttleUpdate)
float alpha = 1f;
float halfMaxDistanceToShow = maxDistanceToShow / 2;
- float lerpValue = Mathf.Clamp01((sqrDistance - halfMaxDistanceToShow) / (halfMaxDistanceToShow));
+ float lerpValue = Mathf.Clamp01((sqrDistance - halfMaxDistanceToShow) / halfMaxDistanceToShow);
alpha = Mathf.LerpUnclamped(alpha, 0, lerpValue);
float namePlateScaleMult = Mathf.LerpUnclamped(1f, 0.5f, lerpValue);
namePlateScaleMult = Mathf.Clamp(namePlateScaleMult * FikaPlugin.NamePlateScale.Value, FikaPlugin.MinimumNamePlateScale.Value * FikaPlugin.NamePlateScale.Value, FikaPlugin.NamePlateScale.Value);
- playerPlate.ScalarObjectScreen.transform.localScale = (Vector3.one / processedDistance) * namePlateScaleMult;
+ playerPlate.ScalarObjectScreen.transform.localScale = Vector3.one / processedDistance * namePlateScaleMult;
alpha *= opacityMultiplier;
alpha *= distFromCenterMultiplier;
@@ -192,13 +168,27 @@ private void CreateHealthBar()
playerPlate.bearPlateScreen.gameObject.SetActive(false);
}
+ SetPlayerPlateFactionVisibility(FikaPlugin.UsePlateFactionSide.Value);
+ SetPlayerPlateHealthVisibility(FikaPlugin.HideHealthBar.Value);
+ playerPlate.gameObject.SetActive(FikaPlugin.UseNamePlates.Value);
+
+ FikaPlugin.UsePlateFactionSide.SettingChanged += UsePlateFactionSide_SettingChanged;
+ FikaPlugin.HideHealthBar.SettingChanged += HideHealthBar_SettingChanged;
+ FikaPlugin.UseNamePlates.SettingChanged += UseNamePlates_SettingChanged;
+
currentPlayer.HealthController.HealthChangedEvent += HealthController_HealthChangedEvent;
currentPlayer.HealthController.BodyPartDestroyedEvent += HealthController_BodyPartDestroyedEvent;
currentPlayer.HealthController.BodyPartRestoredEvent += HealthController_BodyPartRestoredEvent;
+ currentPlayer.HealthController.DiedEvent += HealthController_DiedEvent;
UpdateHealth();
}
+ private void HealthController_DiedEvent(EDamageType obj)
+ {
+ Destroy(this);
+ }
+
private void HealthController_BodyPartRestoredEvent(EBodyPart arg1, EFT.HealthSystem.ValueStruct arg2)
{
UpdateHealth();
@@ -214,6 +204,20 @@ private void HealthController_HealthChangedEvent(EBodyPart arg1, float arg2, Dam
UpdateHealth();
}
+ private void UsePlateFactionSide_SettingChanged(object sender, EventArgs e)
+ {
+ SetPlayerPlateFactionVisibility(FikaPlugin.UsePlateFactionSide.Value);
+ }
+ private void HideHealthBar_SettingChanged(object sender, EventArgs e)
+ {
+ SetPlayerPlateHealthVisibility(FikaPlugin.HideHealthBar.Value);
+ }
+
+ private void UseNamePlates_SettingChanged(object sender, EventArgs e)
+ {
+ playerPlate.gameObject.SetActive(FikaPlugin.UseNamePlates.Value);
+ }
+
///
/// Updates the health on the HealthBar, this is invoked from events on the healthcontroller
///
@@ -228,7 +232,7 @@ private void UpdateHealth()
playerPlate.healthNumberBackgroundScreen.gameObject.SetActive(true);
playerPlate.healthBarBackgroundScreen.gameObject.SetActive(false);
}
- int healthNumberPercentage = (int)Math.Round((currentHealth / maxHealth) * 100);
+ int healthNumberPercentage = (int)Math.Round(currentHealth / maxHealth * 100);
playerPlate.SetHealthNumberText($"{healthNumberPercentage}%");
}
else
@@ -293,23 +297,17 @@ private void SetPlayerPlateFactionVisibility(bool visible)
}
}
- private bool IsThrottleUpdate()
+ protected void OnDestroy()
{
- // For throttling updates to various elements
- frameCounter++;
- bool throttleUpdate = frameCounter >= throttleInterval;
- if (throttleUpdate)
- {
- frameCounter = 0;
- }
- return throttleUpdate;
- }
+ FikaPlugin.UsePlateFactionSide.SettingChanged -= UsePlateFactionSide_SettingChanged;
+ FikaPlugin.HideHealthBar.SettingChanged -= HideHealthBar_SettingChanged;
+ FikaPlugin.UseNamePlates.SettingChanged -= UseNamePlates_SettingChanged;
- private void OnDestroy()
- {
currentPlayer.HealthController.HealthChangedEvent -= HealthController_HealthChangedEvent;
currentPlayer.HealthController.BodyPartDestroyedEvent -= HealthController_BodyPartDestroyedEvent;
currentPlayer.HealthController.BodyPartRestoredEvent -= HealthController_BodyPartRestoredEvent;
+ currentPlayer.HealthController.DiedEvent -= HealthController_DiedEvent;
+
playerPlate.gameObject.SetActive(false);
Destroy(this);
}
diff --git a/Fika.Core/Coop/Factories/PingFactory.cs b/Fika.Core/Coop/Factories/PingFactory.cs
index 3a47c5b5..63fee528 100644
--- a/Fika.Core/Coop/Factories/PingFactory.cs
+++ b/Fika.Core/Coop/Factories/PingFactory.cs
@@ -83,13 +83,13 @@ protected void Update()
screenScale = outputWidth / inputWidth;
}
- if (WorldToScreen.GetScreenPoint(hitPoint, mainPlayer, out Vector3 screenPoint))
+ if (WorldToScreen.GetScreenPoint(hitPoint, mainPlayer, out Vector3 screenPoint, FikaPlugin.PingUseOpticZoom.Value))
{
float distanceToCenter = Vector3.Distance(screenPoint, new Vector3(Screen.width, Screen.height, 0) / 2);
if (distanceToCenter < 200)
{
- image.color = new Color(_pingColor.r, _pingColor.g, _pingColor.b, Mathf.Max(0.05f, distanceToCenter / 200));
+ image.color = new Color(_pingColor.r, _pingColor.g, _pingColor.b, Mathf.Max(FikaPlugin.PingMinimumOpacity.Value, distanceToCenter / 200));
}
else
{
@@ -108,7 +108,16 @@ public virtual void Initialize(ref Vector3 point, Object userObject, Color pingC
float distance = Mathf.Clamp(Vector3.Distance(CameraClass.Instance.Camera.transform.position, transform.position) / 100, 0.4f, 0.6f);
float pingSize = FikaPlugin.PingSize.Value;
- image.rectTransform.localScale = new Vector3(pingSize, pingSize, pingSize) * distance;
+ Vector3 scaledSize = new(pingSize, pingSize, pingSize);
+ if (FikaPlugin.PingScaleWithDistance.Value == true)
+ {
+ scaledSize *= distance;
+ }
+ else
+ {
+ scaledSize *= 0.5f;
+ }
+ image.rectTransform.localScale = scaledSize;
}
}
diff --git a/Fika.Core/Coop/FreeCamera/FreeCamera.cs b/Fika.Core/Coop/FreeCamera/FreeCamera.cs
index a47b058c..efdc63c9 100644
--- a/Fika.Core/Coop/FreeCamera/FreeCamera.cs
+++ b/Fika.Core/Coop/FreeCamera/FreeCamera.cs
@@ -1,7 +1,9 @@
-using Comfort.Common;
+using BSG.CameraEffects;
+using Comfort.Common;
using EFT;
using Fika.Core.Coop.Components;
using Fika.Core.Coop.Players;
+using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
@@ -22,7 +24,12 @@ public class FreeCamera : MonoBehaviour
public bool IsActive = false;
private CoopPlayer CurrentPlayer;
private bool isFollowing = false;
+ private bool leftMode = false;
private bool disableInput = false;
+ private bool showOverlay;
+ private NightVision nightVision;
+ private ThermalVision thermalVision;
+ private FreeCameraController freeCameraController;
private KeyCode forwardKey = KeyCode.W;
private KeyCode backKey = KeyCode.S;
@@ -45,6 +52,52 @@ protected void Start()
relUpKey = KeyCode.E;
relDownKey = KeyCode.A;
}
+
+ showOverlay = FikaPlugin.KeybindOverlay.Value;
+ FikaPlugin.KeybindOverlay.SettingChanged += KeybindOverlay_SettingChanged;
+
+ nightVision = CameraClass.Instance.NightVision;
+ thermalVision = CameraClass.Instance.ThermalVision;
+
+ freeCameraController = Singleton.Instance.gameObject.GetComponent();
+ }
+
+ private void KeybindOverlay_SettingChanged(object sender, EventArgs e)
+ {
+ showOverlay = FikaPlugin.KeybindOverlay.Value;
+ }
+
+ protected void OnGUI()
+ {
+ if (IsActive && showOverlay)
+ {
+ string visionText = "Enable nightvision";
+
+ if (nightVision != null && nightVision.On)
+ {
+ visionText = "Enable thermals";
+ }
+
+ if (thermalVision != null && thermalVision.On)
+ {
+ visionText = "Disable thermals";
+ }
+
+ GUILayout.BeginArea(new Rect(5, 5, 800, 800));
+ GUILayout.BeginVertical();
+
+ GUILayout.Label($"Left/Right Mouse Button: Jump between players");
+ GUILayout.Label($"CTRL + Left/Right Mouse Button: Jump and spectate in 3rd person");
+ GUILayout.Label($"Spacebar + Left/Right Mouse Button: Jump and spectate in head cam");
+ GUILayout.Label($"T: Teleport to cam position");
+ GUILayout.Label($"N: {visionText}");
+ GUILayout.Label($"M: Disable culling");
+ GUILayout.Label($"HOME: {(disableInput ? "Enable Input" : "Disable Input")}");
+ GUILayout.Label($"Shift + Ctrl: Turbo Speed");
+
+ GUILayout.EndVertical();
+ GUILayout.EndArea();
+ }
}
protected void Update()
@@ -54,11 +107,11 @@ protected void Update()
return;
}
+ // Toggle input
if (Input.GetKeyDown(KeyCode.Home))
{
disableInput = !disableInput;
- string status = disableInput == true ? "disabled" : "enabled";
- NotificationManagerClass.DisplayMessageNotification($"Free cam input is now {status}.");
+ NotificationManagerClass.DisplayMessageNotification($"Free cam input is now {(disableInput ? "disabled" : "enabled")}.");
}
if (disableInput)
@@ -79,14 +132,14 @@ protected void Update()
if (players.Count > 0)
{
- bool shouldFollow = Input.GetKey(KeyCode.Space);
+ bool shouldHeadCam = Input.GetKey(KeyCode.Space);
bool should3rdPerson = Input.GetKey(KeyCode.LeftControl);
foreach (CoopPlayer player in players)
{
if (CurrentPlayer == null && players[0] != null)
{
CurrentPlayer = players[0];
- if (shouldFollow)
+ if (shouldHeadCam)
{
AttachToPlayer();
}
@@ -106,7 +159,7 @@ protected void Update()
if (players.Count - 1 >= nextPlayer)
{
CurrentPlayer = players[nextPlayer];
- if (shouldFollow)
+ if (shouldHeadCam)
{
AttachToPlayer();
}
@@ -123,7 +176,7 @@ protected void Update()
else
{
CurrentPlayer = players[0];
- if (shouldFollow)
+ if (shouldHeadCam)
{
AttachToPlayer();
}
@@ -240,14 +293,41 @@ protected void Update()
}
}
+ // Toggle vision
+ if (Input.GetKeyDown(KeyCode.N))
+ {
+ ToggleVision();
+ }
+
+ // Disable culling
+ if (Input.GetKeyDown(KeyCode.M))
+ {
+ if (freeCameraController != null)
+ {
+ freeCameraController.DisableAllCullingObjects();
+ }
+ }
+
if (isFollowing)
{
+ if (CurrentPlayer != null)
+ {
+ if (CurrentPlayer.MovementContext.LeftStanceEnabled && !leftMode)
+ {
+ SetLeftShoulderMode(true);
+ }
+ else if (!CurrentPlayer.MovementContext.LeftStanceEnabled && leftMode)
+ {
+ SetLeftShoulderMode(false);
+ }
+ }
return;
}
bool fastMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
bool superFastMode = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
float movementSpeed = fastMode ? 20f : 2f;
+
if (superFastMode)
{
movementSpeed *= 8;
@@ -255,22 +335,22 @@ protected void Update()
if (Input.GetKey(leftKey) || Input.GetKey(KeyCode.LeftArrow))
{
- transform.position += (-transform.right * (movementSpeed * Time.deltaTime));
+ transform.position += -transform.right * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(rightKey) || Input.GetKey(KeyCode.RightArrow))
{
- transform.position += (transform.right * (movementSpeed * Time.deltaTime));
+ transform.position += transform.right * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(forwardKey) || Input.GetKey(KeyCode.UpArrow))
{
- transform.position += (transform.forward * (movementSpeed * Time.deltaTime));
+ transform.position += transform.forward * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(backKey) || Input.GetKey(KeyCode.DownArrow))
{
- transform.position += (-transform.forward * (movementSpeed * Time.deltaTime));
+ transform.position += -transform.forward * (movementSpeed * Time.deltaTime);
}
// Teleportation
@@ -293,22 +373,22 @@ protected void Update()
{
if (Input.GetKey(relUpKey))
{
- transform.position += (transform.up * (movementSpeed * Time.deltaTime));
+ transform.position += transform.up * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(relDownKey))
{
- transform.position += (-transform.up * (movementSpeed * Time.deltaTime));
+ transform.position += -transform.up * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(upKey) || Input.GetKey(KeyCode.PageUp))
{
- transform.position += (Vector3.up * (movementSpeed * Time.deltaTime));
+ transform.position += Vector3.up * (movementSpeed * Time.deltaTime);
}
if (Input.GetKey(downKey) || Input.GetKey(KeyCode.PageDown))
{
- transform.position += (-Vector3.up * (movementSpeed * Time.deltaTime));
+ transform.position += -Vector3.up * (movementSpeed * Time.deltaTime);
}
}
@@ -317,6 +397,56 @@ protected void Update()
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
}
+ private void SetLeftShoulderMode(bool enabled)
+ {
+ if (enabled)
+ {
+ // Use different coordinates for headcam
+ if (transform.localPosition.z == -0.17f)
+ {
+ transform.localPosition = new(transform.localPosition.x, transform.localPosition.y, -transform.localPosition.z);
+ }
+ else
+ {
+ transform.localPosition = new(-transform.localPosition.x, transform.localPosition.y, transform.localPosition.z);
+ }
+ leftMode = true;
+
+ return;
+ }
+
+ // Use different coordinates for headcam
+ if (transform.localPosition.z == 0.17f)
+ {
+ transform.localPosition = new(transform.localPosition.x, transform.localPosition.y, -transform.localPosition.z);
+ }
+ else
+ {
+ transform.localPosition = new(-transform.localPosition.x, transform.localPosition.y, transform.localPosition.z);
+ }
+ leftMode = false;
+ }
+
+ private void ToggleVision()
+ {
+ if (nightVision != null && thermalVision != null)
+ {
+ if (!nightVision.On && !thermalVision.On)
+ {
+ nightVision.On = true;
+ }
+ else if (nightVision.On && !thermalVision.On)
+ {
+ nightVision.On = false;
+ thermalVision.On = true;
+ }
+ else if (thermalVision.On)
+ {
+ thermalVision.On = false;
+ }
+ }
+ }
+
public void JumpToPlayer()
{
transform.position = new Vector3(CurrentPlayer.Transform.position.x - 2, CurrentPlayer.Transform.position.y + 2, CurrentPlayer.Transform.position.z);
@@ -324,6 +454,7 @@ public void JumpToPlayer()
if (isFollowing)
{
isFollowing = false;
+ leftMode = false;
transform.parent = null;
}
}
@@ -346,8 +477,51 @@ public void Attach3rdPerson()
public void SetActive(bool status)
{
+ if (!status)
+ {
+ if (nightVision != null && nightVision.On)
+ {
+ nightVision.method_1(false);
+ }
+
+ if (thermalVision != null && thermalVision.On)
+ {
+ thermalVision.method_1(false);
+ }
+ }
+
+ if (status)
+ {
+ Player player = Singleton.Instance.MainPlayer;
+ if (player != null && player.HealthController.IsAlive)
+ {
+ if (player.NightVisionObserver.Component != null && player.NightVisionObserver.Component.Togglable.On)
+ {
+ player.NightVisionObserver.Component.Togglable.ForceToggle(false);
+ }
+
+ if (player.ThermalVisionObserver.Component != null && player.ThermalVisionObserver.Component.Togglable.On)
+ {
+ player.ThermalVisionObserver.Component.Togglable.ForceToggle(false);
+ }
+ }
+ else if (player != null && !player.HealthController.IsAlive)
+ {
+ if (nightVision != null && nightVision.On)
+ {
+ nightVision.method_1(false);
+ }
+
+ if (thermalVision != null && thermalVision.On)
+ {
+ thermalVision.method_1(false);
+ }
+ }
+ }
+
IsActive = status;
isFollowing = false;
+ leftMode = false;
transform.parent = null;
}
diff --git a/Fika.Core/Coop/FreeCamera/FreeCameraController.cs b/Fika.Core/Coop/FreeCamera/FreeCameraController.cs
index 812b80bb..2624262e 100644
--- a/Fika.Core/Coop/FreeCamera/FreeCameraController.cs
+++ b/Fika.Core/Coop/FreeCamera/FreeCameraController.cs
@@ -27,7 +27,7 @@ public class FreeCameraController : MonoBehaviour
//private GameObject _mainCamera;
private FreeCamera _freeCamScript;
- private BattleUIScreen _playerUi;
+ private EftBattleUIScreen _playerUi;
private bool _uiHidden;
private bool _effectsCleared = false;
@@ -46,6 +46,7 @@ public class FreeCameraController : MonoBehaviour
private bool deathFadeEnabled;
private DisablerCullingObjectBase[] allCullingObjects;
private List previouslyActiveBakeGroups;
+ private bool hasEnabledCulling = false;
protected void Awake()
{
@@ -145,8 +146,8 @@ protected void Update()
if (quitState == CoopHandler.EQuitState.YouHaveExtracted && !extracted)
{
- CoopGame coopGame = (CoopGame)coopHandler.LocalGameInstance;
- if (coopGame.ExtractedPlayers.Contains((_player).NetId))
+ CoopGame coopGame = coopHandler.LocalGameInstance;
+ if (coopGame.ExtractedPlayers.Contains(_player.NetId))
{
extracted = true;
ShowExtractMessage();
@@ -227,16 +228,16 @@ private void ClearEffects()
Traverse effectsController = Traverse.Create(cameraClass.EffectsController);
- BloodOnScreen bloodOnScreen = effectsController.Field("bloodOnScreen_0").GetValue();
+ BloodOnScreen bloodOnScreen = effectsController.Field("bloodOnScreen_0").Value;
if (bloodOnScreen != null)
{
Destroy(bloodOnScreen);
}
- List effectsManagerList = effectsController.Field("list_0").GetValue
>();
+ List effectsManagerList = effectsController.Field>("list_0").Value;
if (effectsManagerList != null)
{
- foreach (EffectsController.Class566 effectsManager in effectsManagerList)
+ foreach (EffectsController.Class576 effectsManager in effectsManagerList)
{
while (effectsManager.ActiveEffects.Count > 0)
{
@@ -267,8 +268,14 @@ private void ClearEffects()
Destroy(cameraClass.VisorEffect);
cameraClass.VisorSwitcher.Deinit();
Destroy(cameraClass.VisorSwitcher);
- Destroy(cameraClass.NightVision);
- Destroy(cameraClass.ThermalVision);
+ if (cameraClass.NightVision.On)
+ {
+ cameraClass.NightVision.method_1(false);
+ }
+ if (cameraClass.ThermalVision.On)
+ {
+ cameraClass.ThermalVision.method_1(false);
+ }
}
private void ShowExtractMessage()
@@ -326,7 +333,7 @@ private void ToggleUi()
return;
}
- _playerUi = gameObject.GetComponent();
+ _playerUi = gameObject.GetComponent();
if (_playerUi == null)
{
@@ -362,7 +369,29 @@ private void SetPlayerToFreecamMode(Player localPlayer)
_gamePlayerOwner.enabled = false;
_freeCamScript.SetActive(true);
+ }
+ ///
+ /// A helper method to reset the player view back to First Person
+ ///
+ ///
+ private void SetPlayerToFirstPersonMode(Player localPlayer)
+ {
+ // re-enable _gamePlayerOwner
+ _gamePlayerOwner.enabled = true;
+ _freeCamScript.SetActive(false);
+
+ localPlayer.PointOfView = EPointOfView.FirstPerson;
+ CameraClass.Instance.SetOcclusionCullingEnabled(true);
+
+ if (hasEnabledCulling)
+ {
+ EnableAllCullingObjects();
+ }
+ }
+
+ public void DisableAllCullingObjects()
+ {
int count = 0;
foreach (DisablerCullingObjectBase cullingObject in allCullingObjects)
{
@@ -373,7 +402,9 @@ private void SetPlayerToFreecamMode(Player localPlayer)
count++;
cullingObject.SetComponentsEnabled(true);
}
- FikaPlugin.Instance.FikaLogger.LogDebug($"Enabled {count} Culling Triggers.");
+#if DEBUG
+ FikaPlugin.Instance.FikaLogger.LogWarning($"Enabled {count} Culling Triggers.");
+#endif
PerfectCullingAdaptiveGrid perfectCullingAdaptiveGrid = FindObjectOfType();
if (perfectCullingAdaptiveGrid != null)
@@ -398,21 +429,12 @@ private void SetPlayerToFreecamMode(Player localPlayer)
}
}
}
+
+ hasEnabledCulling = true;
}
- ///
- /// A helper method to reset the player view back to First Person
- ///
- ///
- private void SetPlayerToFirstPersonMode(Player localPlayer)
+ public void EnableAllCullingObjects()
{
- // re-enable _gamePlayerOwner
- _gamePlayerOwner.enabled = true;
- _freeCamScript.SetActive(false);
-
- localPlayer.PointOfView = EPointOfView.FirstPerson;
- CameraClass.Instance.SetOcclusionCullingEnabled(true);
-
int count = 0;
foreach (DisablerCullingObjectBase cullingObject in allCullingObjects)
{
@@ -423,7 +445,9 @@ private void SetPlayerToFirstPersonMode(Player localPlayer)
count++;
cullingObject.SetComponentsEnabled(false);
}
- FikaPlugin.Instance.FikaLogger.LogDebug($"Disabled {count} Culling Triggers.");
+#if DEBUG
+ FikaPlugin.Instance.FikaLogger.LogWarning($"Disabled {count} Culling Triggers.");
+#endif
PerfectCullingAdaptiveGrid perfectCullingAdaptiveGrid = FindObjectOfType();
if (perfectCullingAdaptiveGrid != null)
@@ -450,6 +474,8 @@ private void SetPlayerToFirstPersonMode(Player localPlayer)
}
}
}
+
+ hasEnabledCulling = false;
}
///
diff --git a/Fika.Core/Coop/FreeCamera/Patches/DeathFade_Patch.cs b/Fika.Core/Coop/FreeCamera/Patches/DeathFade_Patch.cs
index c130fe39..3dda5851 100644
--- a/Fika.Core/Coop/FreeCamera/Patches/DeathFade_Patch.cs
+++ b/Fika.Core/Coop/FreeCamera/Patches/DeathFade_Patch.cs
@@ -1,4 +1,4 @@
-using Aki.Reflection.Patching;
+using SPT.Reflection.Patching;
using System;
using System.Reflection;
using UnityEngine;
diff --git a/Fika.Core/Coop/FreeCamera/FadeBlackScreen_Patch.cs b/Fika.Core/Coop/FreeCamera/Patches/FadeBlackScreen_Patch.cs
similarity index 93%
rename from Fika.Core/Coop/FreeCamera/FadeBlackScreen_Patch.cs
rename to Fika.Core/Coop/FreeCamera/Patches/FadeBlackScreen_Patch.cs
index 9bd93c5d..d0655da6 100644
--- a/Fika.Core/Coop/FreeCamera/FadeBlackScreen_Patch.cs
+++ b/Fika.Core/Coop/FreeCamera/Patches/FadeBlackScreen_Patch.cs
@@ -1,11 +1,11 @@
-using Aki.Reflection.Patching;
-using EFT.UI;
+using EFT.UI;
+using SPT.Reflection.Patching;
using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
-namespace Fika.Core.Coop.FreeCamera
+namespace Fika.Core.Coop.FreeCamera.Patches
{
internal class FadeBlackScreen_Patch : ModulePatch
{
diff --git a/Fika.Core/Coop/GameMode/AFikaGame.cs b/Fika.Core/Coop/GameMode/AFikaGame.cs
deleted file mode 100644
index b1acc974..00000000
--- a/Fika.Core/Coop/GameMode/AFikaGame.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using Aki.Reflection.Utils;
-using BepInEx.Logging;
-using Comfort.Common;
-using EFT;
-using EFT.InputSystem;
-using EFT.UI;
-using EFT.Weather;
-using JsonType;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-
-namespace Fika.Core.Coop.GameMode
-{
- public abstract class AFikaGame : BaseLocalGame, IBotGame
- {
- public new bool InRaid { get { return true; } }
-
- public ISession BackEndSession { get { return PatchConstants.BackEndSession; } }
-
- BotsController IBotGame.BotsController
- {
- get
- {
- if (BotsController == null)
- {
- BotsController = (BotsController)GetType().GetFields().Where(x => x.FieldType == typeof(BotsController)).FirstOrDefault().GetValue(this);
- }
- return BotsController;
- }
- }
-
- private static BotsController BotsController;
-
- public BotsController PBotsController
- {
- get
- {
- if (BotsController == null)
- {
- BotsController = (BotsController)GetType().GetFields().Where(x => x.FieldType == typeof(BotsController)).FirstOrDefault().GetValue(this);
- }
- return BotsController;
- }
- }
-
- public IWeatherCurve WeatherCurve
- {
- get
- {
- return WeatherController.Instance.WeatherCurve;
- }
- }
-
- ManualLogSource Logger { get; set; }
-
- public static T Create(InputTree inputTree, Profile profile, GameDateTime backendDateTime, InsuranceCompanyClass insurance, MenuUI menuUI,
- CommonUI commonUI, PreloaderUI preloaderUI, GameUI gameUI, LocationSettingsClass.Location location, TimeAndWeatherSettings timeAndWeather,
- WavesSettings wavesSettings, EDateTime dateTime, Callback callback, float fixedDeltaTime, EUpdateQueue updateQueue,
- ISession backEndSession, TimeSpan sessionTime) where T : AFikaGame
- {
-
- var r = smethod_0(inputTree, profile, backendDateTime, insurance, menuUI, commonUI, preloaderUI, gameUI, location, timeAndWeather, wavesSettings, dateTime,
- callback, fixedDeltaTime, updateQueue, backEndSession, new TimeSpan?(sessionTime));
-
- r.Logger = BepInEx.Logging.Logger.CreateLogSource("Coop Game Mode");
- r.Logger.LogInfo("CoopGame::Create");
-
- // Non Waves Scenario setup
- r.nonWavesSpawnScenario_0 = (NonWavesSpawnScenario)typeof(NonWavesSpawnScenario).GetMethod(nameof(NonWavesSpawnScenario.smethod_0), BindingFlags.Static | BindingFlags.Public).Invoke
- (null, [r, location, r.PBotsController]);
- r.nonWavesSpawnScenario_0.ImplementWaveSettings(wavesSettings);
-
- // Waves Scenario setup
- r.wavesSpawnScenario_0 = (WavesSpawnScenario)typeof(WavesSpawnScenario).GetMethod(nameof(WavesSpawnScenario.smethod_0), BindingFlags.Static | BindingFlags.Public).Invoke
- (null, [r.gameObject, location.waves, new Action(r.PBotsController.ActivateBotsByWave), location]);
-
- var bosswavemanagerValue = typeof(GClass579).GetMethod(nameof(GClass579.smethod_0), BindingFlags.Static | BindingFlags.Public).Invoke
- (null, [location.BossLocationSpawn, new Action(r.PBotsController.ActivateBotsByWave)]);
-
- r.GetType().GetFields(BindingFlags.NonPublic).Where(x => x.FieldType == typeof(GClass579)).FirstOrDefault().SetValue(r, bosswavemanagerValue);
-
- r.GClass579 = bosswavemanagerValue as GClass579;
-
- r.func_1 = (player) => GamePlayerOwner.Create(player, inputTree, insurance, backEndSession, commonUI, preloaderUI, gameUI, r.GameDateTime, location);
-
- return r;
- }
-
- public Dictionary Bots { get; set; } = new Dictionary();
-
- ///
- /// Matchmaker countdown
- ///
- ///
- public override void vmethod_1(float timeBeforeDeploy)
- {
- base.vmethod_1(timeBeforeDeploy);
- }
-
- ///
- /// Reconnection handling.
- ///
- public override void vmethod_3()
- {
- base.vmethod_3();
- }
-
- private GClass579 GClass579;
-
- private WavesSpawnScenario wavesSpawnScenario_0;
-
- private NonWavesSpawnScenario nonWavesSpawnScenario_0;
-
- private Func func_1;
-
- public new void method_6(string backendUrl, string locationId, int variantId)
- {
- Logger.LogInfo("CoopGame:method_6");
- return;
- }
- }
-}
diff --git a/Fika.Core/Coop/GameMode/CoopGame.cs b/Fika.Core/Coop/GameMode/CoopGame.cs
index e8ed5558..07321a44 100644
--- a/Fika.Core/Coop/GameMode/CoopGame.cs
+++ b/Fika.Core/Coop/GameMode/CoopGame.cs
@@ -1,13 +1,7 @@
-using Aki.Common.Http;
-using Aki.Custom.Airdrops;
-using Aki.Reflection.Utils;
-using Aki.SinglePlayer.Models.Progression;
-using Aki.SinglePlayer.Utils.Healing;
-using Aki.SinglePlayer.Utils.Insurance;
-using Aki.SinglePlayer.Utils.Progression;
-using BepInEx.Logging;
+using BepInEx.Logging;
using Comfort.Common;
using CommonAssets.Scripts.Game;
+using Coop.Airdrops;
using EFT;
using EFT.AssetsManager;
using EFT.Bots;
@@ -15,11 +9,11 @@
using EFT.Counters;
using EFT.EnvironmentEffect;
using EFT.Game.Spawning;
-using EFT.InputSystem;
using EFT.Interactive;
using EFT.InventoryLogic;
using EFT.UI;
using EFT.UI.BattleTimer;
+using EFT.UI.Matchmaker;
using EFT.UI.Screens;
using EFT.Weather;
using Fika.Core.Coop.BTR;
@@ -27,8 +21,8 @@
using Fika.Core.Coop.Components;
using Fika.Core.Coop.Custom;
using Fika.Core.Coop.FreeCamera;
-using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
+using Fika.Core.Coop.Utils;
using Fika.Core.Modding;
using Fika.Core.Modding.Events;
using Fika.Core.Networking;
@@ -40,6 +34,12 @@
using JsonType;
using LiteNetLib.Utils;
using Newtonsoft.Json;
+using SPT.Common.Http;
+using SPT.Reflection.Utils;
+using SPT.SinglePlayer.Models.Progression;
+using SPT.SinglePlayer.Utils.Healing;
+using SPT.SinglePlayer.Utils.Insurance;
+using SPT.SinglePlayer.Utils.Progression;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -51,35 +51,34 @@
namespace Fika.Core.Coop.GameMode
{
///
- /// A custom Game Type
+ /// Coop game used in Fika
///
- internal sealed class CoopGame : BaseLocalGame, IBotGame, IFikaGame
+ public sealed class CoopGame : BaseLocalGame, IBotGame, IFikaGame
{
public string InfiltrationPoint;
public bool HasAddedFenceRep = false;
- public bool forceStart = false;
public ExitStatus MyExitStatus { get; set; } = ExitStatus.Survived;
public string MyExitLocation { get; set; } = null;
public ISpawnSystem SpawnSystem;
-
public Dictionary Bots = [];
- private CoopExfilManager exfilManager;
- private GameObject fikaStartButton;
+ public List ExtractedPlayers { get; } = [];
+
private readonly Dictionary botQueue = [];
private Coroutine extractRoutine;
- private GClass2928 spawnPoints = null;
+ private SpawnPointManagerClass spawnPoints = null;
private ISpawnPoint spawnPoint = null;
- private GClass579 GClass579;
+ private BossSpawnWaveManagerClass BossSpawnWaveManagerClass;
private WavesSpawnScenario wavesSpawnScenario_0;
private NonWavesSpawnScenario nonWavesSpawnScenario_0;
- private Func func_1;
+ private Func func_1;
private bool hasSaved = false;
+ private CoopExfilManager exfilManager;
+ private CoopTimeManager timeManager;
+ private FikaDebug fikaDebug;
+ private bool isServer;
public FikaDynamicAI DynamicAI { get; private set; }
public RaidSettings RaidSettings { get; private set; }
- //WildSpawnType for sptUsec and sptBear
- const int sptUsecValue = 47;
- const int sptBearValue = 48;
public ISession BackEndSession { get => PatchConstants.BackEndSession; }
BotsController IBotGame.BotsController
{
@@ -105,19 +104,42 @@ public IWeatherCurve WeatherCurve
private static ManualLogSource Logger;
- internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTime backendDateTime, InsuranceCompanyClass insurance, MenuUI menuUI,
- CommonUI commonUI, PreloaderUI preloaderUI, GameUI gameUI, LocationSettingsClass.Location location, TimeAndWeatherSettings timeAndWeather,
- WavesSettings wavesSettings, EDateTime dateTime, Callback callback, float fixedDeltaTime, EUpdateQueue updateQueue,
+ ///
+ /// Creates a CoopGame
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static CoopGame Create(IInputTree inputTree, Profile profile, GameDateTime backendDateTime,
+ InsuranceCompanyClass insurance, MenuUI menuUI, GameUI gameUI, LocationSettingsClass.Location location,
+ TimeAndWeatherSettings timeAndWeather, WavesSettings wavesSettings, EDateTime dateTime,
+ Callback callback, float fixedDeltaTime, EUpdateQueue updateQueue,
ISession backEndSession, TimeSpan sessionTime, RaidSettings raidSettings)
{
- Logger = BepInEx.Logging.Logger.CreateLogSource("Coop Game Mode");
- Logger.LogInfo("CoopGame::Create");
+ Logger = BepInEx.Logging.Logger.CreateLogSource("CoopGame");
bool useCustomWeather = timeAndWeather.IsRandomWeather;
timeAndWeather.IsRandomWeather = false;
- CoopGame coopGame = smethod_0(inputTree, profile, backendDateTime, insurance, menuUI, commonUI,
- preloaderUI, gameUI, location, timeAndWeather, wavesSettings, dateTime, callback, fixedDeltaTime, updateQueue, backEndSession, new TimeSpan?(sessionTime));
+ CoopGame coopGame = smethod_0(inputTree, profile, backendDateTime, insurance, menuUI, gameUI,
+ location, timeAndWeather, wavesSettings, dateTime, callback, fixedDeltaTime, updateQueue, backEndSession,
+ new TimeSpan?(sessionTime));
+
+ coopGame.isServer = FikaBackendUtils.IsServer;
// Non Waves Scenario setup
coopGame.nonWavesSpawnScenario_0 = NonWavesSpawnScenario.smethod_0(coopGame, location, coopGame.botsController_0);
@@ -128,24 +150,69 @@ internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTi
coopGame.wavesSpawnScenario_0 = WavesSpawnScenario.smethod_0(coopGame.gameObject, waves, new Action(coopGame.botsController_0.ActivateBotsByWave), location);
BossLocationSpawn[] bossSpawns = LocalGame.smethod_8(wavesSettings, location.BossLocationSpawn);
- coopGame.GClass579 = GClass579.smethod_0(bossSpawns, new Action(coopGame.botsController_0.ActivateBotsByWave));
+ coopGame.BossSpawnWaveManagerClass = BossSpawnWaveManagerClass.smethod_0(bossSpawns, new Action(coopGame.botsController_0.ActivateBotsByWave));
- if (useCustomWeather && MatchmakerAcceptPatches.IsServer)
+ if (useCustomWeather && coopGame.isServer)
{
Logger.LogInfo("Custom weather enabled, initializing curves");
coopGame.SetupCustomWeather(timeAndWeather);
}
- coopGame.func_1 = (Player player) => GamePlayerOwner.Create(player, inputTree, insurance, backEndSession, commonUI, preloaderUI, gameUI, coopGame.GameDateTime, location);
+ SetupGamePlayerOwnerHandler setupGamePlayerOwnerHandler = new(inputTree, insurance, backEndSession, gameUI, coopGame, location);
+ coopGame.func_1 = new Func(setupGamePlayerOwnerHandler.HandleSetup);
Singleton.Create(coopGame);
FikaEventDispatcher.DispatchEvent(new FikaGameCreatedEvent(coopGame));
+ EndByExitTrigerScenario endByExitTrigger = coopGame.GetComponent();
+ EndByTimerScenario endByTimerScenario = coopGame.GetComponent();
+
+ if (endByExitTrigger != null)
+ {
+ Destroy(endByExitTrigger);
+ }
+ if (endByTimerScenario != null)
+ {
+ Destroy(endByTimerScenario);
+ }
+
+ coopGame.timeManager = CoopTimeManager.Create(coopGame);
+
coopGame.RaidSettings = raidSettings;
return coopGame;
}
+ ///
+ /// Used to create a
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private class SetupGamePlayerOwnerHandler(IInputTree inputTree, InsuranceCompanyClass insurance, ISession backEndSession, GameUI gameUI, CoopGame game, LocationSettingsClass.Location location)
+ {
+ private readonly IInputTree inputTree = inputTree;
+ private readonly InsuranceCompanyClass insurance = insurance;
+ private readonly ISession backEndSession = backEndSession;
+ private readonly GameUI gameUI = gameUI;
+ private readonly CoopGame game = game;
+ private readonly LocationSettingsClass.Location location = location;
+
+ public EftGamePlayerOwner HandleSetup(Player player)
+ {
+ EftGamePlayerOwner gamePlayerOwner = EftGamePlayerOwner.Create(player, inputTree, insurance, backEndSession, gameUI, game.GameDateTime, location);
+ gamePlayerOwner.OnLeave += game.vmethod_3;
+ return gamePlayerOwner;
+ }
+ }
+
+ ///
+ /// Sets up a custom weather curve
+ ///
+ /// Struct with custom settings
private void SetupCustomWeather(TimeAndWeatherSettings timeAndWeather)
{
if (WeatherController.Instance == null)
@@ -153,7 +220,7 @@ private void SetupCustomWeather(TimeAndWeatherSettings timeAndWeather)
return;
}
- DateTime dateTime = GClass1296.StartOfDay();
+ DateTime dateTime = EFTDateTimeClass.StartOfDay();
DateTime dateTime2 = dateTime.AddDays(1);
WeatherClass weather = WeatherClass.CreateDefault();
@@ -164,11 +231,25 @@ private void SetupCustomWeather(TimeAndWeatherSettings timeAndWeather)
weather.ScaterringFogDensity = weather2.ScaterringFogDensity = timeAndWeather.FogType.ToValue();
weather.Time = dateTime.Ticks;
weather2.Time = dateTime2.Ticks;
- WeatherController.Instance.method_4([weather, weather2]);
+ WeatherController.Instance.method_0([weather, weather2]);
}
- public async Task CreateCoopHandler()
+ public override void SetMatchmakerStatus(string status, float? progress = null)
{
+ if (CurrentScreenSingleton.Instance.CurrentScreenController is MatchmakerTimeHasCome.TimeHasComeScreenClass gclass)
+ {
+ gclass.ChangeStatus(status, progress);
+ }
+ }
+
+ ///
+ /// Creates and initializes the
+ ///
+ ///
+ /// If no ServerId was found
+ public Task CreateCoopHandler()
+ {
+ Logger.LogInfo("Creating CoopHandler...");
CoopHandler coopHandler = CoopHandler.GetCoopHandler();
if (coopHandler != null)
{
@@ -190,39 +271,25 @@ public async Task CreateCoopHandler()
coopHandler = CoopHandler.CoopHandlerParent.AddComponent();
coopHandler.LocalGameInstance = this;
- if (!string.IsNullOrEmpty(MatchmakerAcceptPatches.GetGroupId()))
+ if (!string.IsNullOrEmpty(FikaBackendUtils.GetGroupId()))
{
- coopHandler.ServerId = MatchmakerAcceptPatches.GetGroupId();
+ coopHandler.ServerId = FikaBackendUtils.GetGroupId();
}
else
{
Destroy(coopHandler);
Logger.LogError("No Server Id found, Deleting Coop Handler");
- throw new Exception("No Server Id found");
- }
-
- if (MatchmakerAcceptPatches.IsServer)
- {
- FikaServer server = gameObject.AddComponent();
-
- while (!server.ServerReady)
- {
- await Task.Delay(100);
- }
- Logger.LogInfo("FikaServer has started!");
+ throw new MissingReferenceException("No Server Id found");
}
- else if (MatchmakerAcceptPatches.IsClient)
- {
- FikaClient client = gameObject.AddComponent();
- while (!client.ClientReady)
- {
- await Task.Delay(100);
- }
- Logger.LogInfo("FikaClient has started!");
- }
+ return Task.CompletedTask;
}
+ ///
+ /// Returns all human players
+ ///
+ /// used to fetch players
+ ///
private List GetPlayers(CoopHandler coopHandler)
{
List humanPlayers = [];
@@ -238,6 +305,12 @@ private List GetPlayers(CoopHandler coopHandler)
return humanPlayers;
}
+ ///
+ /// Calculates the distance from all players
+ ///
+ /// The position
+ /// of all human s
+ ///
private float GetDistanceFromPlayers(Vector3 position, List humanPlayers)
{
float distance = float.PositiveInfinity;
@@ -254,13 +327,17 @@ private float GetDistanceFromPlayers(Vector3 position, List humanPla
return distance;
}
- private string GetFurthestBot(Dictionary bots, CoopHandler coopHandler, out float furthestDistance)
+ ///
+ /// Grabs the bot furthest away from all players and returns its distance
+ ///
+ /// List of all human s
+ /// The furthest distance
+ ///
+ private string GetFurthestBot(List humanPlayers, out float furthestDistance)
{
string furthestBot = string.Empty;
furthestDistance = 0f;
- List humanPlayers = GetPlayers(coopHandler);
-
foreach (var botKeyValuePair in Bots)
{
if (IsInvalidBotForDespawning(botKeyValuePair))
@@ -280,6 +357,11 @@ private string GetFurthestBot(Dictionary bots, CoopHandler coopH
return furthestBot;
}
+ ///
+ /// Checks whether this bot is valid for despawning
+ ///
+ /// of profileId and player
+ ///
private bool IsInvalidBotForDespawning(KeyValuePair kvp)
{
if (kvp.Value == null || kvp.Value == null || kvp.Value.Position == null)
@@ -302,21 +384,27 @@ private bool IsInvalidBotForDespawning(KeyValuePair kvp)
WildSpawnType role = kvp.Value.Profile.Info.Settings.Role;
- if ((int)role != sptUsecValue && (int)role != sptBearValue && role != WildSpawnType.assault)
+ if (role is not WildSpawnType.pmcUSEC and not WildSpawnType.pmcBEAR and not WildSpawnType.assault)
{
- // We skip all the bots that are not sptUsec, sptBear or assault. That means we never remove bosses, bossfollowers, and raiders
+ // We skip all the bots that are not pmcUSEC, pmcBEAR or assault. That means we never remove bosses, bossfollowers, and raiders
return true;
}
return false;
}
+ ///
+ /// Used to spawn a bot for the host
+ ///
+ /// to spawn
+ /// The position to spawn on
+ ///
private async Task CreateBot(Profile profile, Vector3 position)
{
#if DEBUG
Logger.LogWarning($"Creating bot {profile.Info.Settings.Role} at {position}");
#endif
- if (MatchmakerAcceptPatches.IsClient)
+ if (!isServer)
{
return null;
}
@@ -329,7 +417,7 @@ private async Task CreateBot(Profile profile, Vector3 position)
WildSpawnType role = profile.Info.Settings.Role;
bool isSpecial = false;
- if ((int)role != sptUsecValue && (int)role != sptBearValue && role != WildSpawnType.assault)
+ if (role is not WildSpawnType.pmcUSEC and not WildSpawnType.pmcBEAR and not WildSpawnType.assault)
{
#if DEBUG
Logger.LogWarning($"Bot {profile.Info.Settings.Role} is a special bot.");
@@ -343,14 +431,14 @@ private async Task CreateBot(Profile profile, Vector3 position)
if (FikaPlugin.DespawnFurthest.Value)
{
- despawned = TryDespawnFurthest(profile, position, coopHandler);
+ despawned = TryDespawnFurthestBot(profile, position, coopHandler);
}
// If it's not special and we didnt despawn something, we dont spawn a new bot.
if (!isSpecial && !despawned)
{
#if DEBUG
- Logger.LogWarning($"Stopping spawn of bot {profile.Nickname}, max count reached and enforced limits enabled. Current: {botsController_0.AliveAndLoadingBotsCount}, Max: {botsController_0.BotSpawner.MaxBots}");
+ Logger.LogWarning($"Stopping spawn of bot {profile.Nickname}, max count reached and enforced limits enabled. Current: {Bots.Count}, Max: {botsController_0.BotSpawner.MaxBots}, Alive & Loading: {botsController_0.BotSpawner.AliveAndLoadingBotsCount}");
#endif
return null;
}
@@ -375,7 +463,7 @@ private async Task CreateBot(Profile profile, Vector3 position)
FikaServer server = Singleton.Instance;
netId = server.PopNetId();
- SendCharacterPacket packet = new(new FikaSerialization.PlayerInfoPacket() { Profile = profile }, true, true, position, netId);
+ SendCharacterPacket packet = new(new FikaSerialization.PlayerInfoPacket(profile), true, true, position, netId);
Singleton.Instance.SendDataToAll(new NetDataWriter(), ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
if (server.NetServer.ConnectedPeersCount > 0)
@@ -385,8 +473,8 @@ private async Task CreateBot(Profile profile, Vector3 position)
localPlayer = await CoopBot.CreateBot(num, position, Quaternion.identity, "Player",
"Bot_", EPointOfView.ThirdPerson, profile, true, UpdateQueue, Player.EUpdateMode.Manual,
- Player.EUpdateMode.Auto, GClass549.Config.CharacterController.BotPlayerMode, () => 1f,
- () => 1f, GClass1446.Default);
+ Player.EUpdateMode.Auto, BackendConfigAbstractClass.Config.CharacterController.BotPlayerMode, () => 1f,
+ () => 1f, GClass1457.Default);
localPlayer.Location = Location_0.Id;
@@ -403,7 +491,7 @@ private async Task CreateBot(Profile profile, Vector3 position)
Bots.Add(localPlayer.ProfileId, localPlayer);
}
- if (profile.Info.Side == EPlayerSide.Bear || profile.Info.Side == EPlayerSide.Usec)
+ if (profile.Info.Side is EPlayerSide.Bear or EPlayerSide.Usec)
{
Slot backpackSlot = profile.Inventory.Equipment.GetSlot(EquipmentSlot.Backpack);
Item backpack = backpackSlot.ContainedItem;
@@ -441,11 +529,19 @@ private async Task CreateBot(Profile profile, Vector3 position)
CoopBot coopBot = (CoopBot)localPlayer;
coopBot.NetId = netId;
+ if (FikaPlugin.DisableBotMetabolism.Value)
+ {
+ coopBot.HealthController.DisableMetabolism();
+ }
coopHandler.Players.Add(coopBot.NetId, coopBot);
return localPlayer;
}
+ ///
+ /// Increments the amount of players that have loaded a bot, used for
+ ///
+ ///
public void IncreaseLoadedPlayers(int netId)
{
if (botQueue.ContainsKey(netId))
@@ -458,6 +554,11 @@ public void IncreaseLoadedPlayers(int netId)
}
}
+ ///
+ /// used to ensure that all players loads a bot before it spawns
+ ///
+ /// The NetId to spawn
+ ///
private async Task WaitForPlayersToLoadBotProfile(int netId)
{
botQueue.Add(netId, 0);
@@ -479,19 +580,28 @@ private async Task WaitForPlayersToLoadBotProfile(int netId)
botQueue.Remove(netId);
}
- private bool TryDespawnFurthest(Profile profile, Vector3 position, CoopHandler coopHandler)
+ ///
+ /// Tries to despawn the furthest bot from all players
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool TryDespawnFurthestBot(Profile profile, Vector3 position, CoopHandler coopHandler)
{
- string botKey = GetFurthestBot(Bots, coopHandler, out float furthestDistance);
+ List humanPlayers = GetPlayers(coopHandler);
+
+ string botKey = GetFurthestBot(humanPlayers, out float furthestDistance);
if (botKey == string.Empty)
{
#if DEBUG
- Logger.LogWarning("TryDespawnFurthest: botKey was empty");
+ Logger.LogWarning("TryDespawnFurthest: botKey was empty");
#endif
return false;
}
- if (furthestDistance > GetDistanceFromPlayers(position, GetPlayers(coopHandler)))
+ if (furthestDistance > GetDistanceFromPlayers(position, humanPlayers))
{
#if DEBUG
Logger.LogWarning($"We're not despawning anything. The furthest bot is closer than the one we wanted to spawn.");
@@ -509,7 +619,7 @@ private bool TryDespawnFurthest(Profile profile, Vector3 position, CoopHandler c
}
Player bot = Bots[botKey];
#if DEBUG
- Logger.LogWarning($"Removing {bot.Profile.Info.Settings.Role} at a distance of {Math.Sqrt(furthestDistance)}m from ITs nearest player.");
+ Logger.LogWarning($"Removing {bot.Profile.Info.Settings.Role} at a distance of {Math.Sqrt(furthestDistance)}m from its nearest player.");
#endif
DespawnBot(coopHandler, bot);
#if DEBUG
@@ -518,6 +628,11 @@ private bool TryDespawnFurthest(Profile profile, Vector3 position, CoopHandler c
return true;
}
+ ///
+ /// Despawns a bot
+ ///
+ ///
+ /// The bot to despawn
private void DespawnBot(CoopHandler coopHandler, Player bot)
{
IBotGame botGame = Singleton.Instance;
@@ -537,61 +652,71 @@ private void DespawnBot(CoopHandler coopHandler, Player bot)
}
///
- /// We use instead
+ /// The countdown deploy screen
///
- ///
- public override void vmethod_1(float timeBeforeDeploy)
+ ///
+ public override IEnumerator vmethod_1()
{
- /// Do nothing
+ CoopPlayer coopPlayer = (CoopPlayer)PlayerOwner.Player;
+ coopPlayer.PacketSender.Init();
+
+ int timeBeforeDeployLocal = Singleton.Instance.TimeBeforeDeployLocal;
+ DateTime dateTime = EFTDateTimeClass.Now.AddSeconds(timeBeforeDeployLocal);
+ new MatchmakerFinalCountdown.FinalCountdownScreenClass(Profile_0, dateTime).ShowScreen(EScreenState.Root);
+ MonoBehaviourSingleton.Instance.FadeInVolumeBeforeRaid(timeBeforeDeployLocal);
+ Singleton.Instance.StopMenuBackgroundMusicWithDelay(timeBeforeDeployLocal);
+ GameUi.gameObject.SetActive(true);
+ GameUi.TimerPanel.ProfileId = ProfileId;
+ yield return new WaitForSeconds(timeBeforeDeployLocal);
}
///
- /// Matchmaker countdown
+ /// This task ensures that all players are joined and loaded before continuing
///
- /// Time in seconds to count down
- private async void DeployScreen(float timeBeforeDeploy)
+ ///
+ private IEnumerator WaitForOtherPlayers()
{
if (CoopHandler.TryGetCoopHandler(out CoopHandler coopHandler))
{
- if (MatchmakerAcceptPatches.IsServer && MatchmakerAcceptPatches.HostExpectedNumberOfPlayers <= 1)
+ if (isServer && FikaBackendUtils.HostExpectedNumberOfPlayers <= 1)
{
- if (fikaStartButton != null)
- {
- Destroy(fikaStartButton);
- }
-
if (DynamicAI != null)
{
DynamicAI.AddHumans();
}
SetStatusModel status = new(coopHandler.MyPlayer.ProfileId, LobbyEntry.ELobbyStatus.IN_GAME);
- await FikaRequestHandler.UpdateSetStatus(status);
+ Task updateStatus = FikaRequestHandler.UpdateSetStatus(status);
+
+ while (!updateStatus.IsCompleted)
+ {
+ yield return null;
+ }
Singleton.Instance.ReadyClients++;
- base.vmethod_1(timeBeforeDeploy);
- return;
+ yield break;
}
NetDataWriter writer = new();
- forceStart = false;
- MatchmakerAcceptPatches.GClass3163.ChangeStatus("Waiting for other players to finish loading...");
+ FikaBackendUtils.ScreenController.ChangeStatus("Waiting for other players to finish loading...");
- if (fikaStartButton != null)
- {
- fikaStartButton.SetActive(true);
- }
+ int expectedPlayers = FikaBackendUtils.HostExpectedNumberOfPlayers;
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
SetStatusModel status = new(coopHandler.MyPlayer.ProfileId, LobbyEntry.ELobbyStatus.IN_GAME);
- await FikaRequestHandler.UpdateSetStatus(status);
+ Task updateStatus = FikaRequestHandler.UpdateSetStatus(status);
+
+ while (!updateStatus.IsCompleted)
+ {
+ yield return null;
+ }
do
{
- await Task.Delay(100);
- } while (coopHandler.HumanPlayers < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart);
+ yield return null;
+ } while (coopHandler.HumanPlayers < expectedPlayers);
FikaServer server = Singleton.Instance;
server.ReadyClients++;
@@ -605,8 +730,9 @@ private async void DeployScreen(float timeBeforeDeploy)
do
{
- await Task.Delay(250);
- } while (Singleton.Instance.ReadyClients < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart);
+ FikaBackendUtils.ScreenController.ChangeStatus("Waiting for other players to finish loading...", server.ReadyClients / expectedPlayers);
+ yield return new WaitForEndOfFrame();
+ } while (server.ReadyClients < expectedPlayers);
foreach (CoopPlayer player in coopHandler.Players.Values)
{
@@ -621,12 +747,12 @@ private async void DeployScreen(float timeBeforeDeploy)
DynamicAI.AddHumans();
}
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
do
{
- await Task.Delay(100);
- } while (coopHandler.HumanPlayers < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart);
+ yield return null;
+ } while (coopHandler.HumanPlayers < expectedPlayers);
FikaClient client = Singleton.Instance;
InformationPacket packet = new(true)
@@ -638,23 +764,20 @@ private async void DeployScreen(float timeBeforeDeploy)
do
{
- await Task.Delay(250);
- } while (Singleton.Instance.ReadyClients < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart);
+ FikaBackendUtils.ScreenController.ChangeStatus("Waiting for other players to finish loading...", client.ReadyClients / expectedPlayers);
+ yield return new WaitForEndOfFrame();
+ } while (client.ReadyClients < expectedPlayers);
}
-
- if (fikaStartButton != null)
- {
- Destroy(fikaStartButton);
- }
-
}
-
- base.vmethod_1(timeBeforeDeploy);
}
+ ///
+ /// Sends or receives the for the game
+ ///
+ ///
private async Task SendOrReceiveSpawnPoint()
{
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
bool spawnTogether = RaidSettings.PlayersSpawnPlace == EPlayersSpawnPlace.SamePlace;
UpdateSpawnPointRequest body = new(spawnTogether ? spawnPoint.Id : "");
@@ -669,7 +792,7 @@ private async Task SendOrReceiveSpawnPoint()
}
await FikaRequestHandler.UpdateSpawnPoint(body);
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
SpawnPointRequest body = new();
SpawnPointResponse response = await FikaRequestHandler.RaidSpawnPoint(body);
@@ -679,7 +802,7 @@ private async Task SendOrReceiveSpawnPoint()
{
Logger.LogInfo($"Retrieved Spawn Point '{name}' from server");
- Dictionary allSpawnPoints = Traverse.Create(spawnPoints).Field("dictionary_0").GetValue>();
+ Dictionary allSpawnPoints = Traverse.Create(spawnPoints).Field>("dictionary_0").Value;
foreach (ISpawnPoint spawnPointObject in allSpawnPoints.Keys)
{
if (spawnPointObject.Id == name)
@@ -698,7 +821,7 @@ private async Task SendOrReceiveSpawnPoint()
}
///
- /// Creating the EFT.LocalPlayer
+ ///
///
///
///
@@ -716,27 +839,29 @@ private async Task SendOrReceiveSpawnPoint()
///
///
///
+ ///
///
+ ///
public override async Task vmethod_2(int playerId, Vector3 position, Quaternion rotation,
string layerName, string prefix, EPointOfView pointOfView, Profile profile, bool aiControl,
EUpdateQueue updateQueue, Player.EUpdateMode armsUpdateMode, Player.EUpdateMode bodyUpdateMode,
CharacterControllerSpawner.Mode characterControllerMode, Func getSensitivity, Func getAimingSensitivity,
IStatisticsManager statisticsManager, AbstractQuestControllerClass questController, AbstractAchievementControllerClass achievementsController)
{
- Logger.LogInfo("Creating CoopHandler");
await CreateCoopHandler();
- CoopHandler.GetCoopHandler().LocalGameInstance = this;
-
- LocalPlayer myPlayer = await CoopPlayer.Create(playerId, spawnPoint.Position, spawnPoint.Rotation, "Player", "Main_", EPointOfView.FirstPerson, profile,
- false, UpdateQueue, armsUpdateMode, bodyUpdateMode,
- GClass549.Config.CharacterController.ClientPlayerMode, getSensitivity,
- getAimingSensitivity, new GClass1445(), MatchmakerAcceptPatches.IsServer ? 0 : 1000, statisticsManager);
profile.SetSpawnedInSession(profile.Side == EPlayerSide.Savage);
+ LocalPlayer myPlayer = await CoopPlayer.Create(playerId, spawnPoint.Position, spawnPoint.Rotation, "Player",
+ "Main_", EPointOfView.FirstPerson, profile, false, UpdateQueue, armsUpdateMode, bodyUpdateMode,
+ BackendConfigAbstractClass.Config.CharacterController.ClientPlayerMode, getSensitivity,
+ getAimingSensitivity, new GClass1456(), isServer ? 0 : 1000, statisticsManager);
+
+ await NetManagerUtils.InitNetManager(isServer);
+
if (!CoopHandler.TryGetCoopHandler(out CoopHandler coopHandler))
{
- Logger.LogDebug($"{nameof(vmethod_2)}:Unable to find {nameof(CoopHandler)}");
+ Logger.LogError($"{nameof(vmethod_2)}:Unable to find {nameof(CoopHandler)}");
throw new MissingComponentException("CoopHandler was missing during CoopGame init");
}
@@ -749,19 +874,20 @@ public override async Task vmethod_2(int playerId, Vector3 position
CoopPlayer coopPlayer = (CoopPlayer)myPlayer;
coopHandler.Players.Add(coopPlayer.NetId, coopPlayer);
- PlayerSpawnRequest body = new(myPlayer.ProfileId, MatchmakerAcceptPatches.GetGroupId());
+ PlayerSpawnRequest body = new(myPlayer.ProfileId, FikaBackendUtils.GetGroupId());
await FikaRequestHandler.UpdatePlayerSpawn(body);
myPlayer.SpawnPoint = spawnPoint;
GameObject customButton = null;
- GameObject customButtonStart = null;
+
+ await NetManagerUtils.SetupGameVariables(isServer, coopPlayer);
// This creates a "custom" Back button so that we can back out if we get stuck
if (MenuUI.Instantiated)
{
MenuUI menuUI = MenuUI.Instance;
- DefaultUIButton backButton = Traverse.Create(menuUI.MatchmakerTimeHasCome).Field("_cancelButton").GetValue();
+ DefaultUIButton backButton = Traverse.Create(menuUI.MatchmakerTimeHasCome).Field("_cancelButton").Value;
customButton = Instantiate(backButton.gameObject, backButton.gameObject.transform.parent);
customButton.gameObject.name = "FikaBackButton";
customButton.gameObject.transform.position = new(customButton.transform.position.x, customButton.transform.position.y - 20, customButton.transform.position.z);
@@ -772,59 +898,21 @@ public override async Task vmethod_2(int playerId, Vector3 position
UnityEngine.Events.UnityEvent newEvent = new();
newEvent.AddListener(() =>
{
- Singleton.Instance.ShowCriticalErrorScreen("WARNING", message: "Backing out from this stage is currently experimental. It is recommended to ALT+F4 instead. Do you still want to continue?",
+ Singleton.Instance.ShowCriticalErrorScreen("WARNING",
+ message: "Backing out from this stage is currently experimental. It is recommended to ALT+F4 instead. Do you still want to continue?",
ErrorScreen.EButtonType.OkButton, 15f, () =>
{
- StopFromError(myPlayer.ProfileId, ExitStatus.Runner);
+ StopFromCancel(myPlayer.ProfileId, ExitStatus.Runner);
PlayerLeftRequest playerLeftRequest = new(coopPlayer.ProfileId);
FikaRequestHandler.RaidLeave(playerLeftRequest);
}, null);
});
Traverse.Create(backButtonComponent).Field("OnClick").SetValue(newEvent);
-
- if (MatchmakerAcceptPatches.IsServer)
- {
- DefaultUIButton startButton = Traverse.Create(menuUI.MatchmakerTimeHasCome).Field("_cancelButton").GetValue();
- customButtonStart = Instantiate(backButton.gameObject, backButton.gameObject.transform.parent);
- customButtonStart.gameObject.name = "FikaStartButton";
- customButtonStart.gameObject.SetActive(true);
- customButtonStart.gameObject.transform.position = new(customButton.transform.position.x, customButton.transform.position.y + 60, customButton.transform.position.z);
- DefaultUIButton startButtonComponent = customButtonStart.GetComponent();
- startButtonComponent.SetHeaderText("Force Start", 32);
- startButtonComponent.SetEnabledTooltip("EXPERIMENTAL: Force starts the game. Use at own risk!");
- UnityEngine.Events.UnityEvent newStartEvent = new();
- newStartEvent.AddListener(() =>
- {
- forceStart = true;
-
- InformationPacket packet = new(false)
- {
- ForceStart = true
- };
-
- FikaPlugin.Instance.FikaLogger.LogWarning("Force start was used!");
-
- NetDataWriter writer = new();
- writer.Reset();
- Singleton.Instance.SendDataToAll(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
-
- if (fikaStartButton != null)
- {
- fikaStartButton.SetActive(false);
- }
- });
- Traverse.Create(startButtonComponent).Field("OnClick").SetValue(newStartEvent);
- if (customButton != null)
- {
- customButton.SetActive(true);
- }
- fikaStartButton = customButtonStart;
- }
}
- SendCharacterPacket packet = new(new FikaSerialization.PlayerInfoPacket() { Profile = myPlayer.Profile }, myPlayer.HealthController.IsAlive, false, myPlayer.Transform.position, (myPlayer as CoopPlayer).NetId);
+ SendCharacterPacket packet = new(new FikaSerialization.PlayerInfoPacket(myPlayer.Profile), myPlayer.HealthController.IsAlive, false, myPlayer.Transform.position, (myPlayer as CoopPlayer).NetId);
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
await SetStatus(myPlayer, LobbyEntry.ELobbyStatus.COMPLETE);
}
@@ -833,51 +921,26 @@ public override async Task vmethod_2(int playerId, Vector3 position
Singleton.Instance.SendData(new NetDataWriter(), ref packet, LiteNetLib.DeliveryMethod.ReliableUnordered);
}
- if (MatchmakerAcceptPatches.IsServer)
- {
- while (!Singleton.Instantiated && !Singleton.Instance.ServerReady)
- {
- await Task.Delay(100);
- }
- }
- else if (MatchmakerAcceptPatches.IsClient)
- {
- while (!Singleton.Instantiated && !Singleton.Instance.ClientReady)
- {
- await Task.Delay(100);
- }
- }
-
await WaitForPlayers();
- Destroy(customButton);
- if (fikaStartButton != null)
- {
- fikaStartButton.SetActive(false);
- }
+ fikaDebug = gameObject.AddComponent();
- myPlayer.ActiveHealthController.DiedEvent += MainPlayerDied;
+ Destroy(customButton);
return myPlayer;
}
- private void MainPlayerDied(EDamageType obj)
- {
- EndByTimerScenario endByTimerScenario = GetComponent();
- if (endByTimerScenario != null)
- {
- Destroy(endByTimerScenario);
- }
- if (GameUi.TimerPanel.enabled)
- {
- GameUi.TimerPanel.Close();
- }
- }
-
- public async Task InitPlayer(BotControllerSettings botsSettings, string backendUrl, InventoryControllerClass inventoryController, Callback runCallback)
+ ///
+ /// Initializes the local player
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task InitPlayer(BotControllerSettings botsSettings, string backendUrl, Callback runCallback)
{
Status = GameStatus.Running;
- UnityEngine.Random.InitState((int)GClass1296.Now.Ticks);
+ UnityEngine.Random.InitState((int)EFTDateTimeClass.Now.Ticks);
LocationSettingsClass.Location location;
if (Location_0.IsHideout)
@@ -886,11 +949,11 @@ public async Task InitPlayer(BotControllerSettings botsSettings, string backendU
}
else
{
- using (GClass21.StartWithToken("LoadLocation"))
+ using (CounterCreatorAbstractClass.StartWithToken("LoadLocation"))
{
int num = UnityEngine.Random.Range(1, 6);
method_6(backendUrl, Location_0.Id, num);
- location = await ginterface145_0.LoadLocationLoot(Location_0.Id, num);
+ location = await BackEndSession.LoadLocationLoot(Location_0.Id, num);
}
}
@@ -904,16 +967,16 @@ public async Task InitPlayer(BotControllerSettings botsSettings, string backendU
}
else
{
- Logger.LogError("Can't find event prefab in resources. Path : Prefabs/HALLOWEEN_CONTROLLER");
+ Logger.LogError("Can't find event prefab in resources. Path: 'Prefabs/HALLOWEEN_CONTROLLER'");
}
}
- GClass785 config = GClass549.Config;
+ ApplicationConfigClass config = BackendConfigAbstractClass.Config;
if (config.FixedFrameRate > 0f)
{
FixedDeltaTime = 1f / config.FixedFrameRate;
}
- using (GClass21.StartWithToken("player create"))
+ using (CounterCreatorAbstractClass.StartWithToken("player create"))
{
Player player = await CreateLocalPlayer();
dictionary_0.Add(player.ProfileId, player);
@@ -928,9 +991,16 @@ public async Task InitPlayer(BotControllerSettings botsSettings, string backendU
await method_11(location, startHandler.FinishLoading);
}
- private class StartHandler(BaseLocalGame localGame, BotControllerSettings botSettings, ISpawnSystem spawnSystem, Callback runCallback)
+ ///
+ /// Handler used to start the game
+ ///
+ ///
+ ///
+ ///
+ ///
+ private class StartHandler(BaseLocalGame localGame, BotControllerSettings botSettings, ISpawnSystem spawnSystem, Callback runCallback)
{
- private readonly BaseLocalGame localGame = localGame;
+ private readonly BaseLocalGame localGame = localGame;
private readonly BotControllerSettings botSettings = botSettings;
private readonly ISpawnSystem spawnSystem = spawnSystem;
private readonly Callback runCallback = runCallback;
@@ -941,28 +1011,32 @@ public void FinishLoading()
}
}
+ ///
+ /// Creates the local player
+ ///
+ /// A
private async Task CreateLocalPlayer()
{
int num = method_12();
Player.EUpdateMode eupdateMode = Player.EUpdateMode.Auto;
- if (GClass549.Config.UseHandsFastAnimator)
+ if (BackendConfigAbstractClass.Config.UseHandsFastAnimator)
{
eupdateMode = Player.EUpdateMode.Manual;
}
- spawnPoints = GClass2928.CreateFromScene(new DateTime?(GClass1296.LocalDateTimeFromUnixTime(Location_0.UnixDateTime)), Location_0.SpawnPointParams);
+ spawnPoints = SpawnPointManagerClass.CreateFromScene(new DateTime?(EFTDateTimeClass.LocalDateTimeFromUnixTime(Location_0.UnixDateTime)), Location_0.SpawnPointParams);
int spawnSafeDistance = (Location_0.SpawnSafeDistanceMeters > 0) ? Location_0.SpawnSafeDistanceMeters : 100;
- GStruct380 settings = new(Location_0.MinDistToFreePoint, Location_0.MaxDistToFreePoint, Location_0.MaxBotPerZone, spawnSafeDistance);
- SpawnSystem = GClass2929.CreateSpawnSystem(settings, () => Time.time, Singleton.Instance, zones: botsController_0, spawnPoints);
+ GStruct379 settings = new(Location_0.MinDistToFreePoint, Location_0.MaxDistToFreePoint, Location_0.MaxBotPerZone, spawnSafeDistance);
+ SpawnSystem = GClass2950.CreateSpawnSystem(settings, new Func(Class1384.class1384_0.method_0), Singleton.Instance, zones: botsController_0, spawnPoints);
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
spawnPoint = SpawnSystem.SelectSpawnPoint(ESpawnCategory.Player, Profile_0.Info.Side);
await SendOrReceiveSpawnPoint();
}
- if (MatchmakerAcceptPatches.IsClient)
+ if (!isServer)
{
await SendOrReceiveSpawnPoint();
if (spawnPoint == null)
@@ -975,8 +1049,8 @@ private async Task CreateLocalPlayer()
IStatisticsManager statisticsManager = new CoopClientStatisticsManager(Profile_0);
LocalPlayer myPlayer = await vmethod_2(num, spawnPoint.Position, spawnPoint.Rotation, "Player", "Main_", EPointOfView.FirstPerson, Profile_0, false,
- UpdateQueue, eupdateMode, Player.EUpdateMode.Auto, GClass549.Config.CharacterController.ClientPlayerMode,
- new Func(Class1362.class1362_0.method_1), new Func(Class1362.class1362_0.method_2),
+ UpdateQueue, eupdateMode, Player.EUpdateMode.Auto, BackendConfigAbstractClass.Config.CharacterController.ClientPlayerMode,
+ new Func(Class1384.class1384_0.method_3), new Func(Class1384.class1384_0.method_4),
statisticsManager, null, null);
myPlayer.Location = Location_0.Id;
@@ -985,53 +1059,47 @@ private async Task CreateLocalPlayer()
return myPlayer;
}
+ ///
+ /// used to wait for all other players to join the game
+ ///
+ ///
private async Task WaitForPlayers()
{
Logger.LogInfo("Starting task to wait for other players.");
- if (MatchmakerAcceptPatches.GClass3163 != null)
+ if (FikaBackendUtils.ScreenController != null)
{
- MatchmakerAcceptPatches.GClass3163.ChangeStatus($"Initializing Coop Game...");
+ FikaBackendUtils.ScreenController.ChangeStatus($"Initializing Coop Game...");
}
int numbersOfPlayersToWaitFor = 0;
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
- while (!Singleton.Instantiated && !Singleton.Instance.ServerReady)
- {
- await Task.Delay(100);
- }
-
FikaServer server = Singleton.Instance;
do
{
- numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (server.NetServer.ConnectedPeersCount + 1);
- if (MatchmakerAcceptPatches.GClass3163 != null)
+ numbersOfPlayersToWaitFor = FikaBackendUtils.HostExpectedNumberOfPlayers - (server.NetServer.ConnectedPeersCount + 1);
+ if (FikaBackendUtils.ScreenController != null)
{
if (numbersOfPlayersToWaitFor > 0)
{
- MatchmakerAcceptPatches.GClass3163.ChangeStatus($"Waiting for {numbersOfPlayersToWaitFor} {(numbersOfPlayersToWaitFor > 1 ? "players" : "player")}");
+ FikaBackendUtils.ScreenController.ChangeStatus($"Waiting for {numbersOfPlayersToWaitFor} {(numbersOfPlayersToWaitFor > 1 ? "players" : "player")}");
}
else
{
- MatchmakerAcceptPatches.GClass3163.ChangeStatus($"All players joined, starting game...");
+ FikaBackendUtils.ScreenController.ChangeStatus($"All players joined, starting game...");
}
}
else
{
Logger.LogError("WaitForPlayers::GClass3163 was null!");
}
- await Task.Delay(1000);
- } while (numbersOfPlayersToWaitFor > 0 && !forceStart);
+ await Task.Delay(100);
+ } while (numbersOfPlayersToWaitFor > 0);
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
- while (!Singleton.Instantiated && !Singleton.Instance.ClientReady)
- {
- await Task.Delay(100);
- }
-
FikaClient client = Singleton.Instance;
while (client.NetClient == null)
@@ -1044,13 +1112,14 @@ private async Task WaitForPlayers()
while (client.ServerConnection == null && connectionAttempts < 5)
{
// Server retries 10 times with a 500ms interval, we give it 5 seconds to try
- MatchmakerAcceptPatches.GClass3163.ChangeStatus("Waiting for client to connect to server... If there is no notification it failed.");
+ FikaBackendUtils.ScreenController.ChangeStatus("Waiting for client to connect to server... If there is no notification it failed.");
connectionAttempts++;
await Task.Delay(1000);
if (client.ServerConnection == null && connectionAttempts == 5)
{
- Singleton.Instance.ShowErrorScreen("Network Error", "Unable to connect to the raid server. Make sure ports are forwarded and/or UPnP is enabled and supported.");
+ Singleton.Instance.ShowErrorScreen("Network Error",
+ "Unable to connect to the raid server. Make sure ports are forwarded and/or UPnP is enabled and supported.");
}
}
@@ -1065,16 +1134,16 @@ private async Task WaitForPlayers()
client.SendData(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
do
{
- numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (client.ConnectedClients + 1);
- if (MatchmakerAcceptPatches.GClass3163 != null)
+ numbersOfPlayersToWaitFor = FikaBackendUtils.HostExpectedNumberOfPlayers - (client.ConnectedClients + 1);
+ if (FikaBackendUtils.ScreenController != null)
{
if (numbersOfPlayersToWaitFor > 0)
{
- MatchmakerAcceptPatches.GClass3163.ChangeStatus($"Waiting for {numbersOfPlayersToWaitFor} {(numbersOfPlayersToWaitFor > 1 ? "players" : "player")}");
+ FikaBackendUtils.ScreenController.ChangeStatus($"Waiting for {numbersOfPlayersToWaitFor} {(numbersOfPlayersToWaitFor > 1 ? "players" : "player")}");
}
else
{
- MatchmakerAcceptPatches.GClass3163.ChangeStatus($"All players joined, starting game...");
+ FikaBackendUtils.ScreenController.ChangeStatus($"All players joined, starting game...");
}
}
else
@@ -1085,10 +1154,16 @@ private async Task WaitForPlayers()
writer.Reset();
client.SendData(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
await Task.Delay(1000);
- } while (numbersOfPlayersToWaitFor > 0 && !forceStart);
+ } while (numbersOfPlayersToWaitFor > 0);
}
}
+ ///
+ /// Sets the status of the game on the backend
+ ///
+ ///
+ ///
+ ///
private async Task SetStatus(LocalPlayer myPlayer, LobbyEntry.ELobbyStatus status)
{
SetStatusModel statusBody = new(myPlayer.ProfileId, status);
@@ -1099,30 +1174,34 @@ private async Task SetStatus(LocalPlayer myPlayer, LobbyEntry.ELobbyStatus statu
///
/// Bot System Starter -> Countdown
///
- ///
///
///
///
///
- public override IEnumerator vmethod_4(float startDelay, BotControllerSettings controllerSettings, ISpawnSystem spawnSystem, Callback runCallback)
+ public override IEnumerator vmethod_4(BotControllerSettings controllerSettings, ISpawnSystem spawnSystem, Callback runCallback)
{
- if (MatchmakerAcceptPatches.IsClient)
+#if DEBUG
+ Logger.LogWarning("vmethod_4");
+#endif
+
+ if (!isServer)
{
controllerSettings.BotAmount = EBotAmount.NoBots;
}
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
- BotsPresets profileCreator = new(BackEndSession, wavesSpawnScenario_0.SpawnWaves, GClass579.BossSpawnWaves, nonWavesSpawnScenario_0.GClass1467_0, false);
+ BotsPresets profileCreator = new(BackEndSession, wavesSpawnScenario_0.SpawnWaves,
+ BossSpawnWaveManagerClass.BossSpawnWaves, nonWavesSpawnScenario_0.GClass1478_0, false);
- GClass813 botCreator = new(this, profileCreator, CreateBot);
+ GClass814 botCreator = new(this, profileCreator, CreateBot);
BotZone[] botZones = LocationScene.GetAllObjects(false).ToArray();
bool enableWaves = controllerSettings.BotAmount == EBotAmount.Horde;
botsController_0.Init(this, botCreator, botZones, spawnSystem, wavesSpawnScenario_0.BotLocationModifier,
controllerSettings.IsEnabled, controllerSettings.IsScavWars, enableWaves, false,
- GClass579.HaveSectants, Singleton.Instance, Location_0.OpenZones);
+ BossSpawnWaveManagerClass.HaveSectants, Singleton.Instance, Location_0.OpenZones);
Logger.LogInfo($"Location: {Location_0.Name}");
@@ -1137,7 +1216,7 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co
_ => 0,
};
- if (MatchmakerAcceptPatches.IsClient)
+ if (!isServer)
{
numberOfBots = 0;
}
@@ -1166,16 +1245,16 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co
if (limits > 0)
{
botsController_0.BotSpawner.SetMaxBots(limits);
- }
+ }
}
DynamicAI = gameObject.AddComponent();
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
BotsPresets profileCreator = new(BackEndSession, [], [], [], false);
- GClass813 botCreator = new(this, profileCreator, CreateBot);
+ GClass814 botCreator = new(this, profileCreator, CreateBot);
BotZone[] botZones = LocationScene.GetAllObjects(false).ToArray();
// Setting this to an empty array stops the client from downloading bots
@@ -1191,37 +1270,34 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co
BackendConfigSettingsClass instance = Singleton.Instance;
- bool isWinter = BackEndSession.IsWinter;
- Class420 winterEventController = new();
- Singleton.Instance.Class420_0 = winterEventController;
- winterEventController.Run(isWinter).HandleExceptions();
-
- if (startDelay < 5)
- {
- startDelay = 5;
- NotificationManagerClass.DisplayWarningNotification("You have set the deploy timer too low, resetting to 5!");
- }
+ LocalGame.Class1391 seasonTaskHandler = new();
+ ESeason season = BackEndSession.Season;
+ Class394 seasonHandler = new();
+ Singleton.Instance.GInterface26_0 = seasonHandler;
+ seasonTaskHandler.task = seasonHandler.Run(season);
+ yield return new WaitUntil(new Func(seasonTaskHandler.method_0));
- DeployScreen(startDelay);
+ yield return WaitForOtherPlayers();
- if (MatchmakerAcceptPatches.IsServer)
+ int expectedPlayers = FikaBackendUtils.HostExpectedNumberOfPlayers;
+ if (isServer)
{
- while (Singleton.Instance.ReadyClients < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart)
+ FikaServer server = Singleton.Instance;
+ while (server.ReadyClients < expectedPlayers)
{
yield return new WaitForEndOfFrame();
}
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
- while (Singleton.Instance.ReadyClients < MatchmakerAcceptPatches.HostExpectedNumberOfPlayers && !forceStart)
+ FikaClient client = Singleton.Instance;
+ while (client.ReadyClients < expectedPlayers)
{
yield return new WaitForEndOfFrame();
}
}
- yield return new WaitForSeconds(startDelay);
-
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
if (Location_0.OldSpawn && wavesSpawnScenario_0.SpawnWaves != null && wavesSpawnScenario_0.SpawnWaves.Length != 0)
{
@@ -1241,7 +1317,7 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co
}
}
- GClass579.Run(EBotsSpawnMode.Anyway);
+ BossSpawnWaveManagerClass.Run(EBotsSpawnMode.Anyway);
FikaPlugin.DynamicAI.SettingChanged += DynamicAI_SettingChanged;
FikaPlugin.DynamicAIRate.SettingChanged += DynamicAIRate_SettingChanged;
@@ -1256,33 +1332,51 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co
{
nonWavesSpawnScenario_0.Stop();
}
- if (GClass579 != null)
+ if (BossSpawnWaveManagerClass != null)
{
- GClass579.Stop();
+ BossSpawnWaveManagerClass.Stop();
}
}
- yield return new WaitForEndOfFrame();
-
- CreateExfiltrationPointAndInitDeathHandler();
-
// Add FreeCamController to GameWorld GameObject
Singleton.Instance.gameObject.GetOrAddComponent();
Singleton.Instance.gameObject.GetOrAddComponent();
FikaAirdropsManager.ContainerCount = 0;
SetupBorderzones();
+ SetupRaidCode();
if (Singleton.Instance.MineManager != null)
{
Singleton.Instance.MineManager.OnExplosion += OnMineExplode;
}
- runCallback.Succeed();
+ Singleton.Instance.TimeBeforeDeployLocal = Math.Max(Singleton.Instance.TimeBeforeDeployLocal, 5);
+ yield return base.vmethod_4(controllerSettings, spawnSystem, runCallback);
yield break;
}
+ private void SetupRaidCode()
+ {
+ string raidCode = FikaBackendUtils.GetRaidCode();
+ if (!string.IsNullOrEmpty(raidCode))
+ {
+ Traverse preloaderUiTraverse = Traverse.Create(MonoBehaviourSingleton.Instance);
+ // Raid code
+ preloaderUiTraverse.Field("string_3").SetValue($"{raidCode}");
+ // Update version label
+ preloaderUiTraverse.Method("method_6").GetValue();
+
+ Logger.LogInfo($"MatchingType: {FikaBackendUtils.MatchingType}, Raid Code: {raidCode}");
+ }
+ }
+
+ ///
+ /// Triggers when the setting is changed
+ ///
+ ///
+ ///
private void DynamicAIRate_SettingChanged(object sender, EventArgs e)
{
if (DynamicAI != null)
@@ -1291,6 +1385,11 @@ private void DynamicAIRate_SettingChanged(object sender, EventArgs e)
}
}
+ ///
+ /// Triggers when the setting is changed
+ ///
+ ///
+ ///
private void DynamicAI_SettingChanged(object sender, EventArgs e)
{
if (DynamicAI != null)
@@ -1299,6 +1398,9 @@ private void DynamicAI_SettingChanged(object sender, EventArgs e)
}
}
+ ///
+ /// Sets up all the s on the map
+ ///
private void SetupBorderzones()
{
GameWorld gameWorld = Singleton.Instance;
@@ -1308,14 +1410,14 @@ private void SetupBorderzones()
gameWorld.BorderZones[i].Id = i;
}
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
foreach (BorderZone borderZone in gameWorld.BorderZones)
{
borderZone.PlayerShotEvent += OnBorderZoneShot;
}
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
foreach (BorderZone borderZone in gameWorld.BorderZones)
{
@@ -1324,7 +1426,14 @@ private void SetupBorderzones()
}
}
- private void OnBorderZoneShot(GInterface94 player, BorderZone zone, float arg3, bool arg4)
+ ///
+ /// Triggered when a triggers (only runs on host)
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void OnBorderZoneShot(IPlayerOwner player, BorderZone zone, float arg3, bool arg4)
{
BorderZonePacket packet = new()
{
@@ -1334,6 +1443,10 @@ private void OnBorderZoneShot(GInterface94 player, BorderZone zone, float arg3,
Singleton.Instance.SendDataToAll(new NetDataWriter(), ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
}
+ ///
+ /// Triggers when a explodes
+ ///
+ ///
private void OnMineExplode(MineDirectional directional)
{
if (!directional.gameObject.active)
@@ -1345,29 +1458,36 @@ private void OnMineExplode(MineDirectional directional)
{
MinePositon = directional.transform.position
};
- if (MatchmakerAcceptPatches.IsClient)
+ if (!isServer)
{
Singleton.Instance.SendData(new NetDataWriter(), ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
}
- else if (MatchmakerAcceptPatches.IsServer)
+ else
{
Singleton.Instance.SendDataToAll(new NetDataWriter(), ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered);
}
}
- public void CreateExfiltrationPointAndInitDeathHandler()
+ ///
+ /// Sets up events and all s
+ ///
+ public override void vmethod_5()
{
- Logger.LogInfo("CreateExfiltrationPointAndInitDeathHandler");
-
- GameTimer.Start();
- gparam_0.vmethod_0();
+ GameTimer.Start(null, null);
gparam_0.Player.HealthController.DiedEvent += HealthController_DiedEvent;
+ gparam_0.vmethod_0();
+
+ SkillClass[] skills = Profile_0.Skills.Skills;
+ for (int i = 0; i < skills.Length; i++)
+ {
+ skills[i].SetPointsEarnedInSession(0f, false);
+ }
InfiltrationPoint = spawnPoint.Infiltration;
Profile_0.Info.EntryPoint = InfiltrationPoint;
- Logger.LogDebug("SpawnPoint: " + spawnPoint.Id + ", InfiltrationPoint: " + InfiltrationPoint);
+ Logger.LogInfo("SpawnPoint: " + spawnPoint.Id + ", InfiltrationPoint: " + InfiltrationPoint);
- if (MatchmakerAcceptPatches.IsClient)
+ if (!isServer)
{
CarExtraction carExtraction = FindObjectOfType();
if (carExtraction != null)
@@ -1376,10 +1496,10 @@ public void CreateExfiltrationPointAndInitDeathHandler()
}
}
- ExfiltrationControllerClass.Instance.InitAllExfiltrationPoints(Location_0.exits, MatchmakerAcceptPatches.IsClient, "");
+ ExfiltrationControllerClass.Instance.InitAllExfiltrationPoints(Location_0.exits, !isServer, "");
ExfiltrationPoint[] exfilPoints = ExfiltrationControllerClass.Instance.EligiblePoints(Profile_0);
- GameUi.TimerPanel.SetTime(GClass1296.UtcNow, Profile_0.Info.Side, GameTimer.SessionSeconds(), exfilPoints);
+ GameUi.TimerPanel.SetTime(EFTDateTimeClass.UtcNow, Profile_0.Info.Side, GameTimer.SessionSeconds(), exfilPoints);
exfilManager = gameObject.AddComponent();
exfilManager.Run(exfilPoints);
@@ -1397,11 +1517,11 @@ public void CreateExfiltrationPointAndInitDeathHandler()
{
if (CoopHandler.TryGetCoopHandler(out CoopHandler coopHandler))
{
- if (MatchmakerAcceptPatches.IsServer)
+ if (isServer)
{
coopHandler.serverBTR = gameWorld.gameObject.AddComponent();
}
- else if (MatchmakerAcceptPatches.IsClient)
+ else
{
coopHandler.clientBTR = gameWorld.gameObject.AddComponent();
}
@@ -1410,34 +1530,41 @@ public void CreateExfiltrationPointAndInitDeathHandler()
}
catch (Exception)
{
- Logger.LogError("CreateExfiltrationPointAndInitDeathHandler: Exception thrown during BTR init, check logs.");
+ Logger.LogError("vmethod_5: Exception thrown during BTR init, check logs.");
}
}
- dateTime_0 = GClass1296.Now;
+ dateTime_0 = EFTDateTimeClass.Now;
Status = GameStatus.Started;
ConsoleScreen.ApplyStartCommands();
}
+ ///
+ /// Updates a from the server
+ ///
+ ///
+ ///
public void UpdateExfilPointFromServer(ExfiltrationPoint point, bool enable)
{
exfilManager.UpdateExfilPointFromServer(point, enable);
}
+ ///
+ /// Resets all s from the server
+ ///
+ ///
public void ResetExfilPointsFromServer(ExfiltrationPoint[] points)
{
- Dictionary currentExfils = Traverse.Create(GameUi.TimerPanel).Field("dictionary_0").GetValue>();
+ Dictionary currentExfils = Traverse.Create(GameUi.TimerPanel).Field>("dictionary_0").Value;
foreach (ExitTimerPanel exitTimerPanel in currentExfils.Values)
{
exitTimerPanel.Close();
}
currentExfils.Clear();
- GameUi.TimerPanel.SetTime(GClass1296.UtcNow, Profile_0.Info.Side, GameTimer.SessionSeconds(), points);
+ GameUi.TimerPanel.SetTime(EFTDateTimeClass.UtcNow, Profile_0.Info.Side, GameTimer.SessionSeconds(), points);
}
- public List