mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-12 22:50:44 -05:00
24605 (!14)
Co-authored-by: Dev <dev@noreply.dev.sp-tarkov.com> Reviewed-on: SPT-AKI/Modules#14
This commit is contained in:
parent
a62df7c9be
commit
b3ba581b59
@ -23,7 +23,7 @@ git config --local user.email "USERNAME@SOMETHING.com"
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Escape From Tarkov 23043
|
- Escape From Tarkov 24605
|
||||||
- BepInEx 5.4.19
|
- BepInEx 5.4.19
|
||||||
- Visual Studio Code
|
- Visual Studio Code
|
||||||
- .NET 6 SDK
|
- .NET 6 SDK
|
||||||
|
@ -15,7 +15,7 @@ namespace Aki.Core.Patches
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var type = PatchConstants.EftTypes.Single(t => t.Name == "Class229");
|
var type = PatchConstants.EftTypes.Single(t => t.Name == "Class226");
|
||||||
var value = Traverse.Create(type).Field("TransportPrefixes").GetValue<Dictionary<ETransportProtocolType, string>>();
|
var value = Traverse.Create(type).Field("TransportPrefixes").GetValue<Dictionary<ETransportProtocolType, string>>();
|
||||||
value[ETransportProtocolType.HTTPS] = "http://";
|
value[ETransportProtocolType.HTTPS] = "http://";
|
||||||
value[ETransportProtocolType.WSS] = "ws://";
|
value[ETransportProtocolType.WSS] = "ws://";
|
||||||
@ -34,7 +34,7 @@ namespace Aki.Core.Patches
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
private static bool PatchPrefix(ref GStruct22 legacyParams)
|
private static bool PatchPrefix(ref GStruct21 legacyParams)
|
||||||
{
|
{
|
||||||
//Console.WriteLine($"Original url {legacyParams.Url}");
|
//Console.WriteLine($"Original url {legacyParams.Url}");
|
||||||
legacyParams.Url = legacyParams.Url
|
legacyParams.Url = legacyParams.Url
|
||||||
|
@ -27,52 +27,57 @@ namespace Aki.Custom.Airdrops.Utils
|
|||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
string location = gameWorld.RegisteredPlayers[0].Location;
|
// Get players current location
|
||||||
|
string playerLocation = gameWorld.MainPlayer.Location;
|
||||||
|
|
||||||
int result = 25;
|
int result = 0;
|
||||||
switch (location.ToLower())
|
switch (playerLocation.ToLower())
|
||||||
{
|
{
|
||||||
case "bigmap":
|
case "bigmap":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Bigmap;
|
result = config.AirdropChancePercent.Bigmap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "interchange":
|
case "interchange":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Interchange;
|
result = config.AirdropChancePercent.Interchange;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "rezervbase":
|
case "rezervbase":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Reserve;
|
result = config.AirdropChancePercent.Reserve;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "shoreline":
|
case "shoreline":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Shoreline;
|
result = config.AirdropChancePercent.Shoreline;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "woods":
|
case "woods":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Woods;
|
result = config.AirdropChancePercent.Woods;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "lighthouse":
|
case "lighthouse":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.Lighthouse;
|
result = config.AirdropChancePercent.Lighthouse;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "tarkovstreets":
|
case "tarkovstreets":
|
||||||
{
|
{
|
||||||
result = config.AirdropChancePercent.TarkovStreets;
|
result = config.AirdropChancePercent.TarkovStreets;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Debug.LogError($"[AKI-AIRDROPS]: Map with name {playerLocation} not handled, defaulting spawn chance to 25%");
|
||||||
|
result = 25;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ShouldAirdropOccur(int dropChance, List<AirdropPoint> airdropPoints)
|
private static bool ShouldAirdropOccur(int dropChance, List<AirdropPoint> airdropPoints)
|
||||||
{
|
{
|
||||||
return airdropPoints.Count > 0 && Random.Range(0, 100) <= dropChance;
|
return airdropPoints.Count > 0 && Random.Range(0, 100) <= dropChance;
|
||||||
}
|
}
|
||||||
@ -81,15 +86,16 @@ namespace Aki.Custom.Airdrops.Utils
|
|||||||
{
|
{
|
||||||
var serverConfig = GetConfigFromServer();
|
var serverConfig = GetConfigFromServer();
|
||||||
var allAirdropPoints = LocationScene.GetAll<AirdropPoint>().ToList();
|
var allAirdropPoints = LocationScene.GetAll<AirdropPoint>().ToList();
|
||||||
var playerPosition = gameWorld.RegisteredPlayers[0].Position;
|
var playerPosition = gameWorld.MainPlayer.Position;
|
||||||
var flareAirdropPoints = new List<AirdropPoint>();
|
var flareAirdropPoints = new List<AirdropPoint>();
|
||||||
var dropChance = ChanceToSpawn(gameWorld, serverConfig, isFlare);
|
var dropChance = ChanceToSpawn(gameWorld, serverConfig, isFlare);
|
||||||
|
var flareSpawnRadiusDistance = 100f;
|
||||||
|
|
||||||
if (isFlare && allAirdropPoints.Count > 0)
|
if (isFlare && allAirdropPoints.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (AirdropPoint point in allAirdropPoints)
|
foreach (AirdropPoint point in allAirdropPoints)
|
||||||
{
|
{
|
||||||
if (Vector3.Distance(playerPosition, point.transform.position) <= 100f)
|
if (Vector3.Distance(playerPosition, point.transform.position) <= flareSpawnRadiusDistance)
|
||||||
{
|
{
|
||||||
flareAirdropPoints.Add(point);
|
flareAirdropPoints.Add(point);
|
||||||
}
|
}
|
||||||
@ -98,7 +104,7 @@ namespace Aki.Custom.Airdrops.Utils
|
|||||||
|
|
||||||
if (flareAirdropPoints.Count == 0 && isFlare)
|
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($"[AKI-AIRDROPS]: Airdrop called in by flare, Unable to find an airdropPoint within {flareSpawnRadiusDistance}m, defaulting to normal drop");
|
||||||
flareAirdropPoints.Add(allAirdropPoints.OrderBy(_ => Guid.NewGuid()).FirstOrDefault());
|
flareAirdropPoints.Add(allAirdropPoints.OrderBy(_ => Guid.NewGuid()).FirstOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ namespace Aki.Custom
|
|||||||
new BotDifficultyPatch().Enable();
|
new BotDifficultyPatch().Enable();
|
||||||
new CoreDifficultyPatch().Enable();
|
new CoreDifficultyPatch().Enable();
|
||||||
new OfflineRaidMenuPatch().Enable();
|
new OfflineRaidMenuPatch().Enable();
|
||||||
new RaidSettingsWindowPatch().Enable();
|
// Fixed in live, no need for patch
|
||||||
|
//new RaidSettingsWindowPatch().Enable();
|
||||||
new OfflineRaidSettingsMenuPatch().Enable();
|
new OfflineRaidSettingsMenuPatch().Enable();
|
||||||
new SessionIdPatch().Enable();
|
new SessionIdPatch().Enable();
|
||||||
new VersionLabelPatch().Enable();
|
new VersionLabelPatch().Enable();
|
||||||
|
@ -98,7 +98,7 @@ namespace Aki.Custom.Patches
|
|||||||
{
|
{
|
||||||
var gameWorld = Singleton<GameWorld>.Instance;
|
var gameWorld = Singleton<GameWorld>.Instance;
|
||||||
|
|
||||||
return gameWorld.RegisteredPlayers[0].Location;
|
return gameWorld.MainPlayer.Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CacheIsStale()
|
private static bool CacheIsStale()
|
||||||
|
@ -49,9 +49,9 @@ namespace Aki.Custom.Patches
|
|||||||
private static bool IsTargetMethod(MethodInfo mi)
|
private static bool IsTargetMethod(MethodInfo mi)
|
||||||
{
|
{
|
||||||
var parameters = mi.GetParameters();
|
var parameters = mi.GetParameters();
|
||||||
return (parameters.Length == 6
|
return (parameters.Length == 6
|
||||||
&& parameters[0].Name == "bundleLock"
|
&& parameters[0].Name == "bundleLock"
|
||||||
&& parameters[1].Name == "defaultKey"
|
&& parameters[1].Name == "defaultKey"
|
||||||
&& parameters[4].Name == "shouldExclude");
|
&& parameters[4].Name == "shouldExclude");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace Aki.Custom.Patches
|
|||||||
var player = Singleton<GameWorld>.Instance.MainPlayer;
|
var player = Singleton<GameWorld>.Instance.MainPlayer;
|
||||||
if (profileId == player?.Profile.Id)
|
if (profileId == player?.Profile.Id)
|
||||||
{
|
{
|
||||||
GClass2731.Instance.CloseAllScreensForced();
|
GClass2974.Instance.CloseAllScreensForced();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,7 +29,6 @@ namespace Aki.Custom.Patches
|
|||||||
var raidSettings = Traverse.Create(controller).Field<RaidSettings>("RaidSettings").Value;
|
var raidSettings = Traverse.Create(controller).Field<RaidSettings>("RaidSettings").Value;
|
||||||
|
|
||||||
raidSettings.RaidMode = ERaidMode.Local;
|
raidSettings.RaidMode = ERaidMode.Local;
|
||||||
raidSettings.BotSettings.IsEnabled = true;
|
|
||||||
|
|
||||||
// Default checkbox to be ticked
|
// Default checkbox to be ticked
|
||||||
____offlineModeToggle.isOn = true;
|
____offlineModeToggle.isOn = true;
|
||||||
|
@ -17,7 +17,7 @@ namespace Aki.Custom.Patches
|
|||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
var desiredType = typeof(RaidSettingsWindow);
|
var desiredType = typeof(RaidSettingsWindow);
|
||||||
var desiredMethod = desiredType.GetMethod("method_9", BindingFlags.NonPublic | BindingFlags.Instance);
|
var desiredMethod = desiredType.GetMethod("method_8", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
|
||||||
Logger.LogDebug($"{this.GetType().Name} Type: {desiredType?.Name}");
|
Logger.LogDebug($"{this.GetType().Name} Type: {desiredType?.Name}");
|
||||||
Logger.LogDebug($"{this.GetType().Name} Method: {desiredMethod?.Name}");
|
Logger.LogDebug($"{this.GetType().Name} Method: {desiredMethod?.Name}");
|
||||||
|
@ -7,8 +7,8 @@ namespace Aki.PrePatch
|
|||||||
{
|
{
|
||||||
public static IEnumerable<string> TargetDLLs { get; } = new[] { "Assembly-CSharp.dll" };
|
public static IEnumerable<string> TargetDLLs { get; } = new[] { "Assembly-CSharp.dll" };
|
||||||
|
|
||||||
public static int sptUsecValue = 32;
|
public static int sptUsecValue = 33;
|
||||||
public static int sptBearValue = 33;
|
public static int sptBearValue = 34;
|
||||||
|
|
||||||
public static void Patch(ref AssemblyDefinition assembly)
|
public static void Patch(ref AssemblyDefinition assembly)
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ namespace Aki.SinglePlayer.Models.Progression
|
|||||||
private bool _addedToEnemy;
|
private bool _addedToEnemy;
|
||||||
private List<MineDirectionalColliders> _mines;
|
private List<MineDirectionalColliders> _mines;
|
||||||
private RecodableItemClass _transmitter;
|
private RecodableItemClass _transmitter;
|
||||||
private List<Player> _bosses;
|
private List<IAIDetails> _bosses;
|
||||||
private bool _aggressor;
|
private bool _aggressor;
|
||||||
private bool _disabledDoor;
|
private bool _disabledDoor;
|
||||||
private readonly string _transmitterId = "62e910aaf957f2915e0a5e36";
|
private readonly string _transmitterId = "62e910aaf957f2915e0a5e36";
|
||||||
@ -22,10 +22,13 @@ namespace Aki.SinglePlayer.Models.Progression
|
|||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
_gameWorld = Singleton<GameWorld>.Instance;
|
_gameWorld = Singleton<GameWorld>.Instance;
|
||||||
_bosses = new List<Player>();
|
_bosses = new List<IAIDetails>();
|
||||||
_mines = GameObject.FindObjectsOfType<MineDirectionalColliders>().ToList();
|
_mines = GameObject.FindObjectsOfType<MineDirectionalColliders>().ToList();
|
||||||
|
|
||||||
if (_gameWorld == null || _gameWorld.MainPlayer.Location.ToLower() != "lighthouse") return;
|
if (_gameWorld == null || !string.Equals(_gameWorld.MainPlayer.Location, "lighthouse", System.StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if player is a scav, there is no need to continue this method.
|
// if player is a scav, there is no need to continue this method.
|
||||||
if (_gameWorld.MainPlayer.Side == EPlayerSide.Savage)
|
if (_gameWorld.MainPlayer.Side == EPlayerSide.Savage)
|
||||||
@ -55,7 +58,10 @@ namespace Aki.SinglePlayer.Models.Progression
|
|||||||
|
|
||||||
_timer += Time.deltaTime;
|
_timer += Time.deltaTime;
|
||||||
|
|
||||||
if (_timer < 10f) return;
|
if (_timer < 10f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_bosses.Count == 0)
|
if (_bosses.Count == 0)
|
||||||
{
|
{
|
||||||
@ -100,22 +106,23 @@ namespace Aki.SinglePlayer.Models.Progression
|
|||||||
|
|
||||||
private void SetupBosses()
|
private void SetupBosses()
|
||||||
{
|
{
|
||||||
foreach (var player in _gameWorld.AllPlayers)
|
foreach (var aiBot in _gameWorld.AllAlivePlayersList)
|
||||||
{
|
{
|
||||||
if (!player.IsYourPlayer)
|
if (!aiBot.IsYourPlayer)
|
||||||
{
|
{
|
||||||
if (player.AIData.BotOwner.IsRole(WildSpawnType.bossZryachiy) || player.AIData.BotOwner.IsRole(WildSpawnType.followerZryachiy))
|
// Edge case of bossZryachiy not being hostile to player
|
||||||
|
if (aiBot.AIData.BotOwner.IsRole(WildSpawnType.bossZryachiy) || aiBot.AIData.BotOwner.IsRole(WildSpawnType.followerZryachiy))
|
||||||
{
|
{
|
||||||
// Sub to Bosses OnDeath event, Set mainplayer to aggressor on this script
|
// Subscribe to Bosses OnDeath event
|
||||||
player.OnPlayerDeadOrUnspawn += player1 =>
|
aiBot.OnPlayerDeadOrUnspawn += player1 =>
|
||||||
{
|
{
|
||||||
if (player1.KillerId != null && player1.KillerId == _gameWorld.MainPlayer.ProfileId)
|
if (player1?.KillerId == _gameWorld.MainPlayer.ProfileId)
|
||||||
{
|
{
|
||||||
_aggressor = true;
|
_aggressor = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_bosses.Add(player);
|
_bosses.Add(aiBot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,12 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
|
|
||||||
public GetNewBotTemplatesPatch()
|
public GetNewBotTemplatesPatch()
|
||||||
{
|
{
|
||||||
_getNewProfileMethod = typeof(BotsPresets)
|
var desiredType = typeof(BotsPresets);
|
||||||
.GetMethod(nameof(BotsPresets.GetNewProfile), PatchConstants.PrivateFlags);
|
_getNewProfileMethod = desiredType
|
||||||
|
.GetMethod(nameof(BotsPresets.GetNewProfile), BindingFlags.Instance | BindingFlags.NonPublic); // want the func with 2 params (protected)
|
||||||
|
|
||||||
|
Logger.LogDebug($"{this.GetType().Name} Type: {desiredType?.Name}");
|
||||||
|
Logger.LogDebug($"{this.GetType().Name} Method: {_getNewProfileMethod?.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
@ -36,13 +40,14 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
private bool IsTargetMethod(MethodInfo mi)
|
private bool IsTargetMethod(MethodInfo mi)
|
||||||
{
|
{
|
||||||
var parameters = mi.GetParameters();
|
var parameters = mi.GetParameters();
|
||||||
return (parameters.Length == 2
|
return (parameters.Length == 3
|
||||||
&& parameters[0].Name == "data"
|
&& parameters[0].Name == "data"
|
||||||
&& parameters[1].Name == "cancellationToken");
|
&& parameters[1].Name == "cancellationToken"
|
||||||
|
&& parameters[2].Name == "withDelete");
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
private static bool PatchPrefix(ref Task<Profile> __result, BotsPresets __instance, IBotData data)
|
private static bool PatchPrefix(ref Task<Profile> __result, BotsPresets __instance, GClass626 data, bool withDelete)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
in short when client wants new bot and GetNewProfile() return null (if not more available templates or they don't satisfy by Role and Difficulty condition)
|
in short when client wants new bot and GetNewProfile() return null (if not more available templates or they don't satisfy by Role and Difficulty condition)
|
||||||
@ -57,7 +62,17 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
|
|
||||||
var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||||
var taskAwaiter = (Task<Profile>)null;
|
var taskAwaiter = (Task<Profile>)null;
|
||||||
var profile = (Profile)_getNewProfileMethod.Invoke(__instance, new object[] { data });
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_getNewProfileMethod.Invoke(__instance, new object[] { data, true });
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.LogDebug($"getnewbot failed: {e.Message} {e.InnerException}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// load from server
|
// load from server
|
||||||
var source = data.PrepareToLoadBackend(1).ToList();
|
var source = data.PrepareToLoadBackend(1).ToList();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using TraderInfo = EFT.Profile.GClass1666;
|
using TraderInfo = EFT.Profile.GClass1726;
|
||||||
|
|
||||||
namespace Aki.SinglePlayer.Patches.RaidFix
|
namespace Aki.SinglePlayer.Patches.RaidFix
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@ using Aki.Reflection.Patching;
|
|||||||
using Aki.Reflection.Utils;
|
using Aki.Reflection.Utils;
|
||||||
using EFT;
|
using EFT;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -10,10 +9,10 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
{
|
{
|
||||||
public class RemoveUsedBotProfilePatch : ModulePatch
|
public class RemoveUsedBotProfilePatch : ModulePatch
|
||||||
{
|
{
|
||||||
private static BindingFlags _flags;
|
private static readonly BindingFlags _flags;
|
||||||
private static Type _targetInterface;
|
private static readonly Type _targetInterface;
|
||||||
private static Type _targetType;
|
private static readonly Type _targetType;
|
||||||
private static FieldInfo _profilesField;
|
private static readonly FieldInfo _profilesField;
|
||||||
|
|
||||||
static RemoveUsedBotProfilePatch()
|
static RemoveUsedBotProfilePatch()
|
||||||
{
|
{
|
||||||
@ -21,7 +20,7 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
|
|
||||||
_flags = BindingFlags.Instance | BindingFlags.NonPublic;
|
_flags = BindingFlags.Instance | BindingFlags.NonPublic;
|
||||||
_targetInterface = PatchConstants.EftTypes.Single(IsTargetInterface);
|
_targetInterface = PatchConstants.EftTypes.Single(IsTargetInterface);
|
||||||
_targetType = PatchConstants.EftTypes.Single(IsTargetType);
|
_targetType = typeof(BotsPresets);
|
||||||
_profilesField = _targetType.GetField("list_0", _flags);
|
_profilesField = _targetType.GetField("list_0", _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,21 +40,11 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
private static bool PatchPrefix(ref Profile __result, object __instance, IBotData data)
|
private static bool PatchPrefix(ref Profile __result, object __instance, GClass626 data, ref bool withDelete)
|
||||||
{
|
{
|
||||||
var profiles = (List<Profile>)_profilesField.GetValue(__instance);
|
withDelete = true;
|
||||||
|
|
||||||
if (profiles.Count > 0)
|
return true; // Do original method
|
||||||
{
|
|
||||||
// second parameter makes client remove used profiles
|
|
||||||
__result = data.ChooseProfile(profiles, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
__result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace Aki.SinglePlayer.Patches.RaidFix
|
|||||||
.GetMethod("FindActiveEffect", BindingFlags.Instance | BindingFlags.Public)
|
.GetMethod("FindActiveEffect", BindingFlags.Instance | BindingFlags.Public)
|
||||||
.MakeGenericMethod(typeof(ActiveHealthControllerClass)
|
.MakeGenericMethod(typeof(ActiveHealthControllerClass)
|
||||||
.GetNestedType("Stun", BindingFlags.Instance | BindingFlags.NonPublic))
|
.GetNestedType("Stun", BindingFlags.Instance | BindingFlags.NonPublic))
|
||||||
.Invoke(Singleton<GameWorld>.Instance.AllPlayers[0].ActiveHealthController, new object[] { EBodyPart.Common }) != null;
|
.Invoke(Singleton<GameWorld>.Instance.MainPlayer.ActiveHealthController, new object[] { EBodyPart.Common }) != null;
|
||||||
|
|
||||||
return shouldInvoke;
|
return shouldInvoke;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,7 @@ namespace Aki.SinglePlayer.Patches.ScavMode
|
|||||||
Logger.LogError("Unable to Find Gameworld or RegisterPlayers... Unable to Disable Extracts for Scav raid");
|
Logger.LogError("Unable to Find Gameworld or RegisterPlayers... Unable to Disable Extracts for Scav raid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// One of the RegisteredPlayers will have the IsYourPlayer flag set, which will be our own Player instance.
|
Player player = gameWorld.MainPlayer;
|
||||||
Player player = gameWorld.RegisteredPlayers.Find(p => p.IsYourPlayer);
|
|
||||||
|
|
||||||
var exfilController = gameWorld.ExfiltrationController;
|
var exfilController = gameWorld.ExfiltrationController;
|
||||||
|
|
||||||
|
@ -111,13 +111,16 @@ namespace Aki.SinglePlayer.Patches.ScavMode
|
|||||||
{
|
{
|
||||||
var profile = PatchConstants.BackEndSession.Profile;
|
var profile = PatchConstants.BackEndSession.Profile;
|
||||||
var menuController = (object)GetMenuController();
|
var menuController = (object)GetMenuController();
|
||||||
|
|
||||||
|
// Get fields from MainMenuController.cs
|
||||||
var raidSettings = Traverse.Create(menuController).Field("raidSettings_0").GetValue<RaidSettings>();
|
var raidSettings = Traverse.Create(menuController).Field("raidSettings_0").GetValue<RaidSettings>();
|
||||||
var matchmakerPlayersController = Traverse.Create(menuController).Field("gclass2784_0").GetValue<GClass2784>();
|
var matchmakerPlayersController = Traverse.Create(menuController).Field("gclass3027_0").GetValue<GClass3027>();
|
||||||
var gclass = new MatchmakerOfflineRaidScreen.GClass2773(profile?.Info, ref raidSettings, matchmakerPlayersController);
|
|
||||||
|
var gclass = new MatchmakerOfflineRaidScreen.GClass3016(profile?.Info, ref raidSettings, matchmakerPlayersController);
|
||||||
|
|
||||||
gclass.OnShowNextScreen += LoadOfflineRaidNextScreen;
|
gclass.OnShowNextScreen += LoadOfflineRaidNextScreen;
|
||||||
|
|
||||||
// ready method
|
// Ready method
|
||||||
gclass.OnShowReadyScreen += (OfflineRaidAction)Delegate.CreateDelegate(typeof(OfflineRaidAction), menuController, "method_67");
|
gclass.OnShowReadyScreen += (OfflineRaidAction)Delegate.CreateDelegate(typeof(OfflineRaidAction), menuController, "method_67");
|
||||||
gclass.ShowScreen(EScreenState.Queued);
|
gclass.ShowScreen(EScreenState.Queued);
|
||||||
}
|
}
|
||||||
@ -132,10 +135,10 @@ namespace Aki.SinglePlayer.Patches.ScavMode
|
|||||||
raidSettings.WavesSettings.IsBosses = true;
|
raidSettings.WavesSettings.IsBosses = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set offline raid values
|
// Set offline raid values
|
||||||
_isLocalField.SetValue(menuController, raidSettings.Local);
|
_isLocalField.SetValue(menuController, raidSettings.Local);
|
||||||
|
|
||||||
// load ready screen method
|
// Load ready screen method
|
||||||
_onReadyScreenMethod.Invoke(menuController, null);
|
_onReadyScreenMethod.Invoke(menuController, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user