using util.merge how does it works?

Place to get help with not working mods / modding interface.
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 11:19 am I have another question
Did you mean to ask another question, here?
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Adamo wrote: Mon Sep 16, 2019 11:58 am Did you mean to ask another question, here?
Yeah, can i write all my questions down here or how should i handle this?

my next question is, like in the tutorial of the wiki.factorio there is this code

Code: Select all

--item.lua

local fireArmor = table.deepcopy(data.raw.armor["heavy-armor"])

fireArmor.name = "fire-armor"
fireArmor.icons= {
   {
      icon=fireArmor.icon,
      tint={r=1,g=0,b=0,a=0.3}
   },
}

fireArmor.resistances = {
   {
      type = "physical",
      decrease = 6,
      percent = 10
   },
   {
      type = "explosion",
      decrease = 10,
      percent = 30
   },
   {
      type = "acid",
      decrease = 5,
      percent = 30
   },
   {
      type = "fire",
      decrease = 0,
      percent = 100
   },
}

local recipe = table.deepcopy(data.raw.recipe["heavy-armor"])
recipe.enabled = true
recipe.name = "fire-armor"
recipe.ingredients = {{"copper-plate",200},{"steel-plate",50}}
recipe.result = "fire-armor"

data:extend{fireArmor,recipe}
I try to understand how can i use this for my situation. Do i have to create the last part too?

Code: Select all

local recipe = table.deepcopy(data.raw.recipe["heavy-armor"])
recipe.enabled = true
recipe.name = "fire-armor"
recipe.ingredients = {{"copper-plate",200},{"steel-plate",50}}
recipe.result = "fire-armor"
because, actually i have an entity.lua,item.lua,recipes.lua and technology.lua , where all are separated. In this case like above is there still a recipes.lua needed or can i put all parts together in one file?
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 4:47 pm
I'm not sure which part is the "last part" you mean. In the entity prototype, the "result", which is the item you get when you mine the entity, goes inside the minable table. What you really need to do is look, here: https://wiki.factorio.com/Prototype/Entity

That contains all the possible data values you can put in an entity, and you need to change any of them that matter to you.

Compare that with armor: https://wiki.factorio.com/Prototype/Armor
And with recipe: https://wiki.factorio.com/Prototype/Recipe

These pages contain everything you can possible set on your entity, armor, or recipe prototype, and you can look up the other prototypes on that wiki, too. So you just need to figure out which things you want to set, and to what.

You code does not contain a data:extend() line, so if this is the "last part" you meant, then yes, you would need to do that, because that's the part that actually takes the data you've created and loads it into the game.

It doesn't matter what files you use, as long as they have an associated require() line in your data.lua, data-updates.lua, or data-final-fixes.lua. You could put all the code in those files, or put the code in separate files and use require() lines to reference the other files; doesn't matter.
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Code: Select all

--item.lua

local fireArmor = table.deepcopy(data.raw.armor["heavy-armor"])

fireArmor.name = "fire-armor"
fireArmor.icons= {
   {
      icon=fireArmor.icon,
      tint={r=1,g=0,b=0,a=0.3}
   },
}

fireArmor.resistances = {
   {
      type = "physical",
      decrease = 6,
      percent = 10
   },
   {
      type = "explosion",
      decrease = 10,
      percent = 30
   },
   {
      type = "acid",
      decrease = 5,
      percent = 30
   },
   {
      type = "fire",
      decrease = 0,
      percent = 100
   },
}

local recipe = table.deepcopy(data.raw.recipe["heavy-armor"])
recipe.enabled = true
recipe.name = "fire-armor"
recipe.ingredients = {{"copper-plate",200},{"steel-plate",50}}
recipe.result = "fire-armor"

data:extend{fireArmor,recipe}
With last part i mean the part where
local recipe = table.deepcopy(data.raw.recipe["heavy-armor"]) starts. i mean here it creates a recipe, that belongs to the item right?

Edit: and can i put all like tech,item,recipe and entity together using the local deepcopy element? in one lua?
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

OK, I see what you mean. You can just create your own recipe from scratch, or you can create one by copying another recipe.

