Better quickbar support for ItemWithEntityData

Post Reply
Xorimuth
Filter Inserter
Filter Inserter
Posts: 625
Joined: Sat Mar 02, 2019 9:39 pm
Contact:

Better quickbar support for ItemWithEntityData

Post by Xorimuth »

I've been trying to manipulate the quickbar, but it is quite hard to do with the current interface, which only has 4 functions related to it, of which only

Code: Select all

get_quick_bar_slot(index) → LuaItemPrototype 
and

Code: Select all

set_quick_bar_slot(index, filter)
are really useful to me.
Aim
I want to be able to swap out a vanilla spidertron remote for a modded one whilst it is in the player's hand. For this I have written the following code:

Code: Select all

local function get_previous_quickbar(player)
  local quickbar_slots = {}
  for i = 1, 100 do
    quickbar_slots[i] = player.get_quick_bar_slot(i)
  end
  return quickbar_slots
end

local function fill_in_quickbar(player, previous_quickbar, new_stack)
  for i = 1, 100 do
    if previous_quickbar[i] and not player.get_quick_bar_slot(i) then
      -- The quickbar filter has been lost since last check, therefore it contained the replaced item
      player.set_quick_bar_slot(i, new_stack)
    end
  end
end
]]

local function convert_remote(stack, old_name, new_name, player)
  if stack and stack.valid_for_read and stack.name == old_name then
    local connected_spidertron = stack.connected_entity
    local previous_quickbar = get_previous_quickbar(player)
    stack.set_stack{name=new_name, count=1}
    stack.connected_entity = connected_spidertron
    fill_in_quickbar(player, previous_quickbar, stack)
  end
end
`convert_remote` correctly replaces the remote with a new remote and transfers the `connected_entity`. Without `get_previous_quickbar` and `fill_in_quickbar`, if the old remote was in the player's quickbar, then it would just be removed.
Requested features
1. A way to get all quickbar slot indexes connected to a specific item, such as `LuaItemStack.get_quickbar_slots() -> array of numbers`
I've managed to get around this for my usecase by writing `get_previous_quickbar()` to store the contents of every quickbar slot, and then after the switch `fill_in_quickbar` iterates through the new quickbar contents, and any slots that are now empty and weren't previously are assumed to have been belonging to the old item.
Note that similar to point 2 below, this is made much harder by the fact that I cannot tell from get_quick_bar_slot() if that slot is connected to a specific spidertron remote, I can only tell if it is a spidertron remote. If I could tell which spidertron remote it was, then I wouldn't need this feature as much because I'd only have to iterate through the quickbar slot indexes once, which seems much more sensible.

2. `player.set_quick_bar_slot(i, new_stack)` does not work correctly for items such as spidertron remotes. Even though I am passing in a LuaItemStack instead of a LuaItemPrototype, it is only interpreted as a generic prototype, so it behaves really weirdly (because spidertron remotes don't really have a 'generic' state.
Related: 68374

For reference: my mod https://mods.factorio.com/mod/SpidertronWaypoints, specifically https://github.com/tburrows13/Spidertro ... lua#L1-L40
My mods
Content: Freight Forwarding | Spidertron Patrols | Spidertron Enhancements | Power Overload
QoL: Factory Search | Remote Configuration | Module Inserter Simplified | Wire Shortcuts X | Ghost Warnings

Xorimuth
Filter Inserter
Filter Inserter
Posts: 625
Joined: Sat Mar 02, 2019 9:39 pm
Contact:

Re: Better quickbar support for ItemWithEntityData

Post by Xorimuth »

On further investigation of point 2, it appears that LuaItemStack.item_number is the crucial thing that is not being passed into set_quick_bar_slot(). I'm inclined to say that this is actually a bug.
My mods
Content: Freight Forwarding | Spidertron Patrols | Spidertron Enhancements | Power Overload
QoL: Factory Search | Remote Configuration | Module Inserter Simplified | Wire Shortcuts X | Ghost Warnings

Xorimuth
Filter Inserter
Filter Inserter
Posts: 625
Joined: Sat Mar 02, 2019 9:39 pm
Contact:

Re: Better quickbar support for ItemWithEntityData

Post by Xorimuth »

I've managed to solve this one for my usecase almost perfectly by storing the original item into a temporary inventory and then replacing the item in hand with the new item. This preserves the quickbar shortcut for the original item (it just becomes greyed out).

I'd still appreciate proper quickbar support for items with LuaItemStack.item_number.
My mods
Content: Freight Forwarding | Spidertron Patrols | Spidertron Enhancements | Power Overload
QoL: Factory Search | Remote Configuration | Module Inserter Simplified | Wire Shortcuts X | Ghost Warnings

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

Re: Better quickbar support for ItemWithEntityData

Post by Rseding91 »

I've fixed #2 for the next release. #1 I don't quite understand.
If you want to get ahold of me I'm almost always on Discord.

Xorimuth
Filter Inserter
Filter Inserter
Posts: 625
Joined: Sat Mar 02, 2019 9:39 pm
Contact:

Re: Better quickbar support for ItemWithEntityData

Post by Xorimuth »

Thanks for the reply, that is great to hear! With #2 implemented, I can cover my usecase perfectly, though it would still be a little hacky without #1. I'll try and explain #1 better:

I have an item in my cursor and I want to get all the quick bar slots that link to it. If my cursor item does not have item_number, this is simple: iterate from 1 to 100, call player.get_quick_bar_slot(i) and compare the cursor_stack.name with the returned LuaItemPrototype.name. Store the indexes that match.

The issue is when the item has the item_number property: unless you've changed it so that player.get_quick_bar_slot(i) returns the item_number of that item, there is no way of distinguishing between (e.g.) spidertron remotes on the quickbar. So, I cannot perfectly match the cursor_stack with the quickbar slots that are connected to it.

That's the problem. I have a solution for my usecase that I stated in the original post: I store every value from the quickbar in a table by iterating over it. Then I delete the item in the cursor, at which point all quickbar references to that item are deleted. I then iterate through every quickbar slot a second time, comparing it to table stored from the first time. If an item has disappeared, then I know that it was pointing to my specific spidertron remote. This actually works really well for me, but only because I do actually want to delete the item. If I just moved it to a different inventory, the quickbar connection would stay, and just be greyed out.

Adding `LuaItemStack.get_quickbar_slots() -> array of indexes corresponding to quickbar slots that point to the LuaItemStack (specifically adhering to item_number)` would make all this a lot easier.

As I said though, with #2 implemented, my personal needs are fulfilled. Thank you!
My mods
Content: Freight Forwarding | Spidertron Patrols | Spidertron Enhancements | Power Overload
QoL: Factory Search | Remote Configuration | Module Inserter Simplified | Wire Shortcuts X | Ghost Warnings

Post Reply

Return to “Implemented mod requests”