Merge branch 'main' of https://github.com/sp-tarkov/server-csharp
This commit is contained in:
Alex
2025-01-16 14:08:45 +00:00
7 changed files with 219 additions and 21 deletions
+3 -4
View File
@@ -67,10 +67,9 @@ public class GameCallbacks : OnLoad
/// <returns></returns>
public string GameStart(string url, EmptyRequestData info, string sessionID)
{
var today = _timeUtil.GetDate();
var startTimestampMS = _timeUtil.GetTimeStamp();
_gameController.GameStart(url, info, sessionID, startTimestampMS);
return _httpResponseUtil.GetBody(new GameStartResponse() { UtcTime = startTimestampMS / 1000 });
var startTimestampSec = _timeUtil.GetTimeStamp();
_gameController.GameStart(url, info, sessionID, startTimestampSec);
return _httpResponseUtil.GetBody(new GameStartResponse() { UtcTime = startTimestampSec });
}
/// <summary>
+3 -3
View File
@@ -775,11 +775,11 @@ public class BotEquipmentModGenerator
case "patron_in_weapon":
case "patron_in_weapon_000":
case "patron_in_weapon_001":
return parentTemplate.Properties.Chambers.FirstOrDefault((chamber) => chamber.Name.Contains(modSlotLower));
return parentTemplate?.Properties?.Chambers?.FirstOrDefault((chamber) => chamber.Name.Contains(modSlotLower));
case "cartridges":
return parentTemplate.Properties.Cartridges.FirstOrDefault((c) => c.Name.ToLower() == modSlotLower);
return parentTemplate?.Properties?.Cartridges?.FirstOrDefault((c) => c.Name?.ToLower() == modSlotLower);
default:
return parentTemplate.Properties.Slots.FirstOrDefault((s) => s.Name.ToLower() == modSlotLower);
return parentTemplate?.Properties?.Slots?.FirstOrDefault((s) => s.Name?.ToLower() == modSlotLower);
}
}
+2 -1
View File
@@ -224,8 +224,9 @@ public class BotWeaponGenerator
);
}
var tempList = _cloner.Clone(weaponWithModsArray.Where((item) => item.SlotId == _modMagazineSlotId));
// Fill existing magazines to full and sync ammo type
foreach (var magazine in weaponWithModsArray.Where((item) => item.SlotId == _modMagazineSlotId))
foreach (var magazine in tempList)
{
FillExistingMagazines(weaponWithModsArray, magazine, ammoTpl);
}
@@ -1,12 +1,23 @@
using Core.Annotations;
using Core.Helpers;
using Core.Utils;
namespace Core.Generators.WeaponGen.Implementations;
[Injectable]
public class BarrelInvetoryMagGen : InventoryMagGen, IInventoryMagGen
{
public BarrelInvetoryMagGen()
private readonly RandomUtil _randomUtil;
private readonly BotWeaponGeneratorHelper _botWeaponGeneratorHelper;
public BarrelInvetoryMagGen
(
RandomUtil randomUtil,
BotWeaponGeneratorHelper botWeaponGeneratorHelper
)
{
_randomUtil = randomUtil;
_botWeaponGeneratorHelper = botWeaponGeneratorHelper;
}
public int GetPriority()
@@ -16,11 +27,31 @@ public class BarrelInvetoryMagGen : InventoryMagGen, IInventoryMagGen
public bool CanHandleInventoryMagGen(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
return inventoryMagGen.GetWeaponTemplate().Properties.ReloadMode == "OnlyBarrel";
}
public void Process(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
// Can't be done by _props.ammoType as grenade launcher shoots grenades with ammoType of "buckshot"
double? randomisedAmmoStackSize = null;
if (inventoryMagGen.GetAmmoTemplate().Properties.StackMaxRandom == 1)
{
// doesnt stack
randomisedAmmoStackSize = _randomUtil.GetInt(3, 6);
}
else
{
randomisedAmmoStackSize = _randomUtil.GetInt(
(int)inventoryMagGen.GetAmmoTemplate().Properties.StackMinRandom,
(int)inventoryMagGen.GetAmmoTemplate().Properties.StackMaxRandom
);
}
_botWeaponGeneratorHelper.AddAmmoIntoEquipmentSlots(
inventoryMagGen.GetAmmoTemplate().Id,
(int)randomisedAmmoStackSize,
inventoryMagGen.GetPmcInventory(),
null
);
}
}
@@ -1,13 +1,39 @@
using Core.Annotations;
using Core.Helpers;
using Core.Models.Eft.Common.Tables;
using Core.Models.Enums;
using Core.Models.Utils;
using Core.Services;
using Core.Utils;
namespace Core.Generators.WeaponGen.Implementations;
[Injectable]
public class ExternalInventoryMagGen : InventoryMagGen, IInventoryMagGen
{
public ExternalInventoryMagGen()
private readonly ISptLogger<ExternalInventoryMagGen> _logger;
private readonly ItemHelper _itemHelper;
private readonly LocalisationService _localisationService;
private readonly BotWeaponGeneratorHelper _botWeaponGeneratorHelper;
private readonly BotGeneratorHelper _botGeneratorHelper;
private readonly RandomUtil _randomUtil;
public ExternalInventoryMagGen
(
ISptLogger<ExternalInventoryMagGen> logger,
ItemHelper itemHelper,
LocalisationService localisationService,
BotWeaponGeneratorHelper botWeaponGeneratorHelper,
BotGeneratorHelper botGeneratorHelper,
RandomUtil randomUtil
)
{
_logger = logger;
_itemHelper = itemHelper;
_localisationService = localisationService;
_botWeaponGeneratorHelper = botWeaponGeneratorHelper;
_botGeneratorHelper = botGeneratorHelper;
_randomUtil = randomUtil;
}
public int GetPriority()
@@ -17,16 +43,124 @@ public class ExternalInventoryMagGen : InventoryMagGen, IInventoryMagGen
public bool CanHandleInventoryMagGen(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
return true; // Fallback, if code reaches here it means no other implementation can handle this type of magazine
}
public void Process(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
// Cout of attempts to fit a magazine into bot inventory
var fitAttempts = 0;
// Magazine Db template
var magTemplate = inventoryMagGen.GetMagazineTemplate();
var magazineTpl = magTemplate.Id;
var weapon = inventoryMagGen.GetWeaponTemplate();
List<string> attemptedMagBlacklist = [];
var defaultMagazineTpl = _botWeaponGeneratorHelper.GetWeaponsDefaultMagazineTpl(weapon);
var randomizedMagazineCount = _botWeaponGeneratorHelper.GetRandomizedMagazineCount(inventoryMagGen.GetMagCount());
for (var i = 0; i < randomizedMagazineCount; i++) {
var magazineWithAmmo = _botWeaponGeneratorHelper.CreateMagazineWithAmmo(
magazineTpl,
inventoryMagGen.GetAmmoTemplate().Id,
magTemplate
);
var fitsIntoInventory = _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
[EquipmentSlots.TacticalVest.ToString(), EquipmentSlots.Pockets.ToString()],
magazineWithAmmo[0].Id,
magazineTpl,
magazineWithAmmo,
inventoryMagGen.GetPmcInventory()
);
if (fitsIntoInventory == ItemAddedResult.NO_CONTAINERS) {
// No containers to fit magazines, stop trying
break;
}
// No space for magazine and we haven't reached desired magazine count
if (fitsIntoInventory == ItemAddedResult.NO_SPACE && i < randomizedMagazineCount) {
// Prevent infinite loop by only allowing 5 attempts at fitting a magazine into inventory
if (fitAttempts > 5) {
_logger.Debug($"Failed {fitAttempts} times to add magazine {magazineTpl} to bot inventory, stopping");
break;
}
/* We were unable to fit at least the minimum amount of magazines,
* so we fallback to default magazine and try again.
* Temporary workaround to Killa spawning with no extra mags if he spawns with a drum mag */
if (magazineTpl == defaultMagazineTpl) {
// We were already on default - stop here to prevent infinite looping
break;
}
// Add failed magazine tpl to blacklist
attemptedMagBlacklist.Add(magazineTpl);
// Set chosen magazine tpl to the weapons default magazine tpl and try to fit into inventory next loop
magazineTpl = defaultMagazineTpl;
magTemplate = _itemHelper.GetItem(magazineTpl).Value;
if (magTemplate is null) {
_logger.Error(
_localisationService.GetText("bot-unable_to_find_default_magazine_item", magazineTpl)
);
break;
}
// Edge case - some weapons (SKS) have an internal magazine as default, choose random non-internal magazine to add to bot instead
if (magTemplate.Properties.ReloadMagType == "InternalMagazine") {
var result = GetRandomExternalMagazineForInternalMagazineGun(
inventoryMagGen.GetWeaponTemplate().Id,
attemptedMagBlacklist
);
if (result?.Id is null) {
_logger.Debug($"Unable to add additional magazine into bot inventory for weapon: {weapon.Name}, attempted: {fitAttempts} times");
break;
}
magazineTpl = result.Id;
magTemplate = result;
fitAttempts++;
}
// Reduce loop counter by 1 to ensure we get full cout of desired magazines
i--;
}
if (fitsIntoInventory == ItemAddedResult.SUCCESS) {
// Reset fit counter now it succeeded
fitAttempts = 0;
}
}
}
public TemplateItem? GetRandomExternalMagazineForInternalMagazineGun(string weaponTpl, List<string> magazineBlacklist)
{
throw new NotImplementedException();
// The mag Slot data for the weapon
var magSlot = _itemHelper.GetItem(weaponTpl).Value.Properties.Slots.FirstOrDefault((x) => x.Name == "mod_magazine");
if (magSlot is null) {
return null;
}
// All possible mags that fit into the weapon excluding blacklisted
var magazinePool = magSlot.Props.Filters[0].Filter.Where((x) => !magazineBlacklist.Contains(x)).Select(
(x) => _itemHelper.GetItem(x).Value
);
if (magazinePool is null) {
return null;
}
// Non-internal magazines that fit into the weapon
var externalMagazineOnlyPool = magazinePool.Where((x) => x.Properties.ReloadMagType != "InternalMagazine");
if (externalMagazineOnlyPool is null || externalMagazineOnlyPool?.Count() == 0) {
return null;
}
// Randomly chosen external magazine
return _randomUtil.GetArrayValue(externalMagazineOnlyPool);
}
}
@@ -1,12 +1,19 @@
using Core.Annotations;
using Core.Helpers;
namespace Core.Generators.WeaponGen.Implementations;
[Injectable]
public class InternalMagazineInventoryMagGen : InventoryMagGen, IInventoryMagGen
{
public InternalMagazineInventoryMagGen()
private readonly BotWeaponGeneratorHelper _botWeaponGeneratorHelper;
public InternalMagazineInventoryMagGen
(
BotWeaponGeneratorHelper botWeaponGeneratorHelper
)
{
_botWeaponGeneratorHelper = botWeaponGeneratorHelper;
}
public int GetPriority()
@@ -16,11 +23,20 @@ public class InternalMagazineInventoryMagGen : InventoryMagGen, IInventoryMagGen
public bool CanHandleInventoryMagGen(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
return inventoryMagGen.GetMagazineTemplate().Properties.ReloadMagType == "InternalMagazine";
}
public void Process(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
var bulletCount = _botWeaponGeneratorHelper.GetRandomizedBulletCount(
inventoryMagGen.GetMagCount(),
inventoryMagGen.GetMagazineTemplate()
);
_botWeaponGeneratorHelper.AddAmmoIntoEquipmentSlots(
inventoryMagGen.GetAmmoTemplate().Id,
(int)bulletCount,
inventoryMagGen.GetPmcInventory(),
null
);
}
}
@@ -1,12 +1,20 @@
using Core.Annotations;
using Core.Helpers;
using Core.Models.Enums;
namespace Core.Generators.WeaponGen.Implementations;
[Injectable]
public class UbglExternalMagGen : InventoryMagGen, IInventoryMagGen
{
public UbglExternalMagGen()
private readonly BotWeaponGeneratorHelper _botWeaponGeneratorHelper;
public UbglExternalMagGen
(
BotWeaponGeneratorHelper botWeaponGeneratorHelper
)
{
_botWeaponGeneratorHelper = botWeaponGeneratorHelper;
}
public int GetPriority()
@@ -16,11 +24,20 @@ public class UbglExternalMagGen : InventoryMagGen, IInventoryMagGen
public bool CanHandleInventoryMagGen(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
return inventoryMagGen.GetWeaponTemplate().Parent == BaseClasses.UBGL;
}
public void Process(InventoryMagGen inventoryMagGen)
{
throw new NotImplementedException();
var bulletCount = _botWeaponGeneratorHelper.GetRandomizedBulletCount(
inventoryMagGen.GetMagCount(),
inventoryMagGen.GetMagazineTemplate()
);
_botWeaponGeneratorHelper.AddAmmoIntoEquipmentSlots(
inventoryMagGen.GetAmmoTemplate().Id,
(int)bulletCount,
inventoryMagGen.GetPmcInventory(),
[EquipmentSlots.TacticalVest.ToString()]
);
}
}