Typically, if I'm making an alternate version of an existing item, I make the recipe and the item from scratch, and then deepcopy the vanilla entity and apply changes to make the entity. All that matters is that you have a recipe, item, and entity, with the appropriate names and the settings you want, loaded into the game using data:extend(). How you get there is up to you.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: using util.merge how does it works?

Post by eradicator »

Palaber1984 wrote: Mon Sep 16, 2019 5:04 pm Edit: and can i put all like tech,item,recipe and entity together using the local deepcopy element? in one lua?
The filenames and directory structure of your mod are entirely up to you and have no influence on the data structure.
TL;DR: Yes.
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
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Would you agree so far i did it like this?

Code: Select all

--prototypes/entity.lua


local sep1 = table.deepcopy(data.raw["electric-pole"]["small-electric-pole"])
	sep1.name = "small-electric-pole",
	sep1.minable = {mining_time = 0.1, result = "small-electric-pole"},
	sep1.max_health = 50,
	sep1.maximum_wire_distance = 7.5,
	sep1.supply_area_distance = 2.5,


local sep2 = table.deepcopy(data.raw["electric-pole"]["small-electric-pole"])
	sep2.name = "small-electric-pole-2",
	sep2.minable = {mining_time = 0.1, result = "small-electric-pole-2"},
	sep2.max_health = 50,
	sep2.maximum_wire_distance = 16,
	sep2.supply_area_distance = 1.5,

local mep1 = table.deepcopy(data.raw["electric-pole"]["medium-electric-pole"])
	mep1.name = "medium-electric-pole",
	mep1.minable = {mining_time = 0.1, result = "medium-electric-pole"},
	mep1.max_health = 100,
	mep1.maximum_wire_distance = 9,
	mep1.supply_area_distance = 3.5,
	
local mep2 = table.deepcopy(data.raw["electric-pole"]["medium-electric-pole"])
	mep2.name = "medium-electric-pole-2",
	mep2.minable = {mining_time = 0.1, result = "medium-electric-pole-2"},
	mep2.max_health = 100,
	mep2.maximum_wire_distance = 14,
	mep2.supply_area_distance = 6.5,

local bep1 = table.deepcopy(data.raw["electric-pole"]["big-electric-pole"])
	bep1.name = "big-electric-pole",
	bep1.minable = {mining_time = 0.1, result = "big-electric-pole"},
	bep1.max_health = 250,
	bep1.maximum_wire_distance = 30,
	bep1.supply_area_distance = 2,

local bep2 = table.deepcopy(data.raw["electric-pole"]["big-electric-pole"])
	bep2.name = "big-electric-pole-2",
	bep2.minable = {mining_time = 0.1, result = "big-electric-pole-2"},
	bep2.max_health = 250,
	bep2.maximum_wire_distance = 30,
	bep2.supply_area_distance = 4,
	
local bep3 = table.deepcopy(data.raw["electric-pole"]["big-electric-pole"])
	bep3.name = "big-electric-pole-3",
	bep3.minable = {mining_time = 1, result = "big-electric-pole-3"},
	bep3.max_health = 2000,
	bep3.maximum_wire_distance = 64,
	bep3.supply_area_distance = 1,	

local sub1 = table.deepcopy(data.raw["electric-pole"]["substation"])
	sub1.name = "substation",
	sub1.minable = {mining_time = 0.1, result = "substation"},
	sub1.max_health = 250,
	sub1.maximum_wire_distance = 18,
	sub1.supply_area_distance = 9,	

local sub2 = table.deepcopy(data.raw["electric-pole"]["substation"])
	sub2.name = "substation-2",
	sub2.minable = {mining_time = 0.1, result = "substation-2"},
	sub2.max_health = 250,
	sub2.maximum_wire_distance = 58,
	sub2.supply_area_distance = 7,
	
local sub3 = table.deepcopy(data.raw["electric-pole"]["substation"])
	sub3.name = "substation-3",
	sub3.minable = {mining_time = 0.1, result = "substation-3"},
	sub3.max_health = 500,
	sub3.maximum_wire_distance = 8,
	sub3.supply_area_distance = 64,


