[Solved] How do I know is entity enabled/disabled?

Place to get help with not working mods / modding interface.
Post Reply
User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1190
Joined: Wed May 18, 2016 4:55 pm
Contact:

[Solved] How do I know is entity enabled/disabled?

Post by Mooncat »

Hi all, I am trying to make my first mod, but now I am facing a problem that even studying the existing mods doesn't help.
Can anyone tell me how can I know whether an entity (e.g. inserter) is currently enabled or disabled due to circuit condition in 0.13?

I have tried entity.active and entity.operable but obviously they are not for this purpose.
I have also checked the CircuitCondition class, but it doesn't tell whether the condition is fulfilled, like entity.get_circuit_condition(connector).fulfilled in 0.12. (Hey, did the devs forget to include this in the 0.13 modding changelog?)

Any help is appreciated. :D


Edit: Thanks to Choumiko, I am now able to detect whether an inserter entity is enabled/disabled, or just not affected by the network signals according to its operation mode. Here is the code:

Code: Select all

-- Returns whether the given inserter entity is enabled according to its circuit network state as well as its logistic network state.
function is_inserter_enabled(inserter)
	local control = inserter.get_control_behavior()
	-- Does it have control behaviour? (Not connected = no control?)
	if control and control.valid then
		-- Check logistic network.
		-- Is logistic network connected?
		if control.connect_to_logistic_network then
			-- Has logistic condition set?
			if control.logistic_condition then
				-- Condition fulfilled?
				if not control.logistic_condition.fulfilled then
					return false
				end
			else
				-- Connected but no condition, hence not OK.
				return false
			end			
		end
	
		-- Check circuit network.
		-- Is connected by wire?
		if control.get_circuit_network(defines.wire_type.red, defines.circuit_connector_id.inserter) or control.get_circuit_network(defines.wire_type.green, defines.circuit_connector_id.inserter) then
			-- Is operation mode enable/disable?
			if control.circuit_mode_of_operation == defines.control_behavior.inserter.circuit_mode_of_operation.enable_disable then
				-- Has the circuit condition set?
				if control.circuit_condition then
					-- Condition fulfilled?
					if not control.circuit_condition.fulfilled then
						return false
					end
				else
					-- Connected but no condition, hence not OK.
					return false
				end
			end
		end
	end
	
	-- No control? Because not connected to network?
	return true
end
Last edited by Mooncat on Sat Jul 09, 2016 8:43 pm, edited 1 time in total.

xcompwiz
Burner Inserter
Burner Inserter
Posts: 15
Joined: Fri May 27, 2016 8:18 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by xcompwiz »

I'll take a crack at helping. :) Though I'm afraid I haven't got a direct method.
Honestly, I'd request the enabled state be added to the mod API, as solving this the way I'm about to propose is a bit arduous and wasteful.

Combing through the Lua API (http://lua-api.factorio.com/) for version 0.13.2, I've noted a few specific things you'll want.

On the entity in question, you'll want to get the "control behavior" (get_control_behavior()). If this is nil then the object doesn't hook up to any networks. (LuaControlBehavior)
You'll then want to check that behavior's type to see if it is a LuaGenericOnOffControlBehavior or other type with a "CircuitCondition." Alternatively, check for circuit_condition (and possibly logistic_condition) on the object.
Once you have that condition you can see if it is satisfied on all networks the entity is connected to.
From the LuaControlBehavior you can use get_circuit_network(wire, circuit_connector) to get any connected networks. (You'll want to check with defines.wire_type.red and defines.wire_type.green. You should be able to leave the circuit_connector param out.)

Now, the really messy/complex/fun bit: You have to solve the condition yourself (as far as I know).
You can get the value of a signal out of the network. The condition uses signal ids to reference these.

Code: Select all

local left_val = network.get_signal(condition.first_signal)
The right value of the condition is somewhat tricky, as you could also have a constant (or 0)

Code: Select all

local right_val = condition.constant or network.get_signal(condition.second_signal) or 0
On the condition, you have what comparator to use. Might be clever to use Lua tables to map this to a function.

Code: Select all

--Define these early on
comparators["<"] = function(lft, rht) return lft < rht end
comparators["="] = function(lft, rht) return lft == rht end
comparators[">"] = function(lft, rht) return lft > rht end

--Usage
local result = comparators[condition.comparator or ">"](left_value, right_value)
And that will tell you if the condition is true. You can probably work it out from there.
The biggest pitfall that I see off hand is that the condition.first_signal may be blank (nil) which you could probably shortcut to returning false on.

Hopefully that helps! :D Let us know how it goes.

EDIT: ADDENDUM:
You can probably handle "check all networks" generically by doing a

Code: Select all

for _,wire_type in pairs(defines.wire_type) do
Rough complete code
EDIT2: I noted that the condition.comparator may not be set and should default to ">", so I fixed the code to reflect this.

User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1190
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by Mooncat »

xcompwiz wrote:I'll take a crack at helping. :) Though I'm afraid I haven't got a direct method.
Honestly, I'd request the enabled state be added to the mod API, as solving this the way I'm about to propose is a bit arduous and wasteful.

Combing through the Lua API (http://lua-api.factorio.com/) for version 0.13.2, I've noted a few specific things you'll want.

On the entity in question, you'll want to get the "control behavior" (get_control_behavior()). If this is nil then the object doesn't hook up to any networks. (LuaControlBehavior)
You'll then want to check that behavior's type to see if it is a LuaGenericOnOffControlBehavior or other type with a "CircuitCondition." Alternatively, check for circuit_condition (and possibly logistic_condition) on the object.
Once you have that condition you can see if it is satisfied on all networks the entity is connected to.
From the LuaControlBehavior you can use get_circuit_network(wire, circuit_connector) to get any connected networks. (You'll want to check with defines.wire_type.red and defines.wire_type.green. You should be able to leave the circuit_connector param out.)

Now, the really messy/complex/fun bit: You have to solve the condition yourself (as far as I know).
You can get the value of a signal out of the network. The condition uses signal ids to reference these.

Code: Select all

local left_val = network.get_signal(condition.first_signal)
The right value of the condition is somewhat tricky, as you could also have a constant (or 0)

Code: Select all

local right_val = condition.constant or network.get_signal(condition.second_signal) or 0
On the condition, you have what comparator to use. Might be clever to use Lua tables to map this to a function.

Code: Select all

--Define these early on
comparators["<"] = function(lft, rht) return lft < rht end
comparators["="] = function(lft, rht) return lft == rht end
comparators[">"] = function(lft, rht) return lft > rht end

--Usage
local result = comparators[condition.comparator or ">"](left_value, right_value)
And that will tell you if the condition is true. You can probably work it out from there.
The biggest pitfall that I see off hand is that the condition.first_signal may be blank (nil) which you could probably shortcut to returning false on.

Hopefully that helps! :D Let us know how it goes.

EDIT: ADDENDUM:
You can probably handle "check all networks" generically by doing a

Code: Select all

for _,wire_type in pairs(defines.wire_type) do
Rough complete code
EDIT2: I noted that the condition.comparator may not be set and should default to ">", so I fixed the code to reflect this.
I had the same idea of doing the condition checking ourselves too, but it seems too hacky, so I didn't really think about that. :roll:
Thanks for doing the tough job! I will have a look on it when I go back to that part. Currently I am rushing to finish updating an amazing but outdated mod so I can publish it asap. And yes, we should request the enabled state!
(Also thanks for telling me they have already released updates for 0.13! wow, I was too busy on writing the mod. xD)

Choumiko
Smart Inserter
Smart Inserter
Posts: 1352
Joined: Fri Mar 21, 2014 10:51 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by Choumiko »

A lot of the info is there:
http://lua-api.factorio.com/0.13.3/LuaC ... vior.brief

(run the command while cursor is over an entity with a condition)

Code: Select all

/c game.player.print(serpent.line(game.player.selected.get_or_create_control_behavior().circuit_condition.fulfilled, {comment=false}))
For real code you'd probably want to use get_control_behavior() and checking if it exists though.

User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1190
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by Mooncat »

Choumiko wrote:A lot of the info is there:
http://lua-api.factorio.com/0.13.3/LuaC ... vior.brief

(run the command while cursor is over an entity with a condition)

Code: Select all

/c game.player.print(serpent.line(game.player.selected.get_or_create_control_behavior().circuit_condition.fulfilled, {comment=false}))
For real code you'd probably want to use get_control_behavior() and checking if it exists though.
Oh! It is added! I swear I have searched in that page several times but it wasn't there. Thanks for pointing that out. I will try it. :D

xcompwiz
Burner Inserter
Burner Inserter
Posts: 15
Joined: Fri May 27, 2016 8:18 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by xcompwiz »

Does CircuitCondition.fulfilled exist? it's not in the API. Good to know if it does. :D

User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1190
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: How do I know is entity enabled/disabled?

Post by Mooncat »

xcompwiz wrote:Does CircuitCondition.fulfilled exist? it's not in the API. Good to know if it does. :D
I haven't tested yet (because some more important tasks appeared), but it seems to be..... still missing? :o
I have deleted my request in the mod interface request board. :?


Edit: Yes! Choumiko's method is working. It is just missing in the doc. We should tell the devs to add it back. :lol:
I'm gonna combine it with the circuit_mode_of_operation property in order to get the current state of the inserter, before I can confirm this thread is solved. :mrgreen:

User avatar
Mooncat
Smart Inserter
Smart Inserter
Posts: 1190
Joined: Wed May 18, 2016 4:55 pm
Contact:

Re: [Solved] How do I know is entity enabled/disabled?

Post by Mooncat »

The problem is solved. I have written the function to detect whether an inserter entity is enabled/disabled. The solution is on the first post. ;)

Post Reply

Return to “Modding help”