This is related to modding the game, though is something that worked fine before 1.0. Many modders have made custom vending machines, or even faked a trader using a block setup using the VendingMachine class. But in 1.0 you will get an NRE if you try to sell to one of these vending machines. The error is:
2024-08-04T23:34:07 85.406 ERR [XUi] Error while updating window group 'backpack':
2024-08-04T23:34:07 85.409 EXC Object reference not set to an instance of an object
at ItemActionEntrySell.OnActivated () [0x0060e] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiC_ItemActionEntry.OnPressAction (XUiController _sender, System.Int32 _mouseButton) [0x00041] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.OnPressed (System.Int32 _mouseButton) [0x0000e] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.Pressed (System.Int32 _mouseButton) [0x00000] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiC_ItemActionList.Update (System.Single _dt) [0x001a7] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.Update (System.Single _dt) [0x00084] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.Update (System.Single _dt) [0x00084] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.Update (System.Single _dt) [0x00084] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiC_InfoWindow.Update (System.Single _dt) [0x00000] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiC_ItemInfoWindow.Update (System.Single _dt) [0x00000] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUiController.Update (System.Single _dt) [0x00084] in <40e9b6e9762f43cf836123d0f549ad32>:0
at XUi.OnUpdateDeltaTime (System.Single updateDeltaTime) [0x00159] in <40e9b6e9762f43cf836123d0f549ad32>:0
UnityEngine.StackTraceUtility:ExtractStringFromException(Object)
Log:Exception(Exception)
XUi:OnUpdateDeltaTime(Single)
XUiUpdater:Update()
XUiUpdateHelper:LateUpdate()
A fellow modder, IDC, looked into this and found that the game now assumes if you are selling items, you must be at a trader, since in vanilla that's really the only time you sell things. But this doesn't apply to mods of course. I know this won't be a priority but would be nice if it could get fixed in vanilla. IDC was kind enough to put together a small patch that sorts it, which looks like:
[HarmonyPatch(typeof(ItemActionEntrySell))] public class Patch_ItemActionEntrySell { [HarmonyTranspiler] [HarmonyPatch("OnActivated")] public static IEnumerable OnActivated(IEnumerable<CodeInstruction> instructions) { var codes = new List<CodeInstruction>(instructions); int start = 0, end = 0; for (int i = 0; i < codes.Count; i++) { start = i; if (!(codes[i].opcode == OpCodes.Call)) continue; if (!(codes[i].operand is MethodInfo methodInfo && methodInfo.Name == "get_Current")) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Ldarg_0)) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Call)) continue; if (!(codes[i].operand is MethodInfo methodInfo1 && methodInfo1.Name == "get_ItemController")) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Callvirt)) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Ldfld)) continue; if (!(codes[i].operand is FieldInfo fi && fi.Name == "Trader")) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Ldfld)) continue; if (!(codes[i].operand is FieldInfo fi1 && fi1.Name == "TraderEntity")) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Callvirt)) continue; if (!(codes[i].operand is MethodInfo methodInfo2 && methodInfo2.Name == "get_EntityName")) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Ldloc_S)) continue; if (++i >= codes.Count) break; if (!(codes[i].opcode == OpCodes.Callvirt)) continue; if (!(codes[i].operand is MethodInfo methodInfo3 && methodInfo3.Name == "SoldItems")) continue; if (++i >= codes.Count) break; end = i; codes[start].opcode = OpCodes.Nop; //NOP this one because its the target of a branch. codes.RemoveRange(start + 1, (end - start) - 1); codes.Insert(++start, new CodeInstruction(OpCodes.Ldarg_0)); codes.Insert(++start, new CodeInstruction(OpCodes.Ldloc, 13)); codes.Insert(++start, new CodeInstruction(OpCodes.Callvirt, AccessTools.Method("Patch_ItemActionEntrySell:CountSoldItem"))); Log.Out("[IDCSellingFix] Patching done"); } return codes; } public static void CountSoldItem(ItemActionEntrySell __instance, int count) { if (__instance.ItemController.xui.Trader.TraderEntity != null && __instance.ItemController.xui.Trader.TraderEntity.EntityName != null) { QuestEventManager.Current.SoldItems(__instance.ItemController.xui.Trader.TraderEntity.EntityName, count); } } }
So it isn't a terribly difficult fix. The issue of course with his fix is it means you need a dll included with your mod, with means it is no longer EAC compatible. Not an issue for some, but it is for quite a few. So again, I understand it isn't a vanilla issue, but if someone could give it a look when time permits and see if it can be fixed, that would be great. Thanks.
Oh, and since it says a log is required: https://pastebin.com/8E2ivdWe
Recommended Comments