How to get "owner" of an equipment grid?

Place to get help with not working mods / modding interface.
Post Reply
Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

How to get "owner" of an equipment grid?

Post by Pi-C »

We've got some events for handling changes to equipment grids: The data of all these events contain the grid and the equipment that has been added to or removed from it. However, there seems to be no way to get at the entity that grid belongs to. Any idea how to do that?

Use case: In one of my mods I must regularly check if a vehicle has a certain equipment in its grid. Currently, I call vehicle.grid.get_contents() each time I need it. I'd rather respond to on_equipment_inserted/on_equipment_removed and update my vehicle data if the equipment is something I care about. I suppose that would be more efficient than polling the grid contents all the time -- but it won't work if I don't know what entity the grid belongs to.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: How to get "owner" of an equipment grid?

Post by Pi-C »

I've just noticed that it's even worse than just calling vehicle.grid.get_contents(). It seems the mod already handles the on_player_*_equipment events, but in a terribly inefficient way:

Code: Select all

local function recheck_grid_sensors(grid)
  for _, surface in pairs(game.surfaces) do
    local cars = surface.find_entities_filtered({
      type = 'car',
    })
    for _, car in ipairs(cars) do
      if car.valid and car.grid and car.grid == grid then
        local id = car.unit_number
        global.cars[id] = global.cars[id] or {
          id = id,
          car = car,
          force = car.force,
        }
        local state = mod.cars[id]
        state.ammo_sensor = has_ammo_sensor(state.car)
        state.fuel_sensor = has_fuel_sensor(state.car)
        state.gate_sensor = has_gate_sensor(state.car)
        state.enemy_sensor = has_enemy_sensor(state.car)
        state.train_sensor = has_train_sensor(state.car)
        state.logistic_sensor = has_logistic_sensor(state.car)
        state.circuit_sensor = has_circuit_sensor(state.car)
        state.follow_sensor = has_follow_sensor(state.car)
        gui_car_publish(state)
        break
      end
    end
  end
end

local function on_player_placed_equipment(event)
  if prefixed(event.equipment.name, 'autodrive-') then
    recheck_grid_sensors(event.grid)
  end
end

local function on_player_removed_equipment(event)
  if prefixed(event.equipment, 'autodrive-') then
    recheck_grid_sensors(event.grid)
  end
end
I'd really like to change that. :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

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

Re: How to get "owner" of an equipment grid?

Post by Rseding91 »

Equipment grids do not know who 'owns' them. Mainly because they may not have any owner; they could be in a chest on some armor, or on an item sitting in a player inventory, or maybe a spidertron where it actually does own the grid.

But due to them not having any consistent owner there is no simple way to know who owns a given grid or where the grid is physically located in the world (if it even is in the world).
If you want to get ahold of me I'm almost always on Discord.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: How to get "owner" of an equipment grid?

Post by boskid »

Primary issue with finding who is an owner of EquipmentGrid is that there are 3 possible owner types: Vehicle (Entity), Armor (Item) and ItemWithEntityData (Item). There are no places in the code where an EquipmentGrid would care where it is so there are no pointers to the owner. It is possible to add an owner pointer, but it would be relatively annoying to use because it could be either an Entity (for which a LuaEntity can be given) but in case of an Item, the only reference type we have is LuaItemStack and Item may also not know in which item stack it is right now. Even if a ItemStack would be known it may still be useless because an ItemStack can be part of another Item (in case of ItemWithInventory) or it can be in the Inventory inside of an Entity, or inside of a ScriptInventory, or inside of LinkedInventory (used by linked containers). Trying to define who is an owner of an EquipmentGrid is not trivial and it is not readily available so it is not exposed anywhere. The only thing you could request is for equipment grids to have some kind of a unique ID so you could track on your own for each vehicle what is the equipment grid id so in case of an equipment changed event you would be able to find by which vehicle it is owned by or discard such event if its not owned by any of the tracked vehicles (because it is an item). There is a tiny possibility for an "owner [read]" that would return LuaEntity or nil if its not owned by an entity.

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: How to get "owner" of an equipment grid?

Post by Pi-C »

Rseding91 wrote:
Fri Jul 15, 2022 6:18 pm
Equipment grids […] could be in a chest on some armor, or on an item sitting in a player inventory, or maybe a spidertron where it actually does own the grid.
Handling items certainly would be rather difficult, but spidertrons or other entities? It should be far easier to get the LuaEntity (if there is one) a grid is associated with …


boskid wrote:
Fri Jul 15, 2022 6:20 pm
It is possible to add an owner pointer, but it would be relatively annoying to use because it could be either an Entity (for which a LuaEntity can be given) but in case of an Item, the only reference type we have is LuaItemStack and Item may also not know in which item stack it is right now.
For my use case, I'd only be interested in the owner if it is an entity.
The only thing you could request is for equipment grids to have some kind of a unique ID so you could track on your own for each vehicle what is the equipment grid id so in case of an equipment changed event you would be able to find by which vehicle it is owned by or discard such event if its not owned by any of the tracked vehicles (because it is an item).
Yes, I guess an ID would help a lot already! I could listen to one of the entity_built events and store the grid ID of new entities. This way, I wouldn't have to search on all surfaces, so it should boost performance considerably.
There is a tiny possibility for an "owner [read]" that would return LuaEntity or nil if its not owned by an entity.
Oh, that'd be perfect! No surface searches and no managing IDs, just getting the entity from the event data -- I'd be extremely happy if that tiny possibility became reality. :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: How to get "owner" of an equipment grid?

Post by boskid »

Adding an "owner" read is not likely to happen in 1.1.x branch, but for 1.1.63 i added LuaEquipmentGrid::unique_id read.

Post Reply

Return to “Modding help”