Find a type based on a name

Place to get help with not working mods / modding interface.
Post Reply
User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Find a type based on a name

Post by DRY411S »

This is probably more a LUA question than a modding question.

But if I know the name of something in data.raw factorio, is there a quick way of finding its type?

For example:

name = "rocket", type = "ammo"
name = "iron-plate", type = "item"
name = "basic-grenade", type = "capsule"

My code knows the name, I need to find the type.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Find a type based on a name

Post by DaveMcW »

There is no quick way, you have to brute force search all the types in data.raw.
DRY411S wrote:My code knows the name, I need to find the type.
How did your code get the name without the type?

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Find a type based on a name

Post by DRY411S »

OK thanks. I am bruteforcing, I just thought there may be a better way.

I have an ingredient name from a recipe. Specifically I need to find its stack_size, as part of turning it into a result in a 'reverse recipe'

Ingredients aren't always data.raw.item. sometimes they are data.raw.ammo, .capsule, .mining-tool etc, so I need to know what this type is to find it and pick up the stack_size.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Find a type based on a name

Post by DaveMcW »

If you are doing this for every recipe in the game, it may be faster to build your own lookup table.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Find a type based on a name

Post by bobingabout »

I think I mentioned it before but... look at the item-functions.lua file in my library mod. there are 2 functions in that file, get_item_type and get_basic_item_type.

For a recipe though, it basically expects to only ever see type="fluid" or type="item", if you use a tool, and use type="tool", it will error, you should use type="item" instead.


if it's for recipes, you should cycle through data.raw["fluid"], and if it finds it set type to fluid, if it doesn't, default to item (like my function I told you to look at)

if it's for actually accessing the item, you'll need to do the same, but for every known type.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Find a type based on a name

Post by DRY411S »

DaveMcW wrote:If you are doing this for every recipe in the game, it may be faster to build your own lookup table.
Yes, I'm looking at that now. It needs to built dynamically at the top of my code.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Find a type based on a name

Post by DRY411S »

bobingabout wrote:I think I mentioned it before but... look at the item-functions.lua file in my library mod. there are 2 functions in that file, get_item_type and get_basic_item_type.

For a recipe though, it basically expects to only ever see type="fluid" or type="item", if you use a tool, and use type="tool", it will error, you should use type="item" instead.


if it's for recipes, you should cycle through data.raw["fluid"], and if it finds it set type to fluid, if it doesn't, default to item (like my function I told you to look at)

if it's for actually accessing the item, you'll need to do the same, but for every known type.
The logic I'm using here is

For every recipe
Turn the ingredients into results
For each of the new results, find the stack_size and truncate the result amount if it exceeds the stack_size.

For this I need to find the 'type' that the results belong to." Item" and "fluid" are not precise enough. Because in this case "item" could mean ammo, capsule, item etc.

Unless I'm missing something.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Find a type based on a name

Post by bobingabout »

DRY411S wrote:For every recipe
Turn the ingredients into results
For each of the new results, find the stack_size and truncate the result amount if it exceeds the stack_size.

For this I need to find the 'type' that the results belong to." Item" and "fluid" are not precise enough. Because in this case "item" could mean ammo, capsule, item etc.

Unless I'm missing something.
For this you basically need to check if it exists for every possible type...

This is the function from my mod, though looking at this, the check is overkill

Code: Select all

function bobmods.lib.get_item_type(name)
  local item_types = {"ammo", "armor", "capsule", "fluid", "gun", "mining-tool", "module", "tool"}
  local item_type = "item"
  for i, type_name in pairs(item_types) do
    for j, item in pairs(data.raw[type_name]) do
      if item.name == name then item_type = type_name end
    end
  end
  return item_type
end
you could probably reduce your check to the following: (Yes, I found you can actually define your table of strings inside the pairs() command directly without defining it as a table first.)

Code: Select all

functions your_function_name_here(item_name)
  local item_type = "item" -- the default
  for i, type_name in pairs({"ammo", "armor", "capsule", "fluid", "gun", "mining-tool", "module", "tool"}) do
    if data.raw[type_name][item_name] then item_type = type_name end
    end
  end
  if item_type ~= "fluid" then -- fluid has no stack size
--Do your stack size checks here
  end
end
Though that function is incomplete, I'm not just talking about the do checks here like, you'd probably want to pass more variables than just the item name.

And don't forget to take amount_min, amount_max and probability into account that can exist as a result, but not an ingredient.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Find a type based on a name

Post by DRY411S »

Thanks for sharing, I have something that dynamically looks for all types. it's probably overkill but as it's in the data loading phase I'm relaxed about the time it might take.

How safe is it though to hard code the types likeyou have? I was doing this at first, but I was thinking that modders/ devs may introduce new types.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Find a type based on a name

Post by bobingabout »

I am unaware of a predefined table of item types (That doesn't mean it doesn't exist). But basically, if the devs add one, then you'll need to add it too.

A safer way would be if instead of using "item" as the default, you add that to the list too, and have the default as nil, then when you do the check later, check to see if it's nil, and if so, abandon the check on that item, or delete the item from the recipe entirely, or delete the recipe if it makes no sense anymore.

Something like this would be the basics:

Code: Select all

functions your_function_name_here(item_name)
  local item_type = nil -- the default
  for i, type_name in pairs({"ammo", "armor", "capsule", "fluid", "item", "gun", "mining-tool", "module", "tool"}) do
    if data.raw[type_name][item_name] then item_type = type_name end
    end
  end
  if item_type ~= nil and item_type ~= "fluid" then -- fluid has no stack size
--Do your stack size checks here
  end
end
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
DRY411S
Filter Inserter
Filter Inserter
Posts: 727
Joined: Sun Mar 13, 2016 9:48 am
Contact:

Re: Find a type based on a name

Post by DRY411S »

My brute foce...

Code: Select all

-- If the result amounts are greater than the stack_size we need to limit output to stack_size
-- newrow contains type (item or fluid), count, and name
local stack_size = nil
for _,group  in pairs(data.raw) do
	for _,nextitem in pairs(group) do
		if nextitem.name == newrow.name then
			stack_size = nextitem.stack_size
			if stack_size then
				break
			end
		end
	end
	if stack_size then
		break
	end
end

Post Reply

Return to “Modding help”