Page 1 of 1

Creating an entity based of existing one

Posted: Sun Feb 21, 2016 1:31 pm
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 ?

Re: Creating an entity based of existing one

Posted: Sun Feb 21, 2016 1:57 pm
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.

Re: Creating an entity based of existing one

Posted: Sun Feb 21, 2016 5:06 pm
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 ;)

Re: Creating an entity based of existing one

Posted: Sun Feb 21, 2016 5:10 pm
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"])

Re: Creating an entity based of existing one

Posted: Sun Feb 21, 2016 5:31 pm
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 :)

Re: Creating an entity based of existing one

Posted: Mon Feb 22, 2016 5:08 pm
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})

Re: Creating an entity based of existing one

Posted: Mon Feb 22, 2016 9:00 pm
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,
})