Creating an entity based of existing one

Place to get help with not working mods / modding interface.
DevilXD
Fast Inserter
Fast Inserter
Posts: 213
Joined: Tue Aug 12, 2014 10:47 am
Contact:

Creating an entity based of existing one

Post by DevilXD »

Hello ! I'm new to modding factorio, but I want to give it a shot. I've already created mods based on Lua for the Don't Starve game, so I'm familiar with the Lua code. I have a question:

I want to create a new electric furnace. Is there a way to just code this:

Code: Select all

data:extend({
  {
    -- everything else stays the same as in "electric-furnace" entity, I just want to create a new entity and override this things:
    type = "furnace",
    name = "electric-furnace-mk2",
    icon = "__base__/graphics/icons/electric-furnace.png",
    max_health = 300,
    crafting_speed = 4,
    energy_usage = "360kW",
  },
})
..., instead of copying the whole code for electric furnace and making changes to it? Something like - get the existing table of "electric-furnace" entity, copy it to another entity table with the above changes ?
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: Creating an entity based of existing one

Post by orzelek »

You can use deep copy to make a copy of existing item prototype in a way like this:

Code: Select all

local itemCopy = table.deepcopy(data.raw.item[dataMod.baseName])
It will work with entity in same way - just take data.raw.entity[name].

This needs to be done in data.lua or one of update files - thats where you have access to data.raw.
DevilXD
Fast Inserter
Fast Inserter
Posts: 213
Joined: Tue Aug 12, 2014 10:47 am
Contact:

Re: Creating an entity based of existing one

Post by DevilXD »

Well...

My first line looks like this:

Code: Select all

local ElectricFurnaceEntity = table.deepcopy(data.raw.entity["electric-furnace"])
BTW, widzę że Polacy lubią grać w Factorio ;)
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5410
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Creating an entity based of existing one

Post by Klonan »

DevilXD wrote:Well...

My first line looks like this:

Code: Select all

local ElectricFurnaceEntity = table.deepcopy(data.raw.entity["electric-furnace"])
BTW, widzę że Polacy lubią grać w Factorio ;)

try this

Code: Select all

local ElectricFurnaceEntity = table.deepcopy(data.raw["furnace"]["electric-furnace"])
DevilXD
Fast Inserter
Fast Inserter
Posts: 213
Joined: Tue Aug 12, 2014 10:47 am
Contact:

Re: Creating an entity based of existing one

Post by DevilXD »

Klonan wrote:try this

Code: Select all

local ElectricFurnaceEntity = table.deepcopy(data.raw["furnace"]["electric-furnace"])
EDIT:

That seems to work... Now... I don't know how to properly merge these...

Code: Select all

-- For merging tables
local function merge(t1, t2)
    for k, v in pairs(t2) do
        if (type(v) == "table") and (type(t1[k] or false) == "table") then
            merge(t1[k], t2[k])
        else
            t1[k] = v
        end
    end
    return t1
end

local ElectricFurnaceEntity = table.deepcopy(data.raw["furnace"]["electric-furnace"])

local ElectricFurnaceMk2 = 
{
    type = "furnace",
    name = "electric-furnace-mk2",
    icon = "__base__/graphics/icons/electric-furnace.png",
    max_health = 300,
    crafting_speed = 4,
    energy_usage = "360kW",
}

local ElectricFurnaceMk2_merged = merge(ElectricFurnaceEntity, ElectricFurnaceMk2)

data:extend({
    ElectricFurnaceMk2_merged,
})
It works ! I had to make custom merge function, but now everything works perfectly :)
Rseding91
Factorio Staff
Factorio Staff
Posts: 15913
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Creating an entity based of existing one

Post by Rseding91 »

DevilXD wrote:... It works ! I had to make custom merge function, but now everything works perfectly :)
This will get you the same effect with far less code:

Code: Select all

local MyElectricFurnaceEntity = table.deepcopy(data.raw["furnace"]["electric-furnace"])

MyElectricFurnaceEntity.name = "electric-furnace-mk2"
MyElectricFurnaceEntity.max_health = 300
MyElectricFurnaceEntity.crafting_speed = 4
MyElectricFurnaceEntity.energy_usage = "360kW"

data:extend({MyElectricFurnaceEntity})
If you want to get ahold of me I'm almost always on Discord.
DevilXD
Fast Inserter
Fast Inserter
Posts: 213
Joined: Tue Aug 12, 2014 10:47 am
Contact:

Re: Creating an entity based of existing one

Post by DevilXD »

Rseding91 wrote:This will get you the same effect with far less code:

Code: Select all

local MyElectricFurnaceEntity = table.deepcopy(data.raw["furnace"]["electric-furnace"])

MyElectricFurnaceEntity.name = "electric-furnace-mk2"
MyElectricFurnaceEntity.max_health = 300
MyElectricFurnaceEntity.crafting_speed = 4
MyElectricFurnaceEntity.energy_usage = "360kW"

data:extend({MyElectricFurnaceEntity})
Yeah, but the plan was to add Electric Furnace MK3 and MK4 later, and it simpler (at least for me) to just use my function... I've already did that, here's what my "entity-electric-furnaces" look like now (for interested and future reference, removed some stuff to make it shorter and added some comments):

Code: Select all

-- For merging tables
local function merge(t1, t2)
    for k, v in pairs(t2) do
        if (type(v) == "table") and (type(t1[k] or false) == "table") then
            merge(t1[k], t2[k])
        else
            t1[k] = v
        end
    end
    return t1
end

local ElectricFurnaceMk2 = 
{
    type = "furnace",
    name = "electric-furnace-mk2",
    icon = "__Compact_Factory__/graphics/electric_furnaces/furnace_mk2/electric-furnace-mk2-icon.png",  -- your icon path
    minable = {mining_time = 1, result = "electric-furnace-mk2"},
    max_health = 300,
    module_specification =
    {
        module_slots = 2,
        module_info_icon_shift = {0, 0.8}
    },
    animation =
    {
        filename = "__Compact_Factory__/graphics/electric_furnaces/furnace_mk2/electric-furnace-mk2.png",
    },
    crafting_speed = 4,
    energy_usage = "360kW",
    source_inventory_size = 1,
}

local ElectricFurnaceMk3 = 
{
    -- deleted stuff to make this example shorter, looked same as above
}

local ElectricFurnaceMk4 = 
{
    -- more deleted stuff
}

-- table.deepcopy separate for each merging, as Lua kept referencing to the original one
local EFMK2 = merge(table.deepcopy(data.raw["furnace"]["electric-furnace"]), ElectricFurnaceMk2)
local EFMK3 = merge(table.deepcopy(data.raw["furnace"]["electric-furnace"]), ElectricFurnaceMk3)
local EFMK4 = merge(table.deepcopy(data.raw["furnace"]["electric-furnace"]), ElectricFurnaceMk4)

data:extend({
    EFMK2,
    EFMK3,
    EFMK4,
})
Post Reply

Return to “Modding help”