clone_entities

Post Reply
Boodals
Fast Inserter
Fast Inserter
Posts: 129
Joined: Sun Feb 11, 2018 7:10 pm
Contact:

clone_entities

Post by Boodals »

I want to clone a bunch of entities. They are typically grouped together, but not necessarily in an area that clone_area would work well on (as there may be many entities that I do not want to clone in the same area). The conditions on whether or not to clone a specific entity is complex, and so should be done on the lua side. I do not want to clone entities individually, as that would be many, many API calls, and I would have to make sure to clone entities in a specific order (which is already done in clone_area) (eg clone rails before cloning trains).

Code: Select all

surface.clone_entities(
{
	entities (array of Entity to clone)
	destination_offset (Vector, how far to move the entities)
	destination_surface (SurfaceSpecification, optional, defaults to the same surface)
})
If an entity on a different surface is given, just treat it like it's on the same surface, it shouldn't matter. Or if that can't be done for whatever reason, just throw an error or don't clone it.
It should return an array of Entity with the same indexes as the array that was passed into the function, with nils (or maybe false so that the # operator works?) where entities could not be cloned.
on_entity_cloned should be raised for each entity that was cloned.

Additionally, parameters similar to find_entities_filtered could be added to find the entities/tiles, which would essentially combine surface.clone_multiple({ entities = surface.find_entities_filtered({ ... }), ... }) into a single API call. However the overhead of cloning a bunch of entities is going to far outweigh the additional API call so it really isn't necessary.

ps: thx 4 on_entity_cloned
Last edited by Boodals on Thu Nov 15, 2018 5:51 pm, edited 1 time in total.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13209
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: clone_entities

Post by Rseding91 »

Boodals wrote:
Tue Nov 13, 2018 11:42 pm
It should return an array of Entity with the same indexes as the array that was passed into the function, with nils (or maybe false so that the # operator works?) where entities could not be cloned.
Is that useful at all if the on_entity_cloned event is fired with the cloned-from and cloned-to entities? It has non-trivial overhead to return that much data into the Lua state if nobody is going to ever read it.
If you want to get ahold of me I'm almost always on Discord.

Boodals
Fast Inserter
Fast Inserter
Posts: 129
Joined: Sun Feb 11, 2018 7:10 pm
Contact:

Re: clone_entities

Post by Boodals »

I've gone back and forth on my answer, and i'm still debating it, but I think it should be fairly easy to just use on_entity_cloned.
I could do something like this:

Code: Select all

local isCloning = false
local function doClone(surface, entities, offset)
    isCloning = true
    surface.clone_entities({entities = entities, destination_offset = offset})
    isCloning = false
end
script.on_event(defines.events.on_entity_cloned, function(event)
    if isCloning then
        doExtraStuff()
    end
end)

I guess my answer is; if the overhead of returning the data is significant compared to the overhead of actually cloning the entities, then dont bother. A lot of times it won't be needed. When it is needed, we can work around it (especially if on_entity_cloned is called in the same order as the entities array passed in, but I doubt it would be considering the cloning order).

However a better solution would be to have an additional optional parameter, which is the array to populate the entities with. If it is nil, then don't pass the data to lua, otherwise insert the cloned entities into the table.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13209
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: clone_entities

Post by Rseding91 »

The order of entity cloning is based off the order they *have* to be cloned and then the order that they where given.

So, rails always come before any rolling stock entity.
If you want to get ahold of me I'm almost always on Discord.

Boodals
Fast Inserter
Fast Inserter
Posts: 129
Joined: Sun Feb 11, 2018 7:10 pm
Contact:

Re: clone_entities

Post by Boodals »

I was thinking maybe you could do something like this to build the array of cloned entities in the same order.

Code: Select all

local sourceEntities
local clonedEntities
local function doClone(surface, entities, offset)
    sourceEntities = entities
    clonedEntities = { }
    surface.clone_entities({ entities = entities, destination_offset = offset })
end
script.on_event(defines.events.on_entity_cloned, function(event)
    local index = #clonedEntities + 1
    assert(sourceEntities[index] == event.source) --This will fail because the order entities are cloned in isn't always the order they are passed in as
    clonedEntities[index] = event.destination
end)
But yeah that wouldn't work.

Will the idea for the optional parameter to get the cloned entities array work?

Edit: Oh hey its in the implemented forum. yay!

Rseding91
Factorio Staff
Factorio Staff
Posts: 13209
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: clone_entities

Post by Rseding91 »

Boodals wrote:
Thu Nov 15, 2018 9:24 pm
Will the idea for the optional parameter to get the cloned entities array work?
No, the event includes both the source entity and the cloned result so I don't see why you would ever need to know what position it was in the original array of entities cloned.
If you want to get ahold of me I'm almost always on Discord.

Post Reply

Return to “Implemented mod requests”