BakaSchwarz Posted July 17, 2017 Share Posted July 17, 2017 Hey, i have the following code: owner.components.container:DropItem(inst) owner is lets say a chest. When i use DropItem, it drops the item as expected, but the chest interface is not updated and the item image remains. How can i refresh it without closing the inferface? Link to comment Share on other sites More sharing options...
ZupaleX Posted July 18, 2017 Share Posted July 18, 2017 Hi, could you post more info? Like the function where you call this, etc? Link to comment Share on other sites More sharing options...
BakaSchwarz Posted July 18, 2017 Author Share Posted July 18, 2017 Of course. The following contains the code in which the function is called. I cut out some really unnecessary stuff: require "prefabutil" local assets = { Asset("ANIM", "anim/voidgem_build.zip"), Asset("ATLAS", "images/inventoryimages/voidgem_normal.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_normal.tex"), Asset("ATLAS", "images/inventoryimages/voidgem_refined.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_refined.tex"), Asset("ATLAS", "images/inventoryimages/voidgem_purified.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_purified.tex"), } local function buildvoidgem(version) local current_owner = nil local range_indicator = nil local PLACER_SCALE = 1 local function CheckVoidAmount(inst) local amount = 0 return amount end local function TryInsert(inst, item) end local function IsEntityACandidate(owner, candidate) return false end local function RangeIndicator(inst, active) end local function fn() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.AnimState:SetBank("voidgem") inst.AnimState:SetBuild("voidgem_build") if version == "normal" then inst.AnimState:PlayAnimation("idle_normal", true) elseif version == "refined" then inst.AnimState:PlayAnimation("idle_refined", true) elseif version == "purified" then inst.AnimState:PlayAnimation("idle_purified", true) end inst:AddTag("molebait") inst:AddTag("voidresist") inst.entity:SetPristine() RangeIndicator(inst, true) if not TheWorld.ismastersim then return inst end inst:AddComponent("inventoryitem") if version == "normal" then inst.components.inventoryitem.atlasname = "images/inventoryimages/voidgem_normal.xml" elseif version == "refined" then inst.components.inventoryitem.atlasname = "images/inventoryimages/voidgem_refined.xml" inst:AddComponent("container") inst.components.container:WidgetSetup("voidgem_refined") inst.components.container.onopenfn = function () inst.components.inventoryitem.cangoincontainer = false end inst.components.container.onclosefn = function() inst.components.inventoryitem.cangoincontainer = true end elseif version == "purified" then inst.components.inventoryitem.atlasname = "images/inventoryimages/voidgem_purified.xml" inst:AddComponent("container") inst.components.container:WidgetSetup("voidgem_purified") inst.components.container.onopenfn = function () inst.components.inventoryitem.cangoincontainer = false end inst.components.container.onclosefn = function() inst.components.inventoryitem.cangoincontainer = true end end inst.components.inventoryitem:SetOnPutInInventoryFn(function(_, owner) if not owner:HasTag("voidresist") then RangeIndicator(current_owner, false) RangeIndicator(owner, true) current_owner = owner else owner.components.container:DropItem(inst) -- HERE!!! end end) inst.components.inventoryitem:SetOnDroppedFn(function(_, owner) RangeIndicator(current_owner, false) current_owner = nil end) inst:AddComponent("tradable") inst:AddComponent("inspectable") MakeHauntableLaunchAndSmash(inst) return inst end return Prefab("voidgem_"..version, fn, assets) end return buildvoidgem("normal"), buildvoidgem("refined"), buildvoidgem("purified") The widget setup gets overriden in the modmain.lua, where i define my own container: local RECIPETABS = GLOBAL.RECIPETABS local Vector3 = GLOBAL.Vector3 local TECH = GLOBAL.TECH local require = GLOBAL.require containers = require "containers" Assets = { Asset("ATLAS", "images/inventoryimages/voidgem_normal.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_normal.tex"), Asset("ATLAS", "images/inventoryimages/voidgem_refined.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_refined.tex"), Asset("ATLAS", "images/inventoryimages/voidgem_purified.xml"), Asset("IMAGE", "images/inventoryimages/voidgem_purified.tex"), Asset("ANIM", "anim/ui_chest_3x3.zip"), } PrefabFiles = { "voidgem", } -- Container -- local params = {} local old_widgetsetup = containers.widgetsetup function containers.widgetsetup(container, prefab, ...) local t = 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) else old_widgetsetup(container, prefab, ...) end end local function makeVoidGem() container = { widget = { slotpos = {}, animbank = "ui_chest_3x3", animbuild = "ui_chest_3x3", pos = Vector3(0, 200, 0), side_align_tip = 160, }, acceptsstacks = false, type = "chest", } for y = 2, 0, -1 do for x = 0, 2 do table.insert(container.widget.slotpos, Vector3(80 * x - 80 * 2 + 80, 80 * y - 80 * 2 + 80, 0)) end end return container end params.voidgem_refined = makeVoidGem() params.voidgem_purified = makeVoidGem() for k, v in pairs(params) do containers.MAXITEMSLOTS = math.max(containers.MAXITEMSLOTS, v.widget.slotpos ~= nil and #v.widget.slotpos or 0) end AddRecipe("voidgem_normal", {Ingredient("purplegem", 1), Ingredient("nightmarefuel", 2)}, RECIPETABS.MAGIC, TECH.SCIENCE_ONE, nil, nil, nil, nil, nil, "images/inventoryimages/voidgem_normal.xml") AddRecipe("voidgem_refined", {Ingredient("voidgem_normal", 1, "images/inventoryimages/voidgem_normal.xml", "voidgem_normal.tex"), Ingredient("goldnugget", 20)}, RECIPETABS.MAGIC, TECH.SCIENCE_ONE, nil, nil, nil, nil, nil, "images/inventoryimages/voidgem_refined.xml") AddRecipe("voidgem_purified", {Ingredient("voidgem_normal", 1, "images/inventoryimages/voidgem_normal.xml", "voidgem_normal.tex"), Ingredient("opalpreciousgem", 1)}, RECIPETABS.MAGIC, TECH.SCIENCE_ONE, nil, nil, nil, nil, nil, "images/inventoryimages/voidgem_purified.xml") Link to comment Share on other sites More sharing options...
Lumina Posted July 18, 2017 Share Posted July 18, 2017 (edited) I tried to look at the function in game code and i found it used this way victim.components.container:DropItem(item) (for thief code, like frog for example) --inst.components.container:DropItem(item) (in unused functions in the code). But you use owner.components.container:DropItem(inst) So what are you trying to drop ? The content of the container ? The container itself ? Maybe you need to specify somewhere that you try to drop one item ? Since i'm not sure about what you try to do and how your code is working i could totally be wrong. Edited July 18, 2017 by Lumina Link to comment Share on other sites More sharing options...
BakaSchwarz Posted July 18, 2017 Author Share Posted July 18, 2017 inst is the item to which this code belongs. A void gem. It checks if it is placed inside a container and then tells the container in which it was placed to drop it. owner is the container in which the gem was placed. It is also strange that the code seems to work just fine for guests, but not the host of a server. Link to comment Share on other sites More sharing options...
ZupaleX Posted July 18, 2017 Share Posted July 18, 2017 I will take a look at the snippet you posted but I just wanted to state something: The name of the variable doesn't matter. You could call it player if you want even though it has nothing to do with the player (That would just be confusing). That's why I asked for more details. Link to comment Share on other sites More sharing options...
ZupaleX Posted July 18, 2017 Share Posted July 18, 2017 OK, I just had time to look at what you posted. So dont do that in general: inst.components.container.onclosefn = function() inst.components.inventoryitem.cangoincontainer = true end This function takes an argument, even though here technically it doesn't matter so much it is a good idea to not take bad habits inst.components.container.onclosefn = function(inst_) inst_.components.inventoryitem.cangoincontainer = true end Then for your problem, what happens is that you set the InventoryItem.onputininventoryfn which is called inside InventoryItem:OnPutInInventory(owner) which is called by a container when it receives an object in Container:GiveItem(item, slot, src_pos, drop_on_fail) So your function will be called and DropItem will be executed, spawning the item and removing it from the container. But right after that, the GiveItem function continues its execution and the next line is self.inst:PushEvent("itemget", { slot = in_slot, item = item, src_pos = src_pos }) which triggers a function in the replica.container self._onitemget = function(inst, data) self.classified:SetSlotItem(data.slot, data.item, data.src_pos) if self.issidewidget and inst.components.inventoryitem.owner ~= nil and inst.components.inventoryitem.owner.HUD ~= nil then inst.components.inventoryitem.owner:PushEvent("refreshcrafting") end end self.classified:SetSlotItem(data.slot, data.item, data.src_pos) will set the item in the container to the item you just dropped and effectively duplicating the item. BTW: I am almost certain that your code currently, even fixed to account for the issues I pointed out, will only work for the host. The client is not receiving the necessary information in the way it is written right now. 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