Updating uniform-unstick to unassign items from the global list#1563
Updating uniform-unstick to unassign items from the global list#1563jczpqf wants to merge 1 commit intoDFHack:masterfrom
Conversation
When then uniform-unstick command is run it can unassign items from the squad but it does not remove them from the global assigned items datastructure. This can cause items to be assigned but not to any existing squad.
There was a problem hiding this comment.
I'm going to request that this PR not be merged.
(Edit: however I am interested in the code you mention that resolves orphaned equipment. I'd like to look at the logic you're using, to see if it matches my own. ( https://gist.github.com/ is GitHub's equivalent of pastebin. )
This is conceptually good, and the bug it addresses is real, it is one of the reasons that items_assigned.* and items_unassigned.* get out-of-sync with actual uniform assignment.
A minor issue with this code is that it only adds the item id to items_unassigned.* if it successfully removed it from items_assigned.*. I have seen cases where an item is part of a uniform but the id is in neither of the tracking vectors. That's easy enough to fix.
A major issue with this code is that this function is called when the script has detected a double-assigned item, and is removing one of the assignments. In this case, the item id should remain in items_assigned.*.
That issue is obscured by a bug: the test for double-assignment (line 193 in the current file or line 203 in this patched file) is wrong.
if dfhack.items.getGeneralRef(item, df.general_ref_type.UNIT_HOLDER) thenThis test assumes that the item is assigned to the unit carrying it. This can have both false-positives and false-negatives. It should be testing the squad.position[].equipment.uniform.*.*.* nested data structures, which are canonical.
In my own analysis of items_(un)assigned,*, I decided that I don't care how it gets out of sync. Instead, I decided to fully rebuild it from the canonical data.
I have this rebuild code working, but I need to get more stat tracking into it to make sure I haven't missed or misinterpreted something obscure. Then I intend to merge it into uniform-unstick.
I also plan to fix the bug discussed above, separate the report into a summary section and a details section, and add caching for df.item.find() and perhaps df.unit.find().
I've been moving slow on this, partly because of distractions and partly because of illness. But I'll get it done soon.
When then uniform-unstick command is run it can unassign items from the squad but it does not remove them from the global items_assigned datastructure. This can cause items to be assigned but not to any existing squad.
If this occurs in game you can see this by attempting to assign a specific piece of equipment to a dwarf in a squad. Through this menu you can see existing equipment that is already assigned. Equipment that is assigned mentions the squad and the position. Equipment that are in the global items_assigned seem to show up as "assigned" but have no mention of a squad or position. I don't think it is possible to assign these pieces of equipment in game without a script. At first I thought maybe this was a vanilla DF bug, it could still be, but I'm pretty sure this script can cause it frequently too. These changes will not fix equipment that have already been stuck in this state. I have a separate simple plugin that looks for equipment that is assigned but not to a squad and resolves existing "orphaned" equipment. I can make a pull request for that as well if that is desired and appropriate.
I've played a while with the script updated and it seemed to resolve the issue.
I have not contributed to this project before... Feedback is very welcome.