Jump to content

Recommended Posts

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.

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".

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.

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.

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.

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 trueend

Anyone got an idea what I need to do in order to stop the second player from fishing?

@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 this

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)    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 = nilend

To 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 by rezecib

 

@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 this

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)    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 = nilend

To 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.

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?

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 by simplex
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 :D

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.

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.

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...