diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs
index 7170823f..3a7f6660 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs
@@ -323,7 +323,7 @@ public class ItemHelper(
/// is the tpl a descendant
public bool IsOfBaseclass(MongoId tpl, MongoId baseClassTpl)
{
- return itemBaseClassService.ItemHasBaseClass(tpl, [baseClassTpl]);
+ return itemBaseClassService.ItemHasBaseClass(tpl, baseClassTpl);
}
///
diff --git a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
index 11fd6eef..568b123e 100644
--- a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
@@ -17,8 +17,12 @@ public class ItemBaseClassService(
)
{
private bool _cacheGenerated;
+
+ ///
+ /// Key = Item tpl, values = Ids of its parents
+ ///
private Dictionary> _itemBaseClassesCache = [];
- private HashSet rootNodeIds = [];
+ private readonly HashSet _rootNodeIds = [];
///
/// Create cache and store inside ItemBaseClassService
@@ -44,7 +48,7 @@ public class ItemBaseClassService(
}
else
{
- rootNodeIds.Add(item.Key);
+ _rootNodeIds.Add(item.Key);
}
}
@@ -89,7 +93,7 @@ public class ItemBaseClassService(
// The cache is only generated for item templates with `_type == "Item"`, so return false for any other type,
// including item templates that simply don't exist.
- if (rootNodeIds.Contains(itemTpl))
+ if (_rootNodeIds.Contains(itemTpl))
{
return false;
}
@@ -123,12 +127,68 @@ public class ItemBaseClassService(
return false;
}
+ ///
+ /// Does item tpl inherit from the requested base class
+ ///
+ /// ItemTpl item to check base classes of
+ /// BaseClass base class to check for
+ /// true if item inherits from base class passed in
+ public bool ItemHasBaseClass(MongoId itemTpl, MongoId baseClasses)
+ {
+ if (!_cacheGenerated)
+ {
+ HydrateItemBaseClassCache();
+ }
+
+ if (itemTpl.IsEmpty())
+ {
+ logger.Warning("Unable to check itemTpl base class as value passed is null");
+
+ return false;
+ }
+
+ // The cache is only generated for item templates with `_type == "Item"`, so return false for any other type,
+ // including item templates that simply don't exist.
+ if (_rootNodeIds.Contains(itemTpl))
+ {
+ return false;
+ }
+
+ var existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out var baseClassList);
+ if (!existsInCache)
+ {
+ // Not found
+ if (logger.IsLogEnabled(LogLevel.Debug))
+ {
+ logger.Debug(
+ serverLocalisationService.GetText("baseclass-item_not_found", itemTpl)
+ );
+ }
+
+ // Not found in cache, Hydrate again - some mods add items late in server startup lifecycle
+ HydrateItemBaseClassCache();
+
+ existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList);
+ }
+
+ if (existsInCache)
+ {
+ return baseClassList.Contains(baseClasses);
+ }
+
+ logger.Warning(
+ serverLocalisationService.GetText("baseclass-item_not_found_failed", itemTpl)
+ );
+
+ return false;
+ }
+
///
/// Get base classes item inherits from
///
/// ItemTpl item to get base classes for
/// array of base classes
- public List GetItemBaseClasses(MongoId itemTpl)
+ public HashSet GetItemBaseClasses(MongoId itemTpl)
{
if (!_cacheGenerated)
{
@@ -140,6 +200,6 @@ public class ItemBaseClassService(
return [];
}
- return value.ToList();
+ return value;
}
}