Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[WIP] Support for EFT 0.16.0.34568 and SPT-AKI 4.0.0 #640

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions BepInExPlugin/AkiEftTrainerPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using BepInEx;
using System;
using System.Collections.Generic;
using System.Reflection;
using BepInEx;
using EFT.Trainer;
using JetBrains.Annotations;

[BepInPlugin("com.spt-aki.efttrainer", "AKI.EftTrainer", "1.0.0")]
[BepInPlugin(PluginId, "AKI.EftTrainer", "1.0.0")]
[UsedImplicitly]
public class AkiDebuggingPlugin : BaseUnityPlugin
{
private const string PluginId = "com.spt-aki.efttrainer";
public static bool Loaded = false;

[UsedImplicitly]
Expand All @@ -16,6 +20,22 @@ public void Awake()

Loader.Load();
Loaded = true;

WhitelistThisPlugin();
}

private static void WhitelistThisPlugin()
{
// Whitelist this plugin for spt-aki beta releases
var type = Type.GetType("SPT.Custom.Utils.MenuNotificationManager, spt-custom", throwOnError: false);
if (type == null)
return;

var field = type.GetField("whitelistedPlugins", BindingFlags.NonPublic | BindingFlags.Static);
if (field == null)
return;

var hashset = field.GetValue(null) as HashSet<string>;
hashset?.Add(PluginId);
}
}
7 changes: 5 additions & 2 deletions BepInExPlugin/BepInExPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- Framework -->
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Core" />
<Reference Include="netstandard">
<HintPath>$(EFTManagedPath)\netstandard.dll</HintPath>
</Reference>
<!-- Unity -->
<Reference Include="UnityEngine">
<HintPath>$(EFTManagedPath)\UnityEngine.dll</HintPath>
Expand Down
4 changes: 2 additions & 2 deletions ConsoleCommands/Spawn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ internal static void SpawnTemplate(string template, Player player, ConsoleComman

private static void SpawnTemplate(ItemTemplate template, Player player, ConsoleCommand command)
{
var poolManager = Singleton<PoolManager>.Instance;
var poolManager = Singleton<PoolManagerClass>.Instance;

poolManager
.LoadBundlesAndCreatePools(PoolManager.PoolsCategory.Raid, PoolManager.AssemblyType.Online, [.. template.AllResources], JobPriority.Immediate)
.LoadBundlesAndCreatePools(PoolManagerClass.PoolsCategory.Raid, PoolManagerClass.AssemblyType.Online, [.. template.AllResources], JobPriorityClass.Immediate)
.ContinueWith(task =>
{
AsyncWorker.RunInMainTread(delegate
Expand Down
131 changes: 129 additions & 2 deletions ConsoleCommands/SpawnBot.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Comfort.Common;
using EFT.Trainer.Extensions;
using EFT.Trainer.Properties;
using HarmonyLib;
using JetBrains.Annotations;
using Random = UnityEngine.Random;

#nullable enable

Expand Down Expand Up @@ -44,7 +48,7 @@ public override void Execute(Match match)
SpawnBots(bots);
}

private static void SpawnBots(string[] bots)
private void SpawnBots(string[] bots)
{
var instance = Singleton<IBotGame>.Instance;
if (instance == null)
Expand All @@ -53,7 +57,130 @@ private static void SpawnBots(string[] bots)
var controller = instance.BotsController;

foreach (var bot in bots)
controller.SpawnBotDebugServer(EPlayerSide.Savage, false, (WildSpawnType)Enum.Parse(typeof(WildSpawnType), bot), BotDifficulty.normal, true);
SpawnBotDebugServer(controller, EPlayerSide.Savage, false, (WildSpawnType)Enum.Parse(typeof(WildSpawnType), bot), BotDifficulty.normal, true);
}

private void SpawnBotDebugServer(BotsController controller, EPlayerSide side, bool canBeSnipe, WildSpawnType profile = WildSpawnType.assault, BotDifficulty botDifficulty = BotDifficulty.normal, bool forcedSpawn = false)
{
var spawner = controller.BotSpawner;
if (spawner == null)
return;

var randomBotZone = spawner.GetRandomBotZone(canBeSnipe);
Spawn(spawner, side, randomBotZone, profile, botDifficulty, forcedSpawn).HandleExceptions();
}

public async Task Spawn(BotSpawner spawner, EPlayerSide side, BotZone zone, WildSpawnType profileType = WildSpawnType.assault, BotDifficulty botDifficulty = BotDifficulty.normal, bool forcedSpawn = false)
{
if (profileType.IsBossOrFollower())
{
var bossLocationSpawn = new BossLocationSpawn {
BossZone = "",
Time = 1f,
Delay = 0f,
TriggerId = "",
TriggerName = "",
BossChance = 100f,
BossName = profileType.ToString(),
BossDifficult = BotDifficulty.normal.ToString(),
BossEscortAmount = 0.ToString(),
BossEscortDifficult = BotDifficulty.normal.ToString(),
BossEscortType = WildSpawnType.followerBully.ToString()
};
bossLocationSpawn.ParseMainTypesTypes();
bossLocationSpawn.ForceSpawn = forcedSpawn;
bossLocationSpawn.IgnoreMaxBots = forcedSpawn;
spawner.BossSpawner.Spawn(bossLocationSpawn, new BotSpawnParams()).HandleExceptions();
}
else
{
const string fieldName = "_botCreator";
var field = AccessTools.Field(spawner.GetType(), fieldName);
if (field?.GetValue(spawner) is not IBotCreator botCreator)
{
AddConsoleLog(string.Format(Strings.ErrorCannotFindField, fieldName, spawner.GetType().Name).Red());
return;
}

spawner.TryToSpawnInZoneAndDelay(zone, await BotCreationDataClass.Create(new GetProfileData(side, profileType, botDifficulty), botCreator, 1, spawner), withCheckMinMax: true, newWave: true, null, forcedSpawn);
}
}

public class GetProfileData(EPlayerSide side, WildSpawnType spawnType, BotDifficulty botDifficulty, BotSpawnParams? spawnParams = null) : IGetProfileData
{
public EPlayerSide? Side { get; } = side;
public BotSpawnParams? SpawnParams { get; set; } = spawnParams;

public bool TryGetRole(out WildSpawnType role, out BotDifficulty difficulty)
{
role = spawnType;
difficulty = botDifficulty;
return true;
}

public Profile? ChooseProfile(List<Profile> profiles2Select, bool withDelete)
{
var list = profiles2Select.Where((x) => x.Info.Side == Side && x.Info.Settings.Role == spawnType && x.Info.Settings.BotDifficulty == botDifficulty).ToList();
if (list.Count == 0)
return null;

var profile = list.Random();
if (withDelete)
profiles2Select.Remove(profile);

return profile;
}

public WaveInfoClass[] PrepareToLoadBackend(int count)
{
var waveInfo = new WaveInfoClass(count, spawnType, botDifficulty);
return [waveInfo];
}

public bool IsValidSpawnType(WildSpawnType wildSpawnType)
{
return wildSpawnType == spawnType;
}

public string GetDebugLocalName()
{
return $"{Side}{Random.Range(0, 256)} Profile";
}

public string GetDebugData()
{
return $" Side:{Side} Type:{spawnType} BotDifficulty:{botDifficulty}";
}

public bool ShallChooseByData()
{
return spawnType is WildSpawnType.exUsec or WildSpawnType.pmcBot or WildSpawnType.assaultGroup or WildSpawnType.arenaFighter;
}

public bool IsBossOrFollowerByTime()
{
return IsBossOrFollower();
}

public bool IsZeroWave()
{
return false;
}

public bool IsBossOrFollower()
{
return spawnType.IsBossOrFollower();
}

public bool IsSpawnOnStart()
{
return false;
}

public bool CanAtZoneByType(BotZone botZone, ZoneLeaveControllerClass botsControllerZonesLeaveController)
{
return !botsControllerZonesLeaveController.IsZoneBlockFor(botZone, spawnType);
}
}

private static string[] FindBots(string search)
Expand Down
12 changes: 5 additions & 7 deletions Features/Ammunition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Comfort.Common;
using EFT.Ballistics;
using EFT.InventoryLogic;
using EFT.Trainer.Model;
using EFT.Trainer.Properties;
using JetBrains.Annotations;

Expand All @@ -19,21 +18,20 @@ internal class Ammunition : ToggleFeature
public override bool Enabled { get; set; } = false;

[UsedImplicitly]
private static void ShootPostfix(object shot)
private static void ShootPostfix(EftBulletClass shot)
{
var feature = FeatureFactory.GetFeature<Ammunition>();
if (feature == null || !feature.Enabled)
return;

var shotWrapper = new ShotWrapper(shot);
if (shotWrapper.Weapon is not Weapon weapon)
if (shot.Weapon is not Weapon weapon)
return;

var ammo = shotWrapper.Ammo;
var ammo = shot.Ammo;
if (ammo == null)
return;

var player = shotWrapper.Player;
var player = shot.Player.iPlayer;
if (player is not { IsYourPlayer: true })
return;

Expand Down Expand Up @@ -75,7 +73,7 @@ protected override void UpdateWhenEnabled()
{
HarmonyPatchOnce(harmony =>
{
HarmonyPostfix(harmony, typeof(BallisticsCalculator), nameof(BallisticsCalculator.Shoot), nameof(ShootPostfix));
HarmonyPostfix(harmony, typeof(BallisticsCalculator), nameof(BallisticsCalculator.Shoot), nameof(ShootPostfix), [typeof(EftBulletClass)]);
});
}
}
5 changes: 2 additions & 3 deletions Features/WallShoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ internal class WallShoot : ToggleFeature

#pragma warning disable IDE0060
[UsedImplicitly]
protected static bool IsPenetratedPrefix(object shot, Vector3 hitPoint, BallisticCollider __instance, ref bool __result)
protected static bool IsPenetratedPrefix(EftBulletClass shot, Vector3 hitPoint, BallisticCollider __instance, ref bool __result)
{
var feature = FeatureFactory.GetFeature<WallShoot>();
if (feature == null || !feature.Enabled)
return true; // keep using original code, we are not enabled

var shotWrapper = new ShotWrapper(shot);
var player = shotWrapper.Player;
var player = shot.Player.iPlayer;
if (player is not { IsYourPlayer: true })
return true; // keep using original code for other players

Expand Down
14 changes: 14 additions & 0 deletions Installer/CompilationResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO.Compression;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

Expand All @@ -10,4 +11,17 @@ internal class CompilationResult(CSharpCompilation? compilation, ZipArchive? arc
public ZipArchive? Archive { get; } = archive;
public Diagnostic[] Errors { get; } = errors;
public ResourceDescription[] Resources { get; } = resources;

public string[] ErrorFiles
{
get
{
return Errors
.Select(d => d.Location.SourceTree?.FilePath)
.Where(s => s is not null)
.OfType<string>()
.Distinct()
.ToArray();
}
}
}
7 changes: 1 addition & 6 deletions Installer/InstallCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,6 @@ private static async Task<CompilationResult> BuildTrainerAsync(Settings settings
};

var result = await GetCompilationAsync(context);
var files = result.Errors
.Select(d => d.Location.SourceTree?.FilePath)
.Where(s => s is not null)
.Distinct()
.ToArray();

if (context.IsFatalFailure)
return result;

Expand All @@ -179,6 +173,7 @@ private static async Task<CompilationResult> BuildTrainerAsync(Settings settings
}
}

var files = result.ErrorFiles;
if (result.Compilation == null && files.Length != 0 && files.All(file => folders.Any(folder => file!.StartsWith(folder))))
{
// Failure, retry by removing faulting features if possible
Expand Down
27 changes: 0 additions & 27 deletions Model/ShotWrapper.cs

This file was deleted.

Loading