Item types

Place to post guides, observations, things related to modding that are not mods themselves.
Post Reply
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Item types

Post by darkfrei »

Hi all,

why are we have a lot of item types?

I've made some table:

Code: Select all

 item_type_list = {
  "ammo",
  "armor",
  "gun",
  "item",
  "capsule",
  "repair-tool",
  "mining-tool",
  "item-with-entity-data",
  "rail-planner",
  "tool",
  "blueprint",
  "deconstruction-item",
  "blueprint-book",
  "selection-tool",
  "item-with-tags",
  "item-with-label",
  "item-with-inventory",
  "module"
}
or this item can be called as

Code: Select all

local item = 
	data.raw.item[result_name] 
	or data.raw["item-with-entity-data"][result_name] 
	or data.raw["mining-tool"][result_name] 
	or data.raw["gun"][result_name] 
	or data.raw["ammo"][result_name] 
	or data.raw["armor"][result_name] 
	or data.raw["repair-tool"][result_name] 
	or data.raw["mining-tool"][result_name] 
	or data.raw["capsule"][result_name] 
	or data.raw["fluid"][result_name] 
	or data.raw["module"][result_name] 
	or data.raw["rail-planner"][result_name] 
	or data.raw["tool"][result_name] 
	or data.raw["blueprint"][result_name] 
	or data.raw["deconstruction-item"][result_name] 
	or data.raw["blueprint-book"][result_name] 
	or data.raw["selection-tool"][result_name] 
	or data.raw["item-with-tags"][result_name] 
	or data.raw["item-with-label"][result_name] 
	or data.raw["item-with-inventory"][result_name] 
and now you can change, for example, item.stack_size

It's looks a little bit too complicated.

Bilka
Factorio Staff
Factorio Staff
Posts: 3138
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Item types

Post by Bilka »

darkfrei wrote:Hi all,

why are we have a lot of item types?
Because they each have their own specific function. You don't need iron plates to be able to have the ability to have a durability or an inventory, that would only add to the save file size and also decrease performance. So they are of a type that can't have those attributes. Here is an overview of the item types which shows what item types inherit properties from where:
Item.png
Item.png (32.26 KiB) Viewed 4020 times
darkfrei wrote: It's looks a little bit too complicated.
How is that complicated? There are a lot of types, but whenever they share attributes, those attributes are of the same format. Maybe it's annoying for the average mod author, but it's definitely not complicated to just iterate through all possible types.

Fluids aren't items btw
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Item types

Post by darkfrei »

Bilka wrote:Fluids aren't items btw
Thanks for your answer.

It was a part of function, where item was called from recipe result for checking that compared item_stack_size and result_amount.

Code: Select all

if result_amount > item.stack_size then
	item.stack_size = result_amount
end
And liquids will be ignored.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Item types

Post by eradicator »

If you already have a list of possible item types why not just iterate through it instead of that "or or or" block?

Code: Select all

local item_type_list = ... --as in opening post

local function get_item_prototype(item_name)
  for _,typ in pairs(item_type_list) do
    local prot = data.raw[typ][item_name]
    if prot then return prot end
    end
  end
  
local item = get_item_prototype(result_name)
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

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

Re: Item types

Post by bobingabout »

I suppose the most confusing thing about multiple item types is that when you want to access the item type, you need to use the extra info.

data.raw.tool["science-pack-1"].icon

Yet when you want to add it to a recipe, you only explicitly use item or fluid

{type = "item", name = "science-pack-1", amount = 1}
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Item types

Post by eradicator »

bobingabout wrote:I suppose the most confusing thing about multiple item types is that when you want to access the item type, you need to use the extra info.
I thought about this for "a bit" (and i'd better not say for how long) and i think i found an acceptable solution. Using the list of prototype types that the game internally treats as items (i.e enforces unique naming above, etc):

Code: Select all

item_types = { --index of prototype types that will be redirected to "item"
  "gun"    , "blueprint"     , "item-with-tags"        ,
  "ammo"   , "repair-tool"   , "item-with-label"       ,
  "tool"   , "mining-tool"   , "item-with-inventory"   ,
  "armor"  , "rail-planner"  , "item-with-entity-data" ,
  "module" , "blueprint-book", "deconstruction-item"   ,
  "capsule", "selection-tool"
}
We can then use the function i posted above and define it as an __index method for data.raw.item like this:

Code: Select all

local meta = getmetatable(data.raw.item) or {}
meta.__index = function(_,item_name)
  for _,typ in pairs(item_types) do
    local prot = data.raw[typ][item_name]
    if prot then return prot end
    end
  end
setmetatable(data.raw.item,meta)
The __index method is called every time we try to access data.raw.item with a key that doesn't exist, i.e. because it's of one of the other prototype types. It then searches through all the item_types and returns a pointer to the table of the item found. So we can now access all of the above types from data.raw.item:

Code: Select all

--any type listed in item_types can now be accessed like it was an "item"
data.raw.item['combat-shotgun'].attack_parameters.range = 60
print(data.raw.item["science-pack-1"].order)
Simply put above code at the start of your data.lua and it should work.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Item types

Post by darkfrei »

So, this code makes item type table, example of result [0.15.35] is in the spoiler

Code: Select all

make_item_type_table ()
	local item_type_list = {"ammo","armor","gun","item","capsule","repair-tool","mining-tool","item-with-entity-data","rail-planner","tool","blueprint","deconstruction-item","blueprint-book","selection-tool","item-with-tags","item-with-label","item-with-inventory","module"}
	item_type_table = {}
		for i, item_type_name in pairs (item_type_list) do
			for item_name, item in pairs (data.raw[item_type_name]) do
				item_type_table[item_name] = item_type_name
			end
		end
	log ('item_type_table = ' .. serpent.block(item_type_table, {comment = false}))
end
item_type_table

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Item types

Post by eradicator »

That fixed table approach will not work for any items created after you create the table. That is why my __index method looks up the prototype each time.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Post Reply

Return to “Modding discussion”