Kzisor Posted December 12, 2014 Share Posted December 12, 2014 This is an off the wall type question, but I'm going to ask anyway as it pertains specifically to a mod that I am creating for Don't Starve Together. Do you have to create a replica of the object you want to force only one person to use at a single time? I'm specifically asking because after looking at the code for container and container_replica it seems this might be the case. Any insight would be greatly appreciated. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/ Share on other sites More sharing options...
simplex Posted December 12, 2014 Share Posted December 12, 2014 All networked entities have a replica (non-networked entities do too, the replica is just redundant in that case). The replica is a way of coordinating component state across the network. Check entityreplica.lua for more details (which should lead you to files like components/container_replica.lua). But the actual one person use logic is in actions.lua. Search for the string "INUSE". Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584257 Share on other sites More sharing options...
Kzisor Posted December 12, 2014 Author Share Posted December 12, 2014 All networked entities have a replica (non-networked entities do too, the replica is just redundant in that case). The replica is a way of coordinating component state across the network. Check entityreplica.lua for more details (which should lead you to files like components/container_replica.lua).But the actual one person use logic is in actions.lua. Search for the string "INUSE". The INUSE string is exactly what I was looking for, thank you very much for pointing that out. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584261 Share on other sites More sharing options...
simplex Posted December 12, 2014 Share Posted December 12, 2014 The INUSE string is exactly what I was looking for, thank you very much for pointing that out. Just to be clear: that "INUSE" simply indicates the message that should be displayed (in this case, STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.STORE.INUSE, defined in speech_wilson.lua). Looking for that string should just point you to the places where the functionality you're looking for is at, the string itself doesn't matter. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584264 Share on other sites More sharing options...
Kzisor Posted December 12, 2014 Author Share Posted December 12, 2014 Just to be clear: that "INUSE" simply indicates the message that should be displayed (in this case, STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.STORE.INUSE, defined in speech_wilson.lua). Looking for that string should just point you to the places where the functionality you're looking for is at, the string itself doesn't matter. Thanks for getting me this information. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584271 Share on other sites More sharing options...
Kzisor Posted December 13, 2014 Author Share Posted December 13, 2014 Just to be clear: that "INUSE" simply indicates the message that should be displayed (in this case, STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.STORE.INUSE, defined in speech_wilson.lua). Looking for that string should just point you to the places where the functionality you're looking for is at, the string itself doesn't matter. Okay so I have hit a huge snag. I'm able to determine whether a person is using an object, but I am unable from stopping another person from using the same object even with the mod installed on both computers. Here is my code:function CoopFishingPostInit(inst) -- Add additional variables to be used. inst.fisher = nil inst.InUse = function() return inst.fisher ~= nil end inst.InUseBy = function(guy) return inst.fisher == guy end -- Return the instance. return instendAddPrefabPostInit("pond", CoopFishingPostInit)AddPrefabPostInit("pond_mos", CoopFishingPostInit)--[[ CHANGES FOR FISHINGROD.LUA ]]local FishingRod = require("components/fishingrod")function FishingRod:StartFishing(target, fisherman) -- Stop fishing. self:StopFishing() -- Make user that the target user is empty and fisherman is not nil. if target.fisher == nil and fisherman ~= nil and not target.InUse() then print(fisherman and " has started fishing at " and target.prefab and ".") -- Set target up correctly. target.fisher = fisherman -- Set fishingrod up properly. self.target = target self.fisherman = fisherman self.inst:StartUpdatingComponent(self) endendfunction FishingRod:StopFishing() if self.target and self.fisherman then if self.target.fisher and self.target.InUseBy(self.fisherman) then self.target.fisher = nil end self.inst:PushEvent("fishingcancel") self.fisherman:PushEvent("fishingcancel") self.target = nil self.fisherman = nil end self:CancelFishTask() self.inst:StopUpdatingComponent(self) self.hookedfish = nil self.caughtfish = nilendGLOBAL.ACTIONS.FISH.fn = nilGLOBAL.ACTIONS.FISH.fn = function(act) local fishingrod = act.invobject.components.fishingrod if fishingrod then if act.target.InUse() then if not act.target.InUseBy(act.doer) then fishingrod:StopFishing() return false, "INUSE" end end fishingrod:StartFishing(act.target, act.doer) end return trueendAnyone got an idea what I need to do in order to stop the second player from fishing? Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584390 Share on other sites More sharing options...
rezecib Posted December 13, 2014 Share Posted December 13, 2014 (edited) @Kzisor, You need to be changing Fishingrod with AddComponentPostInit, not using require to acquire and then change it. That changed version isn't being used anywhere. Edit: So change thislocal FishingRod = require("components/fishingrod") function FishingRod:StartFishing(target, fisherman) -- Stop fishing. self:StopFishing() -- Make user that the target user is empty and fisherman is not nil. if target.fisher == nil and fisherman ~= nil and not target.InUse() then print(fisherman and " has started fishing at " and target.prefab and ".") -- Set target up correctly. target.fisher = fisherman -- Set fishingrod up properly. self.target = target self.fisherman = fisherman self.inst:StartUpdatingComponent(self) endend function FishingRod:StopFishing() if self.target and self.fisherman then if self.target.fisher and self.target.InUseBy(self.fisherman) then self.target.fisher = nil end self.inst:PushEvent("fishingcancel") self.fisherman:PushEvent("fishingcancel") self.target = nil self.fisherman = nil end self:CancelFishTask() self.inst:StopUpdatingComponent(self) self.hookedfish = nil self.caughtfish = nilendTo this:local function FishingRodPostInit(self) function self:StartFishing(target, fisherman) -- Stop fishing. self:StopFishing() -- Make user that the target user is empty and fisherman is not nil. if target.fisher == nil and fisherman ~= nil and not target.InUse() then print(fisherman and " has started fishing at " and target.prefab and ".") -- Set target up correctly. target.fisher = fisherman -- Set fishingrod up properly. self.target = target self.fisherman = fisherman self.inst:StartUpdatingComponent(self) end end function self:StopFishing() if self.target and self.fisherman then if self.target.fisher and self.target.InUseBy(self.fisherman) then self.target.fisher = nil end self.inst:PushEvent("fishingcancel") self.fisherman:PushEvent("fishingcancel") self.target = nil self.fisherman = nil end self:CancelFishTask() self.inst:StopUpdatingComponent(self) self.hookedfish = nil self.caughtfish = nil endendAddComponentPostInit("fishingrod", FishingRodPostInit) Edited December 13, 2014 by rezecib Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584396 Share on other sites More sharing options...
Kzisor Posted December 13, 2014 Author Share Posted December 13, 2014 @Kzisor, You need to be changing Fishingrod with AddComponentPostInit, not using require to acquire and then change it. That changed version isn't being used anywhere. Edit: So change thislocal FishingRod = require("components/fishingrod") function FishingRod:StartFishing(target, fisherman) -- Stop fishing. self:StopFishing() -- Make user that the target user is empty and fisherman is not nil. if target.fisher == nil and fisherman ~= nil and not target.InUse() then print(fisherman and " has started fishing at " and target.prefab and ".") -- Set target up correctly. target.fisher = fisherman -- Set fishingrod up properly. self.target = target self.fisherman = fisherman self.inst:StartUpdatingComponent(self) endend function FishingRod:StopFishing() if self.target and self.fisherman then if self.target.fisher and self.target.InUseBy(self.fisherman) then self.target.fisher = nil end self.inst:PushEvent("fishingcancel") self.fisherman:PushEvent("fishingcancel") self.target = nil self.fisherman = nil end self:CancelFishTask() self.inst:StopUpdatingComponent(self) self.hookedfish = nil self.caughtfish = nilendTo this:local function FishingRodPostInit(self) function self:StartFishing(target, fisherman) -- Stop fishing. self:StopFishing() -- Make user that the target user is empty and fisherman is not nil. if target.fisher == nil and fisherman ~= nil and not target.InUse() then print(fisherman and " has started fishing at " and target.prefab and ".") -- Set target up correctly. target.fisher = fisherman -- Set fishingrod up properly. self.target = target self.fisherman = fisherman self.inst:StartUpdatingComponent(self) end end function self:StopFishing() if self.target and self.fisherman then if self.target.fisher and self.target.InUseBy(self.fisherman) then self.target.fisher = nil end self.inst:PushEvent("fishingcancel") self.fisherman:PushEvent("fishingcancel") self.target = nil self.fisherman = nil end self:CancelFishTask() self.inst:StopUpdatingComponent(self) self.hookedfish = nil self.caughtfish = nil endendAddComponentPostInit("fishingrod", FishingRodPostInit) Your changed version does exactly what mine does in practice. It notifies you that a player is using the object, but doesn't prevent another user from using the same object. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584404 Share on other sites More sharing options...
Kzisor Posted December 13, 2014 Author Share Posted December 13, 2014 Okay, so I figured out that I needed to add an overwrite to the action I created with 'AddAction', but now I cannot fish at all on my second account. Every time I fish even while no one is using it, it throws the line and pauses half way through the animation. Any thoughts? Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584460 Share on other sites More sharing options...
simplex Posted December 13, 2014 Share Posted December 13, 2014 (edited) Okay so I have hit a huge snag. I'm able to determine whether a person is using an object, but I am unable from stopping another person from using the same object even with the mod installed on both computers. Here is my code:--snip--Anyone got an idea what I need to do in order to stop the second player from fishing?Your code is working fine, actually. It's just the fishing animation that's being played, the player isn't actually fishing (nor is the fishing rod's durability being decreased). The animation is played because the player's stategraph (stategraphs/SGwilson.lua) goes automatically to the state "fishing_pre" once the FISH action is received (that's before even checking if it will work or fail). This can be ammended by simply changing the last bit of your code:GLOBAL.ACTIONS.FISH.fn = function(act)local fishingrod = act.invobject.components.fishingrodif fishingrod thenif act.target.InUse() thenif not act.target.InUseBy(act.doer) thenact.doer:PushEvent("fishingcancel")fishingrod:StopFishing()return false, "INUSE"endendfishingrod:StartFishing(act.target, act.doer)endreturn trueend Okay, so I figured out that I needed to add an overwrite to the action I created with 'AddAction', but now I cannot fish at all on my second account. Every time I fish even while no one is using it, it throws the line and pauses half way through the animation. Any thoughts?Oh no, don't do that. AddAction is just for adding new, fully custom actions, editing an existing action is done exactly as you were doing it. @Kzisor, You need to be changing Fishingrod with AddComponentPostInit, not using require to acquire and then change it. That changed version isn't being used anywhere.The method he's using is fine. Many modders prefer it over AddComponentPostInit (@squeek is probably the most vocal about it). The class table is the index metamethod of its objects, so whenever you try to index an object's field and it's nil, the class table's field is used. So, as long as e.g. the StartFishing field is not set in any of the fishing rod component's objects, changing the class table propagates the change to all instances of the fishing rod component.EDIT: for some reason the forum had eaten my code indentation.EDIT 2: I give up, code indentation isn't working. Spaces don't work, tabs don't work... Edited December 13, 2014 by simplex Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584489 Share on other sites More sharing options...
rezecib Posted December 13, 2014 Share Posted December 13, 2014 The method he's using is fine. Many modders prefer it over AddComponentPostInit (@squeek is probably the most vocal about it). The class table is the index metamethod of its objects, so whenever you try to index an object's field and it's nil, the class table's field is used. So, as long as e.g. the StartFishing field is not set in any of the fishing rod component's objects, changing the class table propagates the change to all instances of the fishing rod component. Interesting, didn't know that. Thanks for the elucidation Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584491 Share on other sites More sharing options...
Kzisor Posted December 13, 2014 Author Share Posted December 13, 2014 Your code is working fine, actually. It's just the fishing animation that's being played, the player isn't actually fishing (nor is the fishing rod's durability being decreased). The animation is played because the player's stategraph (stategraphs/SGwilson.lua) goes automatically to the state "fishing_pre" once the FISH action is received (that's before even checking if it will work or fail). This can be ammended by simply changing the last bit of your code:GLOBAL.ACTIONS.FISH.fn = function(act)local fishingrod = act.invobject.components.fishingrodif fishingrod thenif act.target.InUse() thenif not act.target.InUseBy(act.doer) thenact.doer:PushEvent("fishingcancel")fishingrod:StopFishing()return false, "INUSE"endendfishingrod:StartFishing(act.target, act.doer)endreturn trueend Oh no, don't do that. AddAction is just for adding new, fully custom actions, editing an existing action is done exactly as you were doing it. The method he's using is fine. Many modders prefer it over AddComponentPostInit (@squeek is probably the most vocal about it). The class table is the index metamethod of its objects, so whenever you try to index an object's field and it's nil, the class table's field is used. So, as long as e.g. the StartFishing field is not set in any of the fishing rod component's objects, changing the class table propagates the change to all instances of the fishing rod component.EDIT: for some reason the forum had eaten my code indentation.EDIT 2: I give up, code indentation isn't working. Spaces don't work, tabs don't work... Honestly, I spent 4 hours trying to make it work only for it already to be working.....*head vs wall* Thanks simplex that single line of code fixed it for me. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584497 Share on other sites More sharing options...
simplex Posted December 13, 2014 Share Posted December 13, 2014 Honestly, I spent 4 hours trying to make it work only for it already to be working.....*head vs wall* Thanks simplex that single line of code fixed it for me. Hey, we've all been there. Trying to fix code that's not broken is the hardest thing there is. Link to comment https://forums.kleientertainment.com/forums/topic/46156-container-functionality-only-allowing-one-person-to-use/#findComment-584513 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