diff --git a/ChestPreview/ChestPreview/PreviewTargetProvider.cs b/ChestPreview/ChestPreview/PreviewTargetProvider.cs
index b800330..acd9dd0 100644
--- a/ChestPreview/ChestPreview/PreviewTargetProvider.cs
+++ b/ChestPreview/ChestPreview/PreviewTargetProvider.cs
@@ -242,7 +242,7 @@ internal partial class PreviewTargetProvider(ICoreClientAPI api, Config config)
if (player == null || playerEntity == null)
return false;
- return inventory.CanPlayerAccess(player, playerEntity.Pos);
+ return inventory.CanPlayerAccess(player, playerEntity.GetPos());
}
private bool IsContainerAllowed(Block block)
diff --git a/ChestPreview/ChestPreview/Rendering/CardRenderer.cs b/ChestPreview/ChestPreview/Rendering/CardRenderer.cs
index 0ec04e8..3f557a7 100644
--- a/ChestPreview/ChestPreview/Rendering/CardRenderer.cs
+++ b/ChestPreview/ChestPreview/Rendering/CardRenderer.cs
@@ -1,6 +1,7 @@
using Cairo;
using ChestPreview.Configs;
using ChestPreview.Models;
+using ChestPreview.Utils;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -50,7 +51,7 @@ internal class CardRenderer(ICoreClientAPI api, Config config) : IDisposable
IPlayer? player = api.World.Player;
EntityPlayer? playerEntity = player?.Entity;
- if (player == null || playerEntity == null || !inventory.CanPlayerAccess(player, playerEntity.Pos))
+ if (player == null || playerEntity == null || !inventory.CanPlayerAccess(player, playerEntity.GetPos()))
return false;
string targetKey = CreateTargetKey(target.BlockEntity.Pos);
diff --git a/ChestPreview/ChestPreview/Utils/CompatibilityUtil.cs b/ChestPreview/ChestPreview/Utils/CompatibilityUtil.cs
new file mode 100644
index 0000000..f08fbbe
--- /dev/null
+++ b/ChestPreview/ChestPreview/Utils/CompatibilityUtil.cs
@@ -0,0 +1,55 @@
+using System;
+using Vintagestory.API.Common.Entities;
+
+namespace ChestPreview.Utils;
+
+///
+/// When the mod is built for 1.21, and then you run it with 1.22, this happens when referring to Entity.Pos,
+/// which was changed from a field to a property (and that being the reason this happens):
+///
+/// System.MissingFieldException: Field not found: 'Vintagestory.API.Common.Entities.Entity.Pos'.
+/// at MonoMod.Core.Interop.CoreCLR.V60.InvokeCompileMethod(IntPtr functionPtr, IntPtr thisPtr, IntPtr corJitInfo, CORINFO_METHOD_INFO* methodInfo, UInt32 flags, Byte** nativeEntry, UInt32* nativeSizeOfCode)
+/// at MonoMod.Core.Platforms.Runtimes.Core60Runtime.JitHookDelegateHolder.CompileMethodHook(IntPtr jit, IntPtr corJitInfo, CORINFO_METHOD_INFO* methodInfo, UInt32 flags, Byte** nativeEntry, UInt32* nativeSizeOfCode)
+/// at ChestPreview.PreviewTargetProvider.CanAccessContainer(BlockEntity blockEntity) in E:\Code\VintageStory\ChestPreview\ChestPreview\ChestPreview\PreviewTargetProvider.cs:line 237
+///
+/// the PreviewTargetProvider.cs: around line 237 looks like this:
+///
+/// private bool CanAccessContainer(BlockEntity blockEntity)
+/// {
+/// if (blockEntity is not IBlockEntityContainer container || container.Inventory is not InventoryBase inventory)
+/// return false;
+///
+/// IPlayer? player = api.World.Player;
+/// EntityPlayer? playerEntity = player?.Entity;
+/// if (player == null || playerEntity == null)
+/// return false;
+///
+/// return inventory.CanPlayerAccess(player, playerEntity.Pos);
+/// }
+///
+/// it happens because of the last line where we refer to "playerEntity.Pos" - this field doesn't exist now, because it's a property.
+///
+/// This class uses reflection to refer to either the property, or the field, whichever actually exists.
+///
+internal static class CompatibilityUtil
+{
+#if !VERSION22
+ private static Func? _getPos;
+
+ private static Func GetPosFunc => _getPos ??= BuildGetPos();
+
+ private static Func BuildGetPos()
+ {
+ var prop = typeof(Entity).GetProperty("Pos");
+ if (prop != null)
+ return (Func)Delegate.CreateDelegate(typeof(Func), prop.GetGetMethod()!);
+
+ var field = typeof(Entity).GetField("Pos")!;
+ return entity => (EntityPos)field.GetValue(entity)!;
+ }
+
+ public static EntityPos GetPos(this Entity entity) => GetPosFunc(entity);
+#else
+ public static EntityPos GetPos(this Entity entity) => entity.Pos;
+#endif
+}
\ No newline at end of file