diff --git a/Mods/0-SCore/0-SCore.csproj b/Mods/0-SCore/0-SCore.csproj
index 0e2f092d..1885f088 100644
--- a/Mods/0-SCore/0-SCore.csproj
+++ b/Mods/0-SCore/0-SCore.csproj
@@ -203,6 +203,7 @@
+
diff --git a/Mods/0-SCore/Config/Localization.txt b/Mods/0-SCore/Config/Localization.txt
index 591b1dac..96a67020 100644
--- a/Mods/0-SCore/Config/Localization.txt
+++ b/Mods/0-SCore/Config/Localization.txt
@@ -117,4 +117,5 @@ xuiSCoreUtilsDisableFlickeringLightsToolTip,"Disables Flickering Lights.",""
xuiPersonalSettings,"Personal Settings",""
xuiSCoreUtilsAutoRedeemChallenges,"Auto Redeem Challenges",""
xuiSCoreUtilsAutoRedeemChallengesToolTip,"Auto Redeem Challenges as they complete.",""
-ObjectiveBuffSDX_keyword,"Get",""
\ No newline at end of file
+ObjectiveBuffSDX_keyword,"Get",""
+ItemCannotBePlaced,"This item cannot go into this slot.",""
\ No newline at end of file
diff --git a/Mods/0-SCore/Harmony/SphereIICore_Init.cs b/Mods/0-SCore/Harmony/SphereIICore_Init.cs
index cc8bb37f..4c9372fe 100644
--- a/Mods/0-SCore/Harmony/SphereIICore_Init.cs
+++ b/Mods/0-SCore/Harmony/SphereIICore_Init.cs
@@ -11,8 +11,8 @@ public void InitMod(Mod _modInstance)
Log.Out(" Loading Patch: " + GetType());
// Reduce extra logging stuff
- Application.SetStackTraceLogType(UnityEngine.LogType.Log, StackTraceLogType.None);
- Application.SetStackTraceLogType(UnityEngine.LogType.Warning, StackTraceLogType.None);
+ // Application.SetStackTraceLogType(UnityEngine.LogType.Log, StackTraceLogType.None);
+ // Application.SetStackTraceLogType(UnityEngine.LogType.Warning, StackTraceLogType.None);
var harmony = new HarmonyLib.Harmony(GetType().ToString());
diff --git a/Mods/0-SCore/Harmony/XUIC/XUiC_ItemStack_SlotTags.cs b/Mods/0-SCore/Harmony/XUIC/XUiC_ItemStack_SlotTags.cs
new file mode 100644
index 00000000..566f3b29
--- /dev/null
+++ b/Mods/0-SCore/Harmony/XUIC/XUiC_ItemStack_SlotTags.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Audio;
+using HarmonyLib;
+using UnityEngine;
+
+namespace SCore.Harmony.TileEntities {
+ public class CheckItemsForContainers {
+ private static bool IsStackAllowedInContainer(XUiC_ItemStack itemStack) {
+ switch (itemStack.StackLocation)
+ {
+ case XUiC_ItemStack.StackLocationTypes.Backpack:
+ case XUiC_ItemStack.StackLocationTypes.ToolBelt:
+ return true;
+ }
+
+ var currentStack = itemStack.xui.dragAndDrop?.CurrentStack;
+ if (currentStack == null || currentStack.IsEmpty()) return true;
+
+ // Only run on loot containers and their slots.
+ if (itemStack.xui.lootContainer == null) return true;
+ if (itemStack.StackLocation != XUiC_ItemStack.StackLocationTypes.LootContainer) return true;
+
+ var block = itemStack.xui.lootContainer.blockValue.Block;
+ return CanPlaceItemInContainerViaTags(block, currentStack, true);
+ }
+ private static bool CanPlaceItemInContainerViaTags(Block block, ItemStack itemStack, bool showToolTip = false) {
+
+ // If the tags don't exist, skip all the checks.
+ if (!block.Properties.Contains("AllowTags") && !block.Properties.Contains("DisallowTags")) return true;
+
+ var all = FastTags.Parse("all");
+ if (block.Properties.Contains("AllowTags"))
+ {
+ var allowedTags = FastTags.Parse(block.Properties.GetString("AllowTags"));
+ if (allowedTags.Test_AnySet(all)) return true;
+ if (itemStack.itemValue.ItemClass.HasAnyTags(allowedTags)) return true;
+ }
+
+ if (block.Properties.Contains("DisallowTags"))
+ {
+ var blockedTags = FastTags.Parse(block.Properties.GetString("DisallowTags"));
+ if (!itemStack.itemValue.ItemClass.HasAnyTags(blockedTags)) return true;
+ }
+
+
+ if (!showToolTip) return false;
+ var message = Localization.Get("ItemCannotBePlaced");
+ if (block.Properties.Contains("DisallowedKey"))
+ {
+ message = Localization.Get(block.Properties.GetString("DisallowedKey"));
+ }
+ if (itemStack.itemValue.ItemClass.Properties.Contains("DisallowedKey"))
+ {
+ message = Localization.Get(itemStack.itemValue.ItemClass.Properties.GetString("DisallowedKey"));
+ }
+ Manager.PlayInsidePlayerHead("ui_denied");
+ var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
+ XUiC_PopupToolTip.ClearTooltips(primaryPlayer.playerUI.xui);
+ GameManager.ShowTooltip(primaryPlayer, message);
+ return false;
+ }
+
+ // For clicking and sending objects to the toolbelt/backpack/loot container
+ public class TEFeatureStoragePatch {
+ [HarmonyPatch(typeof(TEFeatureStorage))]
+ [HarmonyPatch("TryStackItem")]
+ public class TEFeatureStorageTryStackItem {
+ public static bool Prefix(TEFeatureStorage __instance, ItemStack _itemStack) {
+ if (__instance is ITileEntityLootable tileEntityLootable)
+ return CanPlaceItemInContainerViaTags(tileEntityLootable.blockValue.Block, _itemStack);
+ return true;
+ }
+ }
+
+ [HarmonyPatch(typeof(TEFeatureStorage))]
+ [HarmonyPatch("AddItem")]
+ public class TEFeatureStorageAddItem {
+ public static bool Prefix(TEFeatureStorage __instance, ItemStack _itemStack) {
+ if (__instance is ITileEntityLootable tileEntityLootable)
+ return CanPlaceItemInContainerViaTags(tileEntityLootable.blockValue.Block, _itemStack);
+ return true;
+
+ }
+ }
+ }
+
+ // For other methods, such as automatic stashing, dragging and dropping, etc.
+ [HarmonyPatch]
+ public class XUiC_ItemStack_SlotTags {
+ [HarmonyTargetMethod]
+ static IEnumerable TargetMethods() {
+ yield return typeof(XUiC_ItemStack).GetMethod("CanSwap");
+ yield return typeof(XUiC_ItemStack).GetMethod("ForceSetItemStack");
+ yield return typeof(XUiC_ItemStack).GetMethod("HandleDropOne");
+ yield return typeof(XUiC_ItemStack).GetMethod("HandleMoveToPreferredLocation");
+ yield return typeof(XUiC_ItemStack).GetMethod("HandlePartialStackPickup");
+ yield return typeof(XUiC_ItemStack).GetMethod("HandleStackSwap");
+ yield return typeof(XUiC_ItemStack).GetMethod("SwapItem");
+ }
+
+ public static bool Prefix(XUiC_ItemStack __instance) {
+ return IsStackAllowedInContainer(__instance);
+ }
+ }
+
+
+ public class XUICLootContainerCheckItemsForContainers {
+ [HarmonyPatch(typeof(XUiC_LootWindow))]
+ [HarmonyPatch("SetTileEntityChest")]
+ public class XUiCLootWindowSetTileEntityChest {
+ public static void Postfix(XUiC_LootWindow __instance, string _lootContainerName) {
+ if (__instance.te == null) return;
+
+ var block = __instance.te.blockValue.Block;
+ if (block.Properties.Contains("AllowTags"))
+ {
+ var display = block.Properties.GetString("AllowTags");
+ __instance.lootContainerName = $"{_lootContainerName} ( Tag Limited: {display} )";
+ __instance.RefreshBindings(true);
+ return;
+ }
+ if (block.Properties.Contains("DisallowTags"))
+ {
+ var display = block.Properties.GetString("DisallowTags");
+ __instance.lootContainerName = $"{_lootContainerName} ( Blocked Tags: {display} )";
+ __instance.RefreshBindings(true);
+ }
+
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Mods/0-SCore/ModInfo.xml b/Mods/0-SCore/ModInfo.xml
index e8e023df..f36aa096 100644
--- a/Mods/0-SCore/ModInfo.xml
+++ b/Mods/0-SCore/ModInfo.xml
@@ -5,5 +5,5 @@
-
+
\ No newline at end of file
diff --git a/Mods/0-SCore/Properties/AssemblyInfo.cs b/Mods/0-SCore/Properties/AssemblyInfo.cs
index 0679db39..1f37b226 100644
--- a/Mods/0-SCore/Properties/AssemblyInfo.cs
+++ b/Mods/0-SCore/Properties/AssemblyInfo.cs
@@ -38,5 +38,5 @@
// [assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("20.0.*")]
-[assembly: AssemblyVersion("1.0.43.1207")]
-[assembly: AssemblyFileVersion("1.0.43.1207")]
+[assembly: AssemblyVersion("1.0.44.1602")]
+[assembly: AssemblyFileVersion("1.0.44.1602")]
diff --git a/Mods/0-SCore/ReadMe.md b/Mods/0-SCore/ReadMe.md
index 1172e838..b1d55d41 100644
--- a/Mods/0-SCore/ReadMe.md
+++ b/Mods/0-SCore/ReadMe.md
@@ -23,6 +23,39 @@ Direct Download to the 0-SCore.zip available on gitlab mirror:
### Change Logs
[ Change Log ]
+Version: 1.0.44.1602
+ [ Check Items For Valid Containers]
+ - Introduced a new feature through a series of Harmony patches that allows you to filter items from storage containers.
+ - Allows you to filter items being added to any given Loot Container based on tags.
+ - A container with the AllowTags set to "all", will allow all items.
+ - A container with no AllowTags or DisallowTags will not be checked at all, and act normally.
+
+ - If a loot container has the following property, then it will only allow items that have those tags to be stored.
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ - If an item is blocked, a denied UI sound will be triggered.
+ - If an item is dragged and dropped in a blocked container, a tooltip will also display.
+ - Shift clicking on an item to move it will play the denied UI.
+
+ - If a block has the following Property, this will be used to check for localization and display a custom blocked message.
+
+ - This property can also exist on the Item entry as well, and will over-ride the block's message, if it's set.
+ - If not otherwise set, the default localization entry will be displayed.
+
Version: 1.0.43.1207
[ Fire Manager ]
- Removed the DynamicMeshChunk update, which was likely needless, and likely caused a performance issue.
diff --git a/Mods/0-SCore/SCore.dll b/Mods/0-SCore/SCore.dll
index 43fc524f..bc74adf3 100644
Binary files a/Mods/0-SCore/SCore.dll and b/Mods/0-SCore/SCore.dll differ
diff --git a/Mods/0-SCore/SCore.pdb b/Mods/0-SCore/SCore.pdb
index 7e998455..87ca7ae6 100644
Binary files a/Mods/0-SCore/SCore.pdb and b/Mods/0-SCore/SCore.pdb differ
diff --git a/Mods/0-SCore/Scripts/Quests/ObjectiveBuffSDX.cs b/Mods/0-SCore/Scripts/Quests/ObjectiveBuffSDX.cs
index 17cfea0d..7401f0c0 100644
--- a/Mods/0-SCore/Scripts/Quests/ObjectiveBuffSDX.cs
+++ b/Mods/0-SCore/Scripts/Quests/ObjectiveBuffSDX.cs
@@ -1,7 +1,7 @@
using System;
using UnityEngine;
-internal class ObjectiveBuffSDX : BaseObjective
+public class ObjectiveBuffSDX : BaseObjective
{
private string strBuff = "";