mooooaaaaaaaaaaar
This commit is contained in:
@@ -1,59 +1,159 @@
|
||||
using SptCommon.Annotations;
|
||||
using Core.Helpers;
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Eft.Common;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Enums;
|
||||
using Core.Models.Spt.Config;
|
||||
using Core.Servers;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
|
||||
namespace Core.Generators;
|
||||
|
||||
[Injectable]
|
||||
public class RagfairAssortGenerator()
|
||||
public class RagfairAssortGenerator(
|
||||
HashUtil hashUtil,
|
||||
ItemHelper itemHelper,
|
||||
PresetHelper presetHelper,
|
||||
SeasonalEventService seasonalEventService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected List<List<Item>> generatedAssortItems = [];
|
||||
protected RagfairConfig ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get an array of arrays that can be sold on the flea
|
||||
/// Each sub array contains item + children (if any)
|
||||
/// </summary>
|
||||
/// <returns>List of Lists</returns>
|
||||
protected List<string> ragfairItemInvalidBaseTypes =
|
||||
[
|
||||
BaseClasses.LOOT_CONTAINER, // Safe, barrel cache etc
|
||||
BaseClasses.STASH, // Player inventory stash
|
||||
BaseClasses.SORTING_TABLE,
|
||||
BaseClasses.INVENTORY,
|
||||
BaseClasses.STATIONARY_CONTAINER,
|
||||
BaseClasses.POCKETS,
|
||||
BaseClasses.BUILT_IN_INSERTS,
|
||||
];
|
||||
|
||||
/**
|
||||
* Get an array of arrays that can be sold on the flea
|
||||
* Each sub array contains item + children (if any)
|
||||
* @returns array of arrays
|
||||
*/
|
||||
public List<List<Item>> GetAssortItems()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!AssortsAreGenerated())
|
||||
{
|
||||
generatedAssortItems = GenerateRagfairAssortItems();
|
||||
}
|
||||
|
||||
return generatedAssortItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check internal generatedAssortItems array has objects
|
||||
/// </summary>
|
||||
/// <returns>true if array has objects</returns>
|
||||
/**
|
||||
* Check internal generatedAssortItems array has objects
|
||||
* @returns true if array has objects
|
||||
*/
|
||||
protected bool AssortsAreGenerated()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return generatedAssortItems.Count > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate an array of arrays (item + children) the flea can sell
|
||||
/// </summary>
|
||||
/// <returns>List of Lists (item + children)</returns>
|
||||
/**
|
||||
* Generate an array of arrays (item + children) the flea can sell
|
||||
* @returns array of arrays (item + children)
|
||||
*/
|
||||
protected List<List<Item>> GenerateRagfairAssortItems()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
List<List<Item>> results = [];
|
||||
|
||||
/** Get cloned items from db */
|
||||
var dbItemsClone = itemHelper.GetItems().Where((item) => item.Type != "Node");
|
||||
|
||||
/** Store processed preset tpls so we dont add them when procesing non-preset items */
|
||||
List<string> processedArmorItems = [];
|
||||
var seasonalEventActive = seasonalEventService.SeasonalEventEnabled();
|
||||
var seasonalItemTplBlacklist = seasonalEventService.GetInactiveSeasonalEventItems();
|
||||
|
||||
var presets = GetPresetsToAdd();
|
||||
foreach (var preset in presets)
|
||||
{
|
||||
// Update Ids and clone
|
||||
var presetAndMods = itemHelper.ReplaceIDs(preset.Items);
|
||||
itemHelper.RemapRootItemId(presetAndMods);
|
||||
|
||||
// Add presets base item tpl to the processed list so its skipped later on when processing items
|
||||
processedArmorItems.Add(preset.Items[0].Template);
|
||||
|
||||
presetAndMods[0].ParentId = "hideout";
|
||||
presetAndMods[0].SlotId = "hideout";
|
||||
presetAndMods[0].Upd = new Upd()
|
||||
{ StackObjectsCount = 99999999, UnlimitedCount = true, SptPresetId = preset.Id };
|
||||
|
||||
results.Add(presetAndMods);
|
||||
}
|
||||
|
||||
foreach (var item in dbItemsClone)
|
||||
{
|
||||
if (!itemHelper.IsValidItem(item.Id, ragfairItemInvalidBaseTypes))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip seasonal items when not in-season
|
||||
if (
|
||||
ragfairConfig.Dynamic.RemoveSeasonalItemsWhenNotInEvent &&
|
||||
!seasonalEventActive &&
|
||||
seasonalItemTplBlacklist.Contains(item.Id)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (processedArmorItems.Contains(item.Id))
|
||||
{
|
||||
// Already processed
|
||||
continue;
|
||||
}
|
||||
|
||||
var ragfairAssort = CreateRagfairAssortRootItem(
|
||||
item.Id,
|
||||
item.Id
|
||||
); // tplid and id must be the same so hideout recipe rewards work
|
||||
|
||||
results.Add([ragfairAssort]);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get presets from globals to add to flea
|
||||
/// ragfairConfig.dynamic.showDefaultPresetsOnly decides if its all presets or just defaults
|
||||
/// </summary>
|
||||
/// <returns>Dictionary</returns>
|
||||
/**
|
||||
* Get presets from globals to add to flea
|
||||
* ragfairConfig.dynamic.showDefaultPresetsOnly decides if its all presets or just defaults
|
||||
* @returns IPreset array
|
||||
*/
|
||||
protected List<Preset> GetPresetsToAdd()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return ragfairConfig.Dynamic.ShowDefaultPresetsOnly
|
||||
? presetHelper.GetDefaultPresets().Values.ToList()
|
||||
: presetHelper.GetAllPresets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a base assort item and return it with populated values + 999999 stack count + unlimited count = true
|
||||
/// </summary>
|
||||
/// <param name="tplId">tplid to add to item</param>
|
||||
/// <param name="id">id to add to item</param>
|
||||
/// <returns>Hydrated Item object</returns>
|
||||
protected Item CreateRagfairAssortRootItem(string tplId, string id_checkTodoComment) // TODO: string id = this.hashUtil.generate()
|
||||
/**
|
||||
* Create a base assort item and return it with populated values + 999999 stack count + unlimited count = true
|
||||
* @param tplId tplid to add to item
|
||||
* @param id id to add to item
|
||||
* @returns Hydrated Item object
|
||||
*/
|
||||
protected Item CreateRagfairAssortRootItem(string tplId, string? id = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (string.IsNullOrEmpty(id))
|
||||
id = hashUtil.Generate();
|
||||
return new Item()
|
||||
{
|
||||
Id = id,
|
||||
Template = tplId,
|
||||
ParentId = "hideout",
|
||||
SlotId = "hideout",
|
||||
Upd = new Upd() { StackObjectsCount = 99999999, UnlimitedCount = true }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -154,11 +154,11 @@ public class HandbookHelper(
|
||||
/// <param name="nonRoubleCurrencyCount">Currency count to convert</param>
|
||||
/// <param name="currencyTypeFrom">What current currency is</param>
|
||||
/// <returns>Count in roubles</returns>
|
||||
public double InRUB(double nonRoubleCurrencyCount, string currencyTypeFrom)
|
||||
public int InRUB(double nonRoubleCurrencyCount, string currencyTypeFrom)
|
||||
{
|
||||
return currencyTypeFrom == Money.ROUBLES
|
||||
return (int) (currencyTypeFrom == Money.ROUBLES
|
||||
? nonRoubleCurrencyCount
|
||||
: Math.Round(nonRoubleCurrencyCount * (GetTemplatePrice(currencyTypeFrom) ?? 0));
|
||||
: Math.Round(nonRoubleCurrencyCount * (GetTemplatePrice(currencyTypeFrom) ?? 0)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -167,15 +167,15 @@ public class HandbookHelper(
|
||||
/// <param name="roubleCurrencyCount">roubles to convert</param>
|
||||
/// <param name="currencyTypeTo">Currency to convert roubles into</param>
|
||||
/// <returns>currency count in desired type</returns>
|
||||
public double FromRUB(double roubleCurrencyCount, string currencyTypeTo)
|
||||
public int FromRUB(double roubleCurrencyCount, string currencyTypeTo)
|
||||
{
|
||||
if (currencyTypeTo == Money.ROUBLES) {
|
||||
return roubleCurrencyCount;
|
||||
return (int) roubleCurrencyCount;
|
||||
}
|
||||
|
||||
// Get price of currency from handbook
|
||||
var price = GetTemplatePrice(currencyTypeTo);
|
||||
return price is not null ? Math.Max(1, Math.Round((double)(roubleCurrencyCount / price))) : 0;
|
||||
return (int) (price is not null ? Math.Max(1, Math.Round((double)(roubleCurrencyCount / price))) : 0);
|
||||
}
|
||||
|
||||
public HandbookCategory GetCategoryById(string handbookId)
|
||||
|
||||
@@ -1,92 +1,215 @@
|
||||
using SptCommon.Annotations;
|
||||
using System.Runtime.InteropServices.JavaScript;
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Enums;
|
||||
using Core.Models.Spt.Config;
|
||||
using Core.Models.Utils;
|
||||
using Core.Servers;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
using Core.Utils.Cloners;
|
||||
|
||||
namespace Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RagfairServerHelper
|
||||
public class RagfairServerHelper(
|
||||
ISptLogger<RagfairServerHelper> logger,
|
||||
RandomUtil randomUtil,
|
||||
TimeUtil timeUtil,
|
||||
SaveServer saveServer,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
ItemHelper itemHelper,
|
||||
TraderHelper traderHelper,
|
||||
MailSendService mailSendService,
|
||||
LocalisationService localisationService,
|
||||
ItemFilterService itemFilterService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Is item valid / on blacklist / quest item
|
||||
/// </summary>
|
||||
/// <param name="itemDetails"></param>
|
||||
/// <returns>boolean</returns>
|
||||
public bool IsItemValidRagfairItem(bool[] itemDetails)
|
||||
protected RagfairConfig ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
protected QuestConfig questConfig = configServer.GetConfig<QuestConfig>();
|
||||
protected static string goodsReturnedTemplate = "5bdabfe486f7743e1665df6e 0"; // Your item was not sold
|
||||
|
||||
/**
|
||||
* Is item valid / on blacklist / quest item
|
||||
* @param itemDetails
|
||||
* @returns boolean
|
||||
*/
|
||||
public bool IsItemValidRagfairItem(KeyValuePair<bool, TemplateItem?> itemDetails)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var blacklistConfig = ragfairConfig.Dynamic.Blacklist;
|
||||
|
||||
// Skip invalid items
|
||||
if (!itemDetails.Key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!itemHelper.IsValidItem(itemDetails.Value.Id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip bsg blacklisted items
|
||||
if (blacklistConfig.EnableBsgList && !(itemDetails.Value?.Properties?.CanSellOnRagfair ?? false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip custom blacklisted items and flag as unsellable by players
|
||||
if (IsItemOnCustomFleaBlacklist(itemDetails.Value.Id)) {
|
||||
itemDetails.Value.Properties.CanSellOnRagfair = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip custom category blacklisted items
|
||||
if (
|
||||
blacklistConfig.EnableCustomItemCategoryList &&
|
||||
IsItemCategoryOnCustomFleaBlacklist(itemDetails.Value.Parent)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip quest items
|
||||
if (blacklistConfig.EnableQuestList && itemHelper.IsQuestItem(itemDetails.Value.Id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't include damaged ammo packs
|
||||
if (
|
||||
ragfairConfig.Dynamic.Blacklist.DamagedAmmoPacks &&
|
||||
itemDetails.Value.Parent == BaseClasses.AMMO_BOX &&
|
||||
itemDetails[1]._name.includes("_damaged")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is supplied item tpl on the ragfair custom blacklist from configs/ragfair.json/dynamic
|
||||
/// </summary>
|
||||
/// <param name="itemTemplateId">Item tpl to check is blacklisted</param>
|
||||
/// <returns>True if its blacklsited</returns>
|
||||
protected bool IsItemOnCustomFleaBlacklist(string itemTemplateId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Is supplied item tpl on the ragfair custom blacklist from configs/ragfair.json/dynamic
|
||||
* @param itemTemplateId Item tpl to check is blacklisted
|
||||
* @returns True if its blacklsited
|
||||
*/
|
||||
protected isItemOnCustomFleaBlacklist(itemTemplateId: string): boolean {
|
||||
return ragfairConfig.dynamic.blacklist.custom.includes(itemTemplateId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is supplied parent id on the ragfair custom item category blacklist
|
||||
/// </summary>
|
||||
/// <param name="parentId">Parent Id to check is blacklisted</param>
|
||||
/// <returns>true if blacklisted</returns>
|
||||
protected bool IsItemCategoryOnCustomFleaBlacklist(string itemParentId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Is supplied parent id on the ragfair custom item category blacklist
|
||||
* @param parentId Parent Id to check is blacklisted
|
||||
* @returns true if blacklisted
|
||||
*/
|
||||
protected isItemCategoryOnCustomFleaBlacklist(itemParentId: string): boolean {
|
||||
return ragfairConfig.dynamic.blacklist.customItemCategoryList.includes(itemParentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// is supplied id a trader
|
||||
/// </summary>
|
||||
/// <param name="traderId"></param>
|
||||
/// <returns>True if id was a trader</returns>
|
||||
public bool IsTrader(string traderId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* is supplied id a trader
|
||||
* @param traderId
|
||||
* @returns True if id was a trader
|
||||
*/
|
||||
public isTrader(traderId: string): boolean {
|
||||
return traderId in databaseService.getTraders();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send items back to player
|
||||
/// </summary>
|
||||
/// <param name="sessionID">Player to send items to</param>
|
||||
/// <param name="returnedItems">Items to send to player</param>
|
||||
public void ReturnItems(string sessionID, List<Item> returnedItems)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Send items back to player
|
||||
* @param sessionID Player to send items to
|
||||
* @param returnedItems Items to send to player
|
||||
*/
|
||||
public returnItems(sessionID: string, returnedItems: IItem[]): void {
|
||||
mailSendService.sendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
traderHelper.getTraderById(Traders.RAGMAN),
|
||||
MessageType.MESSAGE_WITH_ITEMS,
|
||||
RagfairServerHelper.goodsReturnedTemplate,
|
||||
returnedItems,
|
||||
timeUtil.getHoursAsSeconds(
|
||||
databaseService.getGlobals().config.RagFair.yourOfferDidNotSellMaxStorageTimeInHour,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public int CalculateDynamicStackCount(string tplId, bool isWeaponPreset)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
public calculateDynamicStackCount(tplId: string, isWeaponPreset: boolean): number {
|
||||
var config = ragfairConfig.dynamic;
|
||||
|
||||
// Lookup item details - check if item not found
|
||||
var itemDetails = itemHelper.getItem(tplId);
|
||||
if (!itemDetails[0]) {
|
||||
throw new JSType.Error(
|
||||
localisationService.getText(
|
||||
"ragfair-item_not_in_db_unable_to_generate_dynamic_stack_count",
|
||||
tplId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Item Types to return one of
|
||||
if (
|
||||
isWeaponPreset ||
|
||||
itemHelper.isOfBaseclasses(itemDetails[1]._id, ragfairConfig.dynamic.showAsSingleStack)
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get max stack count
|
||||
var maxStackCount = itemDetails[1]._props.StackMaxSize;
|
||||
|
||||
// non-stackable - use different values to calculate stack size
|
||||
if (!maxStackCount || maxStackCount === 1) {
|
||||
return Math.round(randomUtil.getInt(config.nonStackableCount.min, config.nonStackableCount.max));
|
||||
}
|
||||
|
||||
var stackPercent = Math.round(
|
||||
randomUtil.getInt(config.stackablePercent.min, config.stackablePercent.max),
|
||||
);
|
||||
|
||||
return Math.round((maxStackCount / 100) * stackPercent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Choose a currency at random with bias
|
||||
/// </summary>
|
||||
/// <returns>currency tpl</returns>
|
||||
public string GetDynamicOfferCurrency()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Choose a currency at random with bias
|
||||
* @returns currency tpl
|
||||
*/
|
||||
public getDynamicOfferCurrency(): string {
|
||||
var currencies = ragfairConfig.dynamic.currencies;
|
||||
var bias: string[] = [];
|
||||
|
||||
for (var item in currencies) {
|
||||
for (let i = 0; i < currencies[item]; i++) {
|
||||
bias.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return bias[Math.floor(Math.random() * bias.length)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a preset id from globals.json, return a list of items with unique ids
|
||||
/// </summary>
|
||||
/// <param name="item">Preset item</param>
|
||||
/// <returns>List of weapon and its children</returns>
|
||||
public List<Item> GetPresetItems(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Given a preset id from globals.json, return an array of items[] with unique ids
|
||||
* @param item Preset item
|
||||
* @returns Array of weapon and its children
|
||||
*/
|
||||
public getPresetItems(item: IItem): IItem[] {
|
||||
var preset = cloner.clone(databaseService.getGlobals().ItemPresets[item._id]._items);
|
||||
return itemHelper.reparentItemAndChildren(item, preset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Possible bug, returns all items associated with an items tpl, could be multiple presets from globals.json
|
||||
/// </summary>
|
||||
/// <param name="item">Preset item</param>
|
||||
/// <returns></returns>
|
||||
public List<Item> GetPresetItemsByTpl(Item item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
* Possible bug, returns all items associated with an items tpl, could be multiple presets from globals.json
|
||||
* @param item Preset item
|
||||
* @returns
|
||||
*/
|
||||
public getPresetItemsByTpl(item: IItem): IItem[] {
|
||||
var presets = [];
|
||||
for (var itemId in databaseService.getGlobals().ItemPresets) {
|
||||
if (databaseService.getGlobals().ItemPresets[itemId]._items[0]._tpl === item._tpl) {
|
||||
var presetItems = cloner.clone(databaseService.getGlobals().ItemPresets[itemId]._items);
|
||||
presets.push(itemHelper.reparentItemAndChildren(item, presetItems));
|
||||
}
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ public record BarterScheme
|
||||
public bool? SptQuestLocked { get; set; }
|
||||
|
||||
[JsonPropertyName("level")]
|
||||
public double? Level { get; set; }
|
||||
public int? Level { get; set; }
|
||||
|
||||
[JsonPropertyName("side")]
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
|
||||
@@ -26,7 +26,7 @@ public record RagfairOffer
|
||||
|
||||
/** Handbook price */
|
||||
[JsonPropertyName("itemsCost")]
|
||||
public decimal? ItemsCost { get; set; }
|
||||
public double? ItemsCost { get; set; }
|
||||
|
||||
/** Rouble price per item */
|
||||
[JsonPropertyName("requirementsCost")]
|
||||
@@ -72,7 +72,7 @@ public record OfferRequirement
|
||||
public string? Template { get; set; }
|
||||
|
||||
[JsonPropertyName("count")]
|
||||
public int? Count { get; set; }
|
||||
public double? Count { get; set; }
|
||||
|
||||
[JsonPropertyName("onlyFunctional")]
|
||||
public bool? OnlyFunctional { get; set; }
|
||||
@@ -93,7 +93,7 @@ public record RagfairOfferUser
|
||||
public string? Nickname { get; set; }
|
||||
|
||||
[JsonPropertyName("rating")]
|
||||
public decimal? Rating { get; set; }
|
||||
public double? Rating { get; set; }
|
||||
|
||||
[JsonPropertyName("memberType")]
|
||||
public MemberCategory? MemberType { get; set; }
|
||||
|
||||
@@ -9,5 +9,5 @@ public record TplWithFleaPrice
|
||||
|
||||
// Roubles
|
||||
[JsonPropertyName("price")]
|
||||
public decimal? Price { get; set; }
|
||||
public double? Price { get; set; }
|
||||
}
|
||||
|
||||
@@ -1222,7 +1222,7 @@ public class FenceService(
|
||||
foreach (var plateSlot in plateSlots)
|
||||
{
|
||||
var plateTpl = plateSlot.Props.Filters[0].Plate;
|
||||
if (plateTpl == null)
|
||||
if (string.IsNullOrEmpty(plateTpl))
|
||||
{
|
||||
// Bsg data lacks a default plate, skip randomisng for this mod
|
||||
continue;
|
||||
@@ -1233,13 +1233,11 @@ public class FenceService(
|
||||
var modItemDbDetails = itemHelper.GetItem(plateTpl).Value;
|
||||
|
||||
// Chance to remove plate
|
||||
var plateExistsChance =
|
||||
traderConfig.Fence.ChancePlateExistsInArmorPercent[
|
||||
modItemDbDetails?.Properties?.ArmorClass?.ToString() ?? "3"];
|
||||
var plateExistsChance = traderConfig.Fence.ChancePlateExistsInArmorPercent[modItemDbDetails?.Properties?.ArmorClass?.ToString() ?? "3"];
|
||||
if (!randomUtil.GetChance100(plateExistsChance))
|
||||
{
|
||||
// Remove plate from armor
|
||||
armorWithMods = armorItemAndMods.Where(item => item.SlotId.ToLower() != plateSlot.Name.ToLower())
|
||||
armorItemAndMods = armorItemAndMods.Where(item => item.SlotId.ToLower() != plateSlot.Name.ToLower())
|
||||
.ToList();
|
||||
|
||||
continue;
|
||||
|
||||
@@ -175,7 +175,7 @@ public class PaymentService(
|
||||
if (item.Upd.StackObjectsCount < currencyMaxStackSize) {
|
||||
if (item.Upd.StackObjectsCount + calcAmount > currencyMaxStackSize) {
|
||||
// calculate difference
|
||||
calcAmount -= (currencyMaxStackSize - item.Upd.StackObjectsCount) ?? 0;
|
||||
calcAmount -= (int) ((currencyMaxStackSize - item.Upd.StackObjectsCount) ?? 0);
|
||||
item.Upd.StackObjectsCount = currencyMaxStackSize;
|
||||
} else {
|
||||
skipSendingMoneyToStash = true;
|
||||
@@ -195,7 +195,7 @@ public class PaymentService(
|
||||
Item rootCurrencyReward = new Item {
|
||||
Id = _hashUtil.Generate(),
|
||||
Template = currencyTpl,
|
||||
Upd = new Upd { StackObjectsCount = Math.Round(calcAmount) },
|
||||
Upd = new Upd { StackObjectsCount = Math.Round((double) calcAmount) }
|
||||
};
|
||||
|
||||
// Ensure money is properly split to follow its max stack size limit
|
||||
|
||||
@@ -13,9 +13,9 @@ public class RagfairOfferHolder(
|
||||
ConfigServer configServer)
|
||||
{
|
||||
|
||||
protected Dictionary<string, RagfairOffer> _offersById;
|
||||
protected Dictionary<string, Dictionary<string, RagfairOffer>> _offersByTemplate;
|
||||
protected Dictionary<string, Dictionary<string, RagfairOffer>> _offersByTrader;
|
||||
protected Dictionary<string, RagfairOffer> _offersById = new();
|
||||
protected Dictionary<string, Dictionary<string, RagfairOffer>> _offersByTemplate = new();
|
||||
protected Dictionary<string, Dictionary<string, RagfairOffer>> _offersByTrader = new();
|
||||
protected int _maxOffersPerTemplate = (int) configServer.GetConfig<RagfairConfig>().Dynamic.OfferItemCount.Max;
|
||||
|
||||
public RagfairOffer? GetOfferById(string id)
|
||||
|
||||
@@ -55,6 +55,7 @@ public class RandomUtil(ISptLogger<RandomUtil> _logger, ICloner _cloner)
|
||||
return (float)GetSecureRandomNumber() * (max - min) + min;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random floating-point number within the specified range ~15-17 digits (8 bytes).
|
||||
/// </summary>
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
"5a7c2eca46aef81a7ca2145d": true,
|
||||
"5ac3b934156ae10c4430e83c": true,
|
||||
"5c0647fdd443bc2504c2d371": true,
|
||||
"6617beeaa9cfa777ca915b7c": true,
|
||||
"ragfair": false
|
||||
"6617beeaa9cfa777ca915b7c": true
|
||||
},
|
||||
"dynamic": {
|
||||
"purchasesAreFoundInRaid": false,
|
||||
|
||||
Reference in New Issue
Block a user