Page 1 of 1
script
Posted: Mon Sep 29, 2014 10:50 pm
by cartmen180
Hello everyone,
I have been working on a script that changes the result of a recipe every time it is produced. The result should depends on the outcome of math.random. So far i got nothing to work.
Does anyone know how to do this or if it is even possible in factorio? It would be a great help for the mod i am developing.
What i am trying to do is insert stone in a machine and you get either iron ore or copper ore out of it. Another thing i would like to use it for is to randomize the ore you get from (example) a iron ore field. Something like low grade, medium grade and high grade iron ore. Or different kind of minerals. But like i said i cant get it to work, so i would love to hear your suggestions

Re: script
Posted: Mon Sep 29, 2014 11:19 pm
by FreeER
You can actually specify the recipe result in a couple ways if you use the "results" property instead of "result":
{"item-name", x}. where x is a number.
{type=theType, name="item-or-fluid-name", probability=y, amount=x}, where theType is "item" or "fluid", y is between 0 and 1 (defaults to 1, or 100%), and x is a number.
{type=theType, name="item-or-fluid-name", probability=y, amount_min=a, amount_max=b}, same as above, with 'a' and 'b' both being numbers.
As the name implies you can also provide multiple results at a time.
aka, results = {{"wood", 2}, {type="fluid", name="crude-oil", amount=10}}
Re: script
Posted: Tue Sep 30, 2014 8:05 am
by cartmen180
i did not know that!
thank you very much
edit: so i tried it out and it works as i thought it would, which is not exactly how i want it to work :p
how it is now:
- chance that any of the results is made
- chance that nothing is made
what i would like is:
- always one of the results in the table and
only one
what i tried was something like this:
if math.random() > 0.5 then
result = {"iron-ore"}
else
result = {"copper-ore"}
end
which doesn't work

Re: script
Posted: Tue Sep 30, 2014 9:10 am
by cube
There is no way to do this in the prototypes, but you might be able to hack it somehow in the control script (I don't know how :-) )
Re: script
Posted: Tue Sep 30, 2014 9:17 am
by cartmen180
cube wrote:There is no way to do this in the prototypes, but you might be able to hack it somehow in the control script (I don't know how

)
yeah, that's what i figured. So i put it in a script.lua and then used require("script") in the prototype. In the script i made a function with the if statement but set it to x = {"iron-ore"} etc. and changed the prototype to result = randomFunction() but that throws an incorrect result error.
Re: script
Posted: Tue Sep 30, 2014 9:59 am
by cube
I don't understand what you are doing :-)
But just to be sure:
Prototypes are loaded when Factorio is starting (when the orange progress bar is running). The file 'data.lua' in every mod is executed (with all its require statements) and it modifies the global table data.raw. Next, data.raw is parsed and our internal representation of prototypes is created from it. After this point there is no way to change the prototypes.
control.lua runs at completely different time -- when you load a game and during the game. For this there are lots of events and what not, you can find the details on the wiki.
The important thig is, that control.lua (and everything it requires) has no access to prototypes and data.lua (and everything it requires) does not run when the game is started. If you use math.random in the prototypes definition, the random value will be evaluated only once when Factorio starts.
Re: script
Posted: Tue Sep 30, 2014 10:28 am
by cartmen180
Then that explains why it won't work :p
Re: script
Posted: Tue Sep 30, 2014 12:37 pm
by FreeER
cartmen180 wrote:Then that explains why it won't work :p
Yeah, was hoping that wouldn't be an issue for you, but kind of figured it would. You probably could hack it in control.lua if you really wanted to by having two recipes and monitoring all built assembling machines (using the onbuiltentity event and storing the createdentities in a table in the global glob table) and then checking (in ontick) if they are set to one of the recipes and switching their recipe randomly if so. As for a resource you could have it generate a 'fake' item and you could check ontick if that item is in the player's inventory and if so remove it and insert a randomly chosen item...
You'd need to hard code those item names or use another hack where you make the recipe's name be unique and matchable as well as including the itemname, for example "SwitchingRecipe[itemname]", then during runtime you could loop over the game.player.forces.recipes table looking for names that match"SwitchingRecipe%[(.*)%]" (the %s are to escape the [] and make them literal during pattern matching), store that result in a table (if it's not nil) and then use that generated table when choosing the item to insert. edit: hm. actually if you were just doing the resources you wouldn't need a recipe and could do the same with the item names, just using game.itemprototypes instead of the recipes table. well, assuming there was only one 'tier' of items that'd be recieved, with multiple tiers you'd need someway of specifying that those and recipes would work fairly well imo, considering that it's a hack to begin with end edit:
but.. definitely not as easy as it perhaps should be

Re: script
Posted: Tue Sep 30, 2014 12:49 pm
by cartmen180
What i have done now is made a couple of recipes to process a unknown mineral. The first is basic metal identifying and that has a probability of 0.42 for producing iron or copper and 0.25 for coal. Working on other recipes giving other ores, reducing probability for more rare minerals.
One ore to rule them all, yeay
