Merge branch 'main' of https://github.com/sp-tarkov/server-csharp
This commit is contained in:
@@ -7,10 +7,6 @@
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Utils\Extensions\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SptDependencyInjection\SptDependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BotWeaponGenerator(
|
||||
IEnumerable<IInventoryMagGen> inventoryMagGenComponents
|
||||
)
|
||||
{
|
||||
protected List<IInventoryMagGen> _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents);
|
||||
protected IEnumerable<IInventoryMagGen> _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents);
|
||||
protected BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
protected PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
|
||||
protected RepairConfig _repairConfig = _configServer.GetConfig<RepairConfig>();
|
||||
@@ -42,13 +42,8 @@ public class BotWeaponGenerator(
|
||||
private static List<IInventoryMagGen> MagGenSetUp(IEnumerable<IInventoryMagGen> components)
|
||||
{
|
||||
var inventoryMagGens = components.ToList();
|
||||
inventoryMagGens.ToList()
|
||||
.Sort(
|
||||
(a, b) =>
|
||||
a.GetPriority() -
|
||||
b.GetPriority()
|
||||
);
|
||||
return inventoryMagGens.ToList();
|
||||
inventoryMagGens.Sort((a, b) => a.GetPriority() - b.GetPriority());
|
||||
return inventoryMagGens;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -398,7 +393,7 @@ public class BotWeaponGenerator(
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var isInternalMag = magTemplate.Properties.ReloadMagType == "InternalMagazine";
|
||||
var ammoTemplate = _itemHelper.GetItem(generatedWeaponResult.ChosenAmmoTemplate).Value;
|
||||
if (ammoTemplate is null)
|
||||
{
|
||||
@@ -722,7 +717,6 @@ public class BotWeaponGenerator(
|
||||
/// <param name="weaponWithMods">Weapon items list to amend</param>
|
||||
/// <param name="magazine">Magazine item details we're adding cartridges to</param>
|
||||
/// <param name="chosenAmmoTpl">Cartridge to put into the magazine</param>
|
||||
/// <param name="newStackSize">How many cartridges should go into the magazine</param>
|
||||
/// <param name="magazineTemplate">Magazines db template</param>
|
||||
protected void AddOrUpdateMagazinesChildWithAmmo(List<Item> weaponWithMods, Item magazine, string chosenAmmoTpl, TemplateItem magazineTemplate)
|
||||
{
|
||||
@@ -736,8 +730,7 @@ public class BotWeaponGenerator(
|
||||
}
|
||||
|
||||
// Create array with just magazine
|
||||
List<Item> magazineWithCartridges = new();
|
||||
magazineWithCartridges.AddRange(magazine);
|
||||
List<Item> magazineWithCartridges = [magazine];
|
||||
|
||||
// Add full cartridge child items to above array
|
||||
_itemHelper.FillMagazineWithCartridge(magazineWithCartridges, magazineTemplate, chosenAmmoTpl, 1);
|
||||
|
||||
@@ -530,13 +530,17 @@ public class BotGeneratorHelper(
|
||||
foreach (var slotGrid in value?.Properties?.Grids ?? [])
|
||||
{
|
||||
// Grid is empty, skip or item size is bigger than grid
|
||||
if (slotGrid.Props?.CellsH == 0 || slotGrid.Props?.CellsV == 0 || itemSize[0] * itemSize[1] > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH)
|
||||
if (slotGrid.Props?.CellsH == 0 ||
|
||||
slotGrid.Props?.CellsV == 0 ||
|
||||
itemSize[0] * itemSize[1] > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Can't put item type in grid, skip all grids as we're assuming they have the same rules
|
||||
if (!ItemAllowedInContainer(slotGrid, rootItemTplId))
|
||||
{
|
||||
// Multiple containers, maybe next one allows item, only break out of loop for this containers grids
|
||||
// Multiple containers, maybe next one allows item, only break out of loop for the containers grids
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -548,44 +552,22 @@ public class BotGeneratorHelper(
|
||||
|
||||
// Get root items in container we can iterate over to find out what space is free
|
||||
var containerItemsToCheck = existingContainerItems.Where(x => x.SlotId == slotGrid.Name);
|
||||
var itemsToRemove = new List<Item>();
|
||||
var itemsToAdd = new List<Item>();
|
||||
foreach (var item in containerItemsToCheck)
|
||||
{
|
||||
// Check item in contain for children, store for later insertion into `containerItemsToCheck`
|
||||
// (used later when figuring out how much space weapon takes up)
|
||||
var itemWithChildItems = _itemHelper.FindAndReturnChildrenAsItems(inventory.Items, item.Id);
|
||||
if (itemWithChildItems.Count <= 1) continue;
|
||||
var containerItemsWithChildren = GetContainerItemsWithChildren(containerItemsToCheck, inventory.Items);
|
||||
|
||||
|
||||
// Store replaced item + new Child items to add later as we can't modify a collecting while looking over it
|
||||
itemsToRemove.Add(item);
|
||||
itemsToAdd.AddRange(itemsToAdd);
|
||||
}
|
||||
|
||||
// Remove the base items flagged above
|
||||
foreach (var item in itemsToRemove)
|
||||
{
|
||||
existingContainerItems.Remove(item);
|
||||
}
|
||||
|
||||
// Add item back with its child items
|
||||
existingContainerItems.AddRange(itemsToAdd);
|
||||
|
||||
// Get rid of items free/used spots in current grid
|
||||
if (slotGrid.Props is not null)
|
||||
{
|
||||
// Get rid of an items free/used spots in current grid
|
||||
var slotGridMap = _inventoryHelper.GetContainerMap(
|
||||
slotGrid.Props.CellsH.GetValueOrDefault(),
|
||||
slotGrid.Props.CellsV.GetValueOrDefault(),
|
||||
existingContainerItems,
|
||||
containerItemsWithChildren,
|
||||
container.Id
|
||||
);
|
||||
|
||||
// Try to fit item into grid
|
||||
var findSlotResult = _containerHelper.FindSlotForItem(slotGridMap, itemSize[0], itemSize[1]);
|
||||
|
||||
// Open slot found, add item to inventory
|
||||
// Free slot found, add item
|
||||
if (findSlotResult.Success ?? false)
|
||||
{
|
||||
var parentItem = itemWithChildren.FirstOrDefault((i) => i.Id == rootItemId);
|
||||
@@ -633,6 +615,28 @@ public class BotGeneratorHelper(
|
||||
return ItemAddedResult.NO_SPACE;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take a list of items and check if they need children + add them
|
||||
/// </summary>
|
||||
/// <param name="containerItems"></param>
|
||||
/// <param name="inventoryItems"></param>
|
||||
/// <returns></returns>
|
||||
protected List<Item> GetContainerItemsWithChildren(IEnumerable<Item> containerItems, List<Item> inventoryItems)
|
||||
{
|
||||
var result = new List<Item>();
|
||||
foreach (var item in containerItems)
|
||||
{
|
||||
// Check item in container for children, store for later insertion into `containerItemsToCheck`
|
||||
// (used later when figuring out how much space weapon takes up)
|
||||
var itemWithChildItems = _itemHelper.FindAndReturnChildrenAsItems(inventoryItems, item.Id);
|
||||
|
||||
// Item had children, replace existing data with item + its children
|
||||
result.AddRange(itemWithChildItems);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the provided item allowed inside a container
|
||||
/// </summary>
|
||||
|
||||
@@ -510,7 +510,7 @@ public class ProfileHelper(
|
||||
/// <returns>True if account is developer</returns>
|
||||
public bool IsDeveloperAccount(string sessionID)
|
||||
{
|
||||
return GetFullProfile(sessionID)?.ProfileInfo?.Edition?.ToLower().StartsWith("spt developer") == false;
|
||||
return GetFullProfile(sessionID)?.ProfileInfo?.Edition?.ToLower().StartsWith("spt developer") ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,13 +32,16 @@ public class CreateProfileService(
|
||||
SaveServer _saveServer,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
PlayerScavGenerator _playerScavGenerator,
|
||||
ICloner _cloner
|
||||
ICloner _cloner,
|
||||
MailSendService _mailSendService
|
||||
)
|
||||
{
|
||||
public string CreateProfile(string sessionId, ProfileCreateRequestData request)
|
||||
{
|
||||
var account = _saveServer.GetProfile(sessionId).ProfileInfo;
|
||||
var profileTemplate = _cloner.Clone(_databaseService.GetProfiles()?.GetByJsonProp<ProfileSides>(account.Edition)?.GetByJsonProp<TemplateSide>(request.Side.ToLower()));
|
||||
var profileTemplate = _cloner.Clone(
|
||||
_databaseService.GetProfiles()?.GetByJsonProp<ProfileSides>(account.Edition)?.GetByJsonProp<TemplateSide>(request.Side.ToLower())
|
||||
);
|
||||
var pmcData = profileTemplate.Character;
|
||||
|
||||
// Delete existing profile
|
||||
@@ -439,18 +442,17 @@ public class CreateProfileService(
|
||||
QuestStatusEnum.Started,
|
||||
sessionID,
|
||||
response
|
||||
);
|
||||
).ToList();
|
||||
|
||||
/* TODO:
|
||||
_mailSendService.sendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
this.traderHelper.getTraderById(questFromDb.traderId),
|
||||
MessageType.QUEST_START,
|
||||
messageId,
|
||||
itemRewards,
|
||||
this.timeUtil.getHoursAsSeconds(100),
|
||||
);
|
||||
*/
|
||||
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
questFromDb.TraderId,
|
||||
MessageType.QUEST_START,
|
||||
messageId,
|
||||
itemRewards,
|
||||
_timeUtil.GetHoursAsSeconds(100)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class InMemoryCacheService(
|
||||
ICloner _cloner)
|
||||
ICloner _cloner
|
||||
)
|
||||
{
|
||||
|
||||
protected Dictionary<string, object?> _cacheData = new();
|
||||
|
||||
// Store data into an in-memory object
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Eft.Common;
|
||||
using Core.Models.Eft.Match;
|
||||
|
||||
namespace Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class LegacyLocationLifecycleService
|
||||
{
|
||||
/// <summary>
|
||||
/// Handle client/match/offline/end
|
||||
/// </summary>
|
||||
public void endOfflineRaid(EndOfflineRaidRequestData info, string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle when a player extracts using a car - Add rep to fence
|
||||
/// </summary>
|
||||
/// <param name="extractName">name of the extract used</param>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
protected void handleCarExtract(string extractName, PmcData pmcData, string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the fence rep gain from using a car or coop extract
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Profile</param>
|
||||
/// <param name="baseGain">amount gained for the first extract</param>
|
||||
/// <param name="extractCount">Number of times extract was taken</param>
|
||||
/// <returns>Fence standing after taking extract</returns>
|
||||
protected int getFenceStandingAfterExtract(PmcData pmcData, int baseGain, int extractCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Was extract by car
|
||||
/// </summary>
|
||||
/// <param name="extractName">name of extract</param>
|
||||
/// <returns>true if car extract</returns>
|
||||
protected bool extractWasViaCar(string extractName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Did player take a COOP extract
|
||||
/// </summary>
|
||||
/// <param name="extractName">Name of extract player took</param>
|
||||
/// <returns>True if coop extract</returns>
|
||||
protected bool extractWasViaCoop(string extractName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle when a player extracts using a coop extract - add rep to fence
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Session/player id</param>
|
||||
/// <param name="pmcData">Profile</param>
|
||||
/// <param name="extractName">Name of extract taken</param>
|
||||
protected void handleCoopExtract(string sessionId, PmcData pmcData, string extractName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected void sendCoopTakenFenceMessage(string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -8,19 +8,22 @@ public class NotificationService
|
||||
{
|
||||
protected Dictionary<string, List<WsNotificationEvent>> _messageQueue = new();
|
||||
|
||||
public Dictionary<string, List<object>> GetMessageQueue()
|
||||
public Dictionary<string, List<WsNotificationEvent>> GetMessageQueue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _messageQueue;
|
||||
}
|
||||
|
||||
public List<object> GetMessageFromQueue(string sessionId)
|
||||
public List<WsNotificationEvent>? GetMessageFromQueue(string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _messageQueue.GetValueOrDefault(sessionId);
|
||||
}
|
||||
|
||||
public void UpdateMessageOnQueue(string sessionId, List<WsNotificationEvent> value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (_messageQueue.ContainsKey(sessionId))
|
||||
{
|
||||
_messageQueue[sessionId] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Has(string sessionID)
|
||||
@@ -33,7 +36,9 @@ public class NotificationService
|
||||
/// </summary>
|
||||
public WsNotificationEvent Pop(string sessionID)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var result = Get(sessionID).First();
|
||||
Get(sessionID).Remove(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -93,15 +93,6 @@ public class ProfileFixerService(
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find issues in the scav profile data that may cause issues
|
||||
/// </summary>
|
||||
/// <param name="scavProfile">profile to check and fix</param>
|
||||
public void CheckForAndFixScavProfileIssues(PmcData scavProfile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to fix common item issues that corrupt profiles
|
||||
/// </summary>
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RaidWeatherService(
|
||||
ISptLogger<RaidWeatherService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
TimeUtil _timeUtil,
|
||||
WeatherGenerator _weatherGenerator,
|
||||
SeasonalEventService _seasonalEventService,
|
||||
|
||||
@@ -897,7 +897,21 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void EnableDancingTree()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var maps = _databaseService.GetLocations();
|
||||
List<string> mapsToCheck = ["hideout", "base", "privatearea"];
|
||||
foreach (KeyValuePair<string, object?> map in maps.GetAllPropsAsDict())
|
||||
{
|
||||
// Skip maps that have no tree
|
||||
if (mapsToCheck.Contains(map.Key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var mapData = map.Value as Location;
|
||||
if (mapData.Base?.Events?.Khorovod?.Chance is not null) {
|
||||
mapData.Base.Events.Khorovod.Chance = 100;
|
||||
mapData.Base.BotLocationModifier.KhorovodChance = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -905,12 +919,69 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void AddGifterBotToMaps()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var gifterSettings = _seasonalEventConfig.GifterSettings;
|
||||
var maps = _databaseService.GetLocations().GetAllPropsAsDict();
|
||||
foreach (var gifterMapSettings in gifterSettings) {
|
||||
Location mapData = maps.FirstOrDefault(x => x.Key == gifterMapSettings.Map).Value as Location;
|
||||
// Dont add gifter to map twice
|
||||
if (mapData.Base.BossLocationSpawn.Any((boss) => boss.BossName == "gifter")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mapData.Base.BossLocationSpawn.Add(new BossLocationSpawn {
|
||||
BossName = "gifter",
|
||||
BossChance = gifterMapSettings.SpawnChance,
|
||||
BossZone = gifterMapSettings.Zones,
|
||||
IsBossPlayer = false,
|
||||
BossDifficulty = "normal",
|
||||
BossEscortType = "gifter",
|
||||
BossEscortDifficulty = "normal",
|
||||
BossEscortAmount = "0",
|
||||
ForceSpawn = true,
|
||||
SpawnMode = ["regular", "pve"],
|
||||
Time = -1,
|
||||
TriggerId = "",
|
||||
TriggerName = "",
|
||||
Delay = 0,
|
||||
IsRandomTimeSpawn = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleModEvent(SeasonalEvent seasonalEvent, Config globalConfig)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (seasonalEvent.Settings?.EnableChristmasHideout ?? false) {
|
||||
globalConfig.EventType = globalConfig.EventType.Where((x) => x != "None").ToList();
|
||||
globalConfig.EventType.Add("Christmas");
|
||||
}
|
||||
|
||||
if (seasonalEvent.Settings?.EnableHalloweenHideout ?? false) {
|
||||
globalConfig.EventType = globalConfig.EventType.Where((x) => x != "None").ToList();
|
||||
globalConfig.EventType.Add("Halloween");
|
||||
globalConfig.EventType.Add("HalloweenIllumination");
|
||||
}
|
||||
|
||||
if (seasonalEvent.Settings?.AddEventGearToBots ?? false) {
|
||||
AddEventGearToBots(seasonalEvent.Type);
|
||||
}
|
||||
if (seasonalEvent.Settings?.AddEventLootToBots ?? false) {
|
||||
AddEventLootToBots(seasonalEvent.Type);
|
||||
}
|
||||
|
||||
if (seasonalEvent.Settings?.EnableSummoning ?? false) {
|
||||
EnableHalloweenSummonEvent();
|
||||
AddEventBossesToMaps("halloweensummon");
|
||||
}
|
||||
if (seasonalEvent.Settings?.ZombieSettings?.Enabled ?? false) {
|
||||
ConfigureZombies(seasonalEvent.Settings.ZombieSettings);
|
||||
}
|
||||
if (seasonalEvent.Settings?.ForceSeason is not null) {
|
||||
_weatherConfig.OverrideSeason = seasonalEvent.Settings.ForceSeason;
|
||||
}
|
||||
|
||||
if (seasonalEvent.Settings?.AdjustBotAppearances ?? false) {
|
||||
AdjustBotAppearanceValues(seasonalEvent.Type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user