data:extend{sep1,sep2,mep1,mep2,bep1,bep2,bep3,sub1,sub2,sub3}
i get this error after loading the game
https://drive.google.com/open?id=1-lN0_ ... wTZtYPl53K

But if look at the code, there isnt anything wrong
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Oh, the problem is you have a comma hanging off the end of one of your lines. Each of those statements is a separate operation, so they shouldn't be separated by commas.
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Code: Select all

minable = {mining_time = 0.1, result = "small-electric-pole"},
You mean that comma before result?

It is strange because, in my orignal entity is like above and the game is running

Edit:
i have deleted all commas like this and get another error

Code: Select all

local sep1 = table.deepcopy(data.raw["electric-pole"]["small-electric-pole"])
	  sep1.name = "small-electric-pole"
	  sep1.minable = {mining_time = 0.1 result = "small-electric-pole"}
	  sep1.max_health = 50
	  sep1.maximum_wire_distance = 7.5
	  sep1.supply_area_distance = 2.5
https://drive.google.com/open?id=1Acxgu ... V1lJQ6b2Gd
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 6:01 pm
I think you're having trouble with understanding the difference between creating a table all at once and taking an existing table, then changing individual entries.

Look, it's like this. You can have a table, like

Code: Select all

local table =
{
	thing1 = "foo",
	thing2 = "yo",
	thing3 = "bar"
}
But now if I want to take that existing table and CHANGE it, I typically do this one piece at a time...

Code: Select all

local table2 = util.table.deepcopy(table)
table2.thing2 = "notyo"
Now table2 is

Code: Select all

{
	thing1 = "foo",
	thing2 = "notyo",
	thing3 = "bar"
}
And if I wanted to change more, I have to do it one value at a time...

Code: Select all

table2.thing3 = table2.thing1
table2.thing1 = "bar"
table2.newthing = "new"
which means I would now have, in table2,

Code: Select all

{
	thing1 = "bar",
	thing2 = "notyo",
	thing3 = "foo",
	newthing = "new"
}
So, you see, I am doing the entries one at time in a sequence of imperative statements, rather than constructing the entire table at once. When making the table all at once, you separate the entries with commas. A series of imperative statements is just separated by line breaks. When you deepcopy, you're doing it the "imperative statements" way.
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

ah ok, when creating a table then with comma, and when changing a table then without.

BTW, my mod runs now with this short way,
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 6:32 pm ah ok, when creating a table then with comma, and when changing a table then without.

BTW, my mod runs now with this short way,
Exactly. And congratulations!
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Adamo wrote: Mon Sep 16, 2019 6:34 pm
Palaber1984 wrote: Mon Sep 16, 2019 6:32 pm ah ok, when creating a table then with comma, and when changing a table then without.

BTW, my mod runs now with this short way,
Exactly. And congratulations!
thx, but now my next big thing is coming :)
before that, why you have use util in your code?
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 6:36 pm
Uhh, well, that's where the deepcopy function comes from, I think... util.table.deepcopy(). I assume you have access to it just using table.deepcopy() because somewhere along the way, in some data file somewhere, either in another mod or in the base mod, there is a line that says "table = util.table", or something similar. But I don't know for sure.
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

Ah makes sense. btw i try to read the Lua manual in german, because i live in german and even in german it seems more complicated to read and understand it, then make a mod here.

So, how about deleting code segments of an entity? is that possible in the same operation with the deepcopy part?
Adamo
Filter Inserter
Filter Inserter
Posts: 481
Joined: Sat May 24, 2014 7:00 am
Contact:

Re: using util.merge how does it works?

Post by Adamo »

Palaber1984 wrote: Mon Sep 16, 2019 7:03 pm
Deepcopy makes a NEW TABLE that is a COPY of the table you fed to it. So anything you delete in the new table will only be deleted in the new table. To delete an entry in the table you just do something like

Code: Select all

local table2 = util.table.deepcopy(table)
table2.thing2 = nil
That removed the value at "thing2", so the table2 would now only read

Code: Select all

{
	thing1 = "foo",
	thing3 = "bar"
}
But it did NOT change the original table, it only changed table2. So if you're doing this to make new game data, that's why you now have to take table2 and run data:extend() on it to load it into the game. If you wanted to remove data from existing game objects, you can do that directly, too, but it is dangerous and should only be done if you know exactly what you are doing.
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

So i am preparing a detail explanation about what i try to achieve

Edit: This code is a original Part of the small-electric-pole in the entity.lua in the base folder

Code: Select all

  {
    type = "electric-pole",
    name = "small-electric-pole",
    icon = "__base__/graphics/icons/small-electric-pole.png",
    icon_size = 32,
    flags = {"placeable-neutral", "player-creation", "fast-replaceable-no-build-while-moving"},
    minable = {mining_time = 0.1, result = "small-electric-pole"},
    max_health = 50,
    corpse = "small-electric-pole-remnants",
    collision_box = {{-0.15, -0.15}, {0.15, 0.15}},
    selection_box = {{-0.4, -0.4}, {0.4, 0.4}},
    drawing_box = {{-0.5, -2.6}, {0.5, 0.5}},
    maximum_wire_distance = 7.5,
    supply_area_distance = 2.5,
    vehicle_impact_sound =  { filename = "__base__/sound/car-wood-impact.ogg", volume = 1.0 },
    track_coverage_during_build_by_moving = true,
    fast_replaceable_group = "electric-pole",
    pictures =
    {
      layers =
      {
        {
          filename = "__base__/graphics/entity/small-electric-pole/small-electric-pole.png",
          priority = "extra-high",
          width = 36,
          height = 108,
          direction_count = 4,
          shift = util.by_pixel(2, -42),
          hr_version =
          {
            filename = "__base__/graphics/entity/small-electric-pole/hr-small-electric-pole.png",
            priority = "extra-high",
            width = 72,
            height = 220,
            direction_count = 4,
            shift = util.by_pixel(1.5, -42.5),
            scale = 0.5
          }
        },
        {
          filename = "__base__/graphics/entity/small-electric-pole/small-electric-pole-shadow.png",
          priority = "extra-high",
          width = 130,
          height = 28,
          direction_count = 4,
          shift = util.by_pixel(50, 2),
          draw_as_shadow = true,
          hr_version =
          {
            filename = "__base__/graphics/entity/small-electric-pole/hr-small-electric-pole-shadow.png",
            priority = "extra-high",
            width = 256,
            height = 52,
            direction_count = 4,
            shift = util.by_pixel(51, 3),
            draw_as_shadow = true,
            scale = 0.5
          }
        }
      }
    },
    connection_points =
    {
      {
        shadow =
        {
          copper = util.by_pixel(98.5, 2.5),
          red = util.by_pixel(111.0, 4.5),
          green = util.by_pixel(85.5, 4.0)
        },
        wire =
        {
          copper = util.by_pixel(0.0, -82.5),
          red = util.by_pixel(13.0, -81.0),
          green = util.by_pixel(-12.5, -81.0)
        }
      },
      {
        shadow =
        {
          copper = util.by_pixel(99.5, 4.0),
          red = util.by_pixel(110.0, 9.0),
          green = util.by_pixel(92.5, -4.0)
        },
        wire =
        {
          copper = util.by_pixel(1.5, -81.0),
          red = util.by_pixel(12.0, -76.0),
          green = util.by_pixel(-6.0, -89.5)
        }
      },
      {
        shadow =
        {
          copper = util.by_pixel(100.5, 5.5),
          red = util.by_pixel(102.5, 14.5),
          green = util.by_pixel(103.5, -3.5)
        },
        wire =
        {
          copper = util.by_pixel(2.5, -79.5),
          red = util.by_pixel(4.0, -71.0),
          green = util.by_pixel(5.0, -89.5)
        }
      },
      {
        shadow =
        {
          copper = util.by_pixel(98.5, -1.5),
          red = util.by_pixel(88.0, 3.5),
          green = util.by_pixel(106.0, -9.0)
        },
        wire =
        {
          copper = util.by_pixel(0.5, -86.5),
          red = util.by_pixel(-10.5, -81.5),
          green = util.by_pixel(8.0, -93.5)
        }
      }
    },
    radius_visualisation_picture =
    {
      filename = "__base__/graphics/entity/small-electric-pole/electric-pole-radius-visualization.png",
      width = 12,
      height = 12,
      priority = "extra-high-no-scale"
    }
  },
And what i want is that the game doesnt rotate the pole. Therefor i just have to change the part where

Code: Select all

direction_count = 4,
is four times, into direction count 1, because there are one for lower graphics, one for lower shadows, one for HD graphics and one for HD shadows. Means 4 times

And thats not all, to run the game i have to remove 3 of 4 connection points. therefore i remove the last 3 once and the first stays, means i remove this part

Code: Select all

{
        shadow =
        {
          copper = util.by_pixel(99.5, 4.0),
          red = util.by_pixel(110.0, 9.0),
          green = util.by_pixel(92.5, -4.0)
        },
        wire =
        {
          copper = util.by_pixel(1.5, -81.0),
          red = util.by_pixel(12.0, -76.0),
          green = util.by_pixel(-6.0, -89.5)
        }
      },
      {
        shadow =
        {
          copper = util.by_pixel(100.5, 5.5),
          red = util.by_pixel(102.5, 14.5),
          green = util.by_pixel(103.5, -3.5)
        },
        wire =
        {
          copper = util.by_pixel(2.5, -79.5),
          red = util.by_pixel(4.0, -71.0),
          green = util.by_pixel(5.0, -89.5)
        }
      },
      {
        shadow =
        {
          copper = util.by_pixel(98.5, -1.5),
          red = util.by_pixel(88.0, 3.5),
          green = util.by_pixel(106.0, -9.0)
        },
        wire =
        {
          copper = util.by_pixel(0.5, -86.5),
          red = util.by_pixel(-10.5, -81.5),
          green = util.by_pixel(8.0, -93.5)
        }
      }
any ideas?
User avatar
Palaber1984
Inserter
Inserter
Posts: 32
Joined: Sat Feb 16, 2019 10:09 am
Contact:

Re: using util.merge how does it works?

Post by Palaber1984 »

So i try it to my self.

i added into my deepcopy this line

Code: Select all

sep1.pictures = {layers = {{direction_count = 1, {direction_count = 1}}, direction_count = 1, {direction_count = 1}}}
i looked for this part right here, it is the picture section of the entity

Code: Select all

    pictures =
    {
      layers =
      {
        {
          filename = "__base__/graphics/entity/small-electric-pole/small-electric-pole.png",
          priority = "extra-high",
          width = 36,
          height = 108,
          direction_count = 4,
          shift = util.by_pixel(2, -42),
          hr_version =
          {
            filename = "__base__/graphics/entity/small-electric-pole/hr-small-electric-pole.png",
            priority = "extra-high",
            width = 72,
            height = 220,
            direction_count = 4,
            shift = util.by_pixel(1.5, -42.5),
            scale = 0.5
          }
        },
        {
          filename = "__base__/graphics/entity/small-electric-pole/small-electric-pole-shadow.png",
          priority = "extra-high",
          width = 130,
          height = 28,
          direction_count = 4,
          shift = util.by_pixel(50, 2),
          draw_as_shadow = true,
          hr_version =
          {
            filename = "__base__/graphics/entity/small-electric-pole/hr-small-electric-pole-shadow.png",
            priority = "extra-high",
            width = 256,
            height = 52,
            direction_count = 4,
            shift = util.by_pixel(51, 3),
            draw_as_shadow = true,
            scale = 0.5
          }
        }
      }
    },
after loading the game i got this
https://drive.google.com/open?id=1lNNHb ... SnjfT_qSP-

i expected any error, but now i dont know how to go on
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: using util.merge how does it works?

Post by eradicator »

Palaber1984 wrote: Tue Sep 17, 2019 12:25 pm

Code: Select all

sep1.pictures = {layers = {{direction_count = 1, {direction_count = 1}}, direction_count = 1, {direction_count = 1}}}
You're overwriting the whole table.

The internet offers many tutorials on generic lua programming and table handling. And a well made tutorial could teach you more faster than anyone here on the forum. The forum is meant for factorio-specific help, not for personal programming lessons.
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 help”