KaiserKatze Posted February 3, 2019 Share Posted February 3, 2019 I try to port Iron, Alloy and Smelter from Don't Starve to Don't Starve Together. The version v1.0.7 of my mod works fine. But my subscriber said the game crashes when the Smelter is opened (error report can be found here). I took a look and determined that maybe my mod is not compatible with some other mod because I overrode `scripts/containers.lua`: -- https://github.com/WayOfModding/DST-Mod-Hamlet-Ironmaking/blob/master/scripts/containers.lua#L157 -------------------------------------------------------------------------- --[[ smelter ]] -------------------------------------------------------------------------- params.smelter = { widget = { slotpos = { Vector3(0, 64 + 32 + 8 + 4, 0), Vector3(0, 32 + 4, 0), Vector3(0, -(32 + 4), 0), Vector3(0, -(64 + 32 + 8 + 4), 0), }, animbank = "ui_cookpot_1x4", animbuild = "ui_cookpot_1x4", pos = Vector3(200, 0, 0), side_align_tip = 100, buttoninfo = { text = STRINGS.ACTIONS.SMELT, position = Vector3(0, -165, 0), } }, acceptsstacks = false, type = "cooker", } function params.smelter.itemtestfn(container, item, slot) return not container.inst:HasTag("burnt") and item.prefab == "iron" end function params.smelter.widget.buttoninfo.fn(inst) print("KK-TEST> Button down: SMELT/COOK ...") if inst.components.container ~= nil then BufferedAction(inst.components.container.opener, inst, ACTIONS.COOK):Do() elseif inst.replica.container ~= nil and not inst.replica.container:IsBusy() then SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.COOK.code, inst, ACTIONS.COOK.mod_name) end end function params.smelter.widget.buttoninfo.validfn(inst) return inst.replica.container ~= nil and inst.replica.container:IsFull() end -- https://github.com/WayOfModding/DST-Mod-Hamlet-Ironmaking/blob/v1.0.7/scripts/prefabs/smelter.lua#L265 inst.components.container:WidgetSetup("smelter") To solve this problem, I removed `scripts/containers.lua` and modified `scripts/prefabs/smelter.lua`: -- https://github.com/WayOfModding/DST-Mod-Hamlet-Ironmaking/blob/v1.0.9/scripts/prefabs/smelter.lua#L15 -------------------------------------------------------------------------- --[[ smelter ]] -------------------------------------------------------------------------- local params = {} params.smelter = { widget = { slotpos = { Vector3(0, 64 + 32 + 8 + 4, 0), Vector3(0, 32 + 4, 0), Vector3(0, -(32 + 4), 0), Vector3(0, -(64 + 32 + 8 + 4), 0), }, animbank = "ui_cookpot_1x4", animbuild = "ui_cookpot_1x4", pos = Vector3(200, 0, 0), side_align_tip = 100, buttoninfo = { text = STRINGS.ACTIONS.SMELT, position = Vector3(0, -165, 0), } }, acceptsstacks = false, type = "cooker", } function params.smelter.itemtestfn(container, item, slot) return not container.inst:HasTag("burnt") and item.prefab == "iron" end function params.smelter.widget.buttoninfo.fn(inst) --print("KK-TEST> Button down: SMELT/COOK ...") if inst.components.container ~= nil then BufferedAction(inst.components.container.opener, inst, ACTIONS.COOK):Do() elseif inst.replica.container ~= nil and not inst.replica.container:IsBusy() then SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.COOK.code, inst, ACTIONS.COOK.mod_name) end end function params.smelter.widget.buttoninfo.validfn(inst) return inst.replica.container ~= nil and inst.replica.container:IsFull() end -- https://github.com/WayOfModding/DST-Mod-Hamlet-Ironmaking/blob/v1.0.9/scripts/prefabs/smelter.lua#L312 inst.components.container:WidgetSetup("smelter", params.smelter) This version v1.0.9 works okay when I host a game directly with Don't Starve Together (TheWorld.ismastersim == true). However, the game crashes (client side) when I host a game with Don't Starve Together Dedicated Server (TheWorld.ismastersim == false). The following is the error log: [00:02:57]: [string "scripts/widgets/containerwidget.lua"]:29: attempt to index local 'widget' (a nil value) LUA ERROR stack traceback: scripts/widgets/containerwidget.lua:29 in (method) Open (Lua) <24-143> self = callbacks = table: 638D0E10 slotsperrow = 3 inst = 102478 - (valid:true) focus = false children = table: 638D0DC0 focus_flow_args = table: 638D11A8 focus_target = false isopen = false owner = 100038 - wickerbottom (valid:true) open = false can_fade_alpha = true inv = table: 638D11D0 parent = name = Container bgimage = Image - : focus_flow = table: 638D1180 enabled = true bganim = UIAnim shown = true container = 101309 - smelter (valid:true) doer = 100038 - wickerbottom (valid:true) widget = nil scripts/screens/playerhud.lua:247 in (upvalue) OpenContainerWidget (Lua) <244-249> self = fireover = FireOver sandover = SandOver beefbloodover = BeefBloodOver parent = screenroot overlayroot = overlays storm_overlays = storm_overlays mindcontrolover = UIAnim enabled = true under_root = under_root eventannouncer = EventAnnouncer name = HUD focus_flow = table: 587B0290 bloodover = BloodOver storm_root = storm_root over_root = over_root callbacks = table: 587B0038 popupstats_root = popupstats_root sanddustover = UIAnim inst = 100039 - (valid:true) focus = true gogglesover = GogglesOver heatover = HeatOver focus_flow_args = table: 587B02B8 focus_target = false vig = UIAnim _StatusAnnouncer = table: 1DDC83C8 owner = 100038 - wickerbottom (valid:true) controls = Controls can_fade_alpha = true iceover = IceOver clouds = UIAnim is_screen = true fumeover = FumeOver shown = true handlers = table: 587B02E0 children = table: 587AFFE8 root = root container = 101309 - smelter (valid:true) side = false containerwidget = Container scripts/screens/playerhud.lua:257 in (method) OpenContainer (Lua) <251-259> self = fireover = FireOver sandover = SandOver beefbloodover = BeefBloodOver parent = screenroot overlayroot = overlays storm_overlays = storm_overlays mindcontrolover = UIAnim enabled = true under_root = under_root eventannouncer = EventAnnouncer name = HUD focus_flow = table: 587B0290 bloodover = BloodOver storm_root = storm_root over_root = over_root callbacks = table: 587B0038 popupstats_root = popupstats_root sanddustover = UIAnim inst = 100039 - (valid:true) focus = true gogglesover = GogglesOver heatover = HeatOver focus_flow_args = table: 587B02B8 focus_target = false vig = UIAnim _StatusAnnouncer = table: 1DDC83C8 owner = 100038 - wickerbottom (valid:true) controls = Controls can_fade_alpha = true iceover = IceOver clouds = UIAnim is_screen = true fumeover = FumeOver shown = true handlers = table: 587B02E0 children = table: 587AFFE8 root = root container = 101309 - smelter (valid:true) side = false scripts/components/container_replica.lua:289 in (method) Open (Lua) <275-296> self = __craftPotPatched = true ondetachclassified = function - scripts/components/container_replica.lua:106 acceptsstacks = true _numslots = 0 inst = 101309 - smelter (valid:true) issidewidget = false _cannotbeopened = net_bool (34CA64B8) classified = 102477 - container_classified (valid:true) _isopen = false doer = 100038 - wickerbottom (valid:true) scripts/components/container_replica.lua:95 in (field) fn (Lua) <87-101> inst = 101309 - smelter (valid:true) self = __craftPotPatched = true ondetachclassified = function - scripts/components/container_replica.lua:106 acceptsstacks = true [00:02:57]: [string "scripts/widgets/containerwidget.lua"]:29: attempt to index local 'widget' (a nil value) LUA ERROR stack traceback: scripts/widgets/containerwidget.lua:29 in (method) Open (Lua) <24-143> scripts/screens/playerhud.lua:247 in (upvalue) OpenContainerWidget (Lua) <244-249> scripts/screens/playerhud.lua:257 in (method) OpenContainer (Lua) <251-259> scripts/components/container_replica.lua:289 in (method) Open (Lua) <275-296> scripts/components/container_replica.lua:95 in (field) fn (Lua) <87-101> scripts/scheduler.lua:177 in (method) OnTick (Lua) <155-207> scripts/scheduler.lua:371 in (global) RunScheduler (Lua) <369-377> scripts/update.lua:170 in () ? (Lua) <149-228> [00:02:57]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is ScriptErrorWidget not a screen? [00:02:57]: stack traceback: scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624> scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658> scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119> scripts/update.lua:90 in () ? (Lua) <33-129> [00:02:58]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is ScriptErrorWidget not a screen? [00:02:58]: stack traceback: scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624> scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624> scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624> scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624> scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658> scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119> scripts/update.lua:90 in () ? (Lua) <33-129> [00:02:58]: Force aborting... Again, my guess is that on client side, prefab Smelter didn't invoke `inst.components.container:WidgetSetup("smelter", params.smelter)` at all and because `params.smelter` is not registered in `scripts/containers` module, the client cannot figure it out what value `widget` has. I don't know what to do now. Please help, many thanks. Link to comment Share on other sites More sharing options...
Ultroman Posted February 3, 2019 Share Posted February 3, 2019 (edited) Replacing an original game file is a BIG no-no, sir. You have been a bad boy, mister! I'm glad to see that your 1.0.9 version doesn't do that Now, this is a bit of a shot in the dark, but from how I'm reading the code in containers.lua, this line in your prefab inst.components.container:WidgetSetup("smelter", params.smelter) should be inst.components.container:WidgetSetup("smelter", params) Edited February 3, 2019 by Ultroman Link to comment Share on other sites More sharing options...
KaiserKatze Posted February 18, 2019 Author Share Posted February 18, 2019 (edited) On 2019/2/3 at 10:24 PM, Ultroman said: Replacing an original game file is a BIG no-no, sir. You have been a bad boy, mister! I'm glad to see that your 1.0.9 version doesn't do that Now, this is a bit of a shot in the dark, but from how I'm reading the code in containers.lua, this line in your prefab inst.components.container:WidgetSetup("smelter", params.smelter) should be inst.components.container:WidgetSetup("smelter", params) Sir, thank you for your reply, but your solution would lead to an exception. Please, double check the following API: In `Don't Starve Together/data/scripts/components/container.lua`: function Container:WidgetSetup(prefab, data) for i, v in ipairs(widgetprops) do removesetter(self, v) end containers.widgetsetup(self, prefab, data) self.inst.replica.container:WidgetSetup(prefab, data) for i, v in ipairs(widgetprops) do makereadonly(self, v) end end In `Don't Starve Together/data/scripts/containers.lua`: function containers.widgetsetup(container, prefab, data) local t = data or params[prefab or container.inst.prefab] if t ~= nil then for k, v in pairs(t) do container[k] = v end container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0) end end Edited February 18, 2019 by KaiserKatze Link to comment Share on other sites More sharing options...
Ultroman Posted February 18, 2019 Share Posted February 18, 2019 Yeah, you're right. You want the smelter prefab there. I have no idea what's going on here. Someone, please help this man! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now