@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user