Ability to control if an assembler's recipe can be changed?

Post Reply
damienreave
Inserter
Inserter
Posts: 46
Joined: Sat Jun 07, 2014 7:35 pm
Contact:

Ability to control if an assembler's recipe can be changed?

Post by damienreave »

I poured through the code this morning, but I can't seem to figure out a way to prevent an assembler's recipe from being changed after its initially set. Am I missing something? If not, I'd love for this to be put in!

Thanks.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13220
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by Rseding91 »

Set entity.operable = false and the machine will still run but the player can't open it.
If you want to get ahold of me I'm almost always on Discord.

damienreave
Inserter
Inserter
Posts: 46
Joined: Sat Jun 07, 2014 7:35 pm
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by damienreave »

This doesn't seem to work, and I don't see any other examples of 'operable' in the code to use to figure out what I'm doing wrong.

Removing the assembler's selection box seemed like a possible solution, but if you do, you can't set the recipe for assembling the first time, and its useless.

FishSandwich
Smart Inserter
Smart Inserter
Posts: 1847
Joined: Sun Feb 23, 2014 3:37 pm
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by FishSandwich »

I'm not sure how to do it, but I know that the test mode mod is able to make a building's operable = false when it is placed. Try looking through the code for that mod and see if you can find how it's done.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13220
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by Rseding91 »

Mouse over the entity once and enter this:

Code: Select all

/c game.getplayer(1).selected.operable = false
Or, if you want a single machine that sets its own recipe on creation you could use something like this in the onbuilt event(s):

Code: Select all

event.createentity.recipe = "wooden-chest"; event.createentity.operable = false
That would make the built entity's recipe the "wooden-chest" and make it non-operable essentially giving you a wooden-chest machine.
If you want to get ahold of me I'm almost always on Discord.

damienreave
Inserter
Inserter
Posts: 46
Joined: Sat Jun 07, 2014 7:35 pm
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by damienreave »

Thanks for the suggestions everyone.

Making entity.operable = false would be a great solution, if only I could call it when a recipe was set. I went through the list of events: https://forums.factorio.com/wiki/inde ... Lua/Events but none of them seem appropriate. I wonder if its possible that we could get a onrecipeset event?

Incinirate
Burner Inserter
Burner Inserter
Posts: 18
Joined: Sun May 03, 2015 9:50 pm
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by Incinirate »

damienreave wrote:Thanks for the suggestions everyone.

Making entity.operable = false would be a great solution, if only I could call it when a recipe was set. I went through the list of events: https://forums.factorio.com/wiki/inde ... Lua/Events but none of them seem appropriate. I wonder if its possible that we could get a onrecipeset event?
I know that this is not the best solution by a long shot, but it could work for the time being, seeing that we don't have an onrecipeset event yet.
You could potentially, through scripting, have a onTick handler, that every like 20-30 ticks or whatever check all the machines that you want this property to be applied to, and if they have a recipe set, make that machine inoperable.

wahming
Fast Inserter
Fast Inserter
Posts: 190
Joined: Sun May 17, 2015 8:30 pm
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by wahming »

Incinirate wrote:
damienreave wrote:Thanks for the suggestions everyone.

Making entity.operable = false would be a great solution, if only I could call it when a recipe was set. I went through the list of events: https://forums.factorio.com/wiki/inde ... Lua/Events but none of them seem appropriate. I wonder if its possible that we could get a onrecipeset event?
I know that this is not the best solution by a long shot, but it could work for the time being, seeing that we don't have an onrecipeset event yet.
You could potentially, through scripting, have a onTick handler, that every like 20-30 ticks or whatever check all the machines that you want this property to be applied to, and if they have a recipe set, make that machine inoperable.
Is there a method that checks that? I don't see it on wiki anywhere.

itzJanuary
Burner Inserter
Burner Inserter
Posts: 7
Joined: Mon May 25, 2015 9:45 am
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by itzJanuary »

Since I had a bit too much time on my hands, I mocked up a quick control.lua that should do the job

This should work although i have not tested it :3

Code: Select all

require "defines"

if not glob.entityPositions then
	glob.entityPositions = {}
end

prototypes = {{"assembling-machine-1"}, {"assembling-machine-2"}, {"assembling-machine-3"}}
entities = {}

-- The frequency is (60 / tickFreqency) per second, so currently it is 10 ticks/sec
tickFreqency = 6
tickCounter = 0

game.onevent(defines.events.ontick, function(event)
	tick()
	
	tickCounter = tickCounter + 1
end)

game.onevent(defines.events.onbuiltentity, function(event)
	local entity = event.createdentity
	
	if not entity then
		return
	end
	
	addEntity(entity)
end)

function tick()
	if tickCounter % tickFreqency == 0 then
		
		--Load all entities on map load
		if tickCounter == 0 then
			local allEntities =  {}
			local aabb = {{-10000, -10000}, {10000, 10000}}
			
			for i=1,#prototypes do
				appendTable(allEntities, game.findentitiesfiltered(aabb, prototypes[i].name))
			end
		end
		
		--Check the assembling machines
		for i=1,#entities do
			local wrapper = entities[i]
			local entity = wrapper.entity
			
			-- This is the most important bit. This makes the machines unoperable
			if entity.recipe then
				entity.operable = false
				removeEntity(entity.position)
			end
		end
	end
end

function removeEntity(position)
	if not position then
		return false
	end
	
	--Remove the entity from the global list
	for i=1,#glob.entityPositions do
		local p = glob.entityPositions[i]
		
		if position.x == p.x and position.y == p.y then
			table.remove(glob.entityPositions, i)
			break
		end
	end
	
	--Remove the entity from the 'local'/unpersistent list
	for i=1,#entities do
		local p = entities[i].postition
		
		if position.x == p.x and position.y == p.y then
			table.remove(entities, i)
			break
		end
	end
end

-- Checks whether the entity is in the protoype table.
-- If it is, it adds the entity to a list.
function addEntity(entity)
	if not entity then
		return false
	end
	
	local isValid = false
	
	for i=1,#prototypes do
		if entity.name == prototypes[i].name then
			isValid = true
			break
		end
	end
	
	if not isValid then
		return false
	end
	
	--Create a wrapper for the entity
	local wrapper = {}
	wrapper.entity = entity
	table.insert(entities, entity)
	
	--This is important! Since control.lua isnt persistent between game loads.
	local position = {}
	position.x = entity.position.x
	position.y = entity.position.y
	table.insert(glob.entityPositions, position)
	
	return true
end

-- Adds all values from 'table2' to 'table1'.
-- If one table is nil the other is returned.
function appendTable(table1, table2)
	if table1 == nil then
		return table2
	elseif table2 == nil then
		return table1
	end
	
	local table1Size = #table1
	
	for i=1,#table2 do
		table1[table1Size + i + 1] = table2[i]
	end
	
	return table1
end

itzJanuary
Burner Inserter
Burner Inserter
Posts: 7
Joined: Mon May 25, 2015 9:45 am
Contact:

Re: Ability to control if an assembler's recipe can be changed?

Post by itzJanuary »

wahming wrote:
Incinirate wrote:
damienreave wrote:Thanks for the suggestions everyone.

Making entity.operable = false would be a great solution, if only I could call it when a recipe was set. I went through the list of events: https://forums.factorio.com/wiki/inde ... Lua/Events but none of them seem appropriate. I wonder if its possible that we could get a onrecipeset event?
I know that this is not the best solution by a long shot, but it could work for the time being, seeing that we don't have an onrecipeset event yet.
You could potentially, through scripting, have a onTick handler, that every like 20-30 ticks or whatever check all the machines that you want this property to be applied to, and if they have a recipe set, make that machine inoperable.
Is there a method that checks that? I don't see it on wiki anywhere.
Yes, there is!
https://forums.factorio.com/wiki/inde ... ingMachine

this could also be helpful (it's kinda hidden away):
https://forums.factorio.com/wiki/inde ... WithHealth

Especially the "Extensions" part of that second link can come in handy.

Post Reply

Return to “Implemented mod requests”