CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.26k stars 4.12k forks source link

Interrupted disassembly creates new item if continued by NPC #75628

Open Antrocon opened 1 month ago

Antrocon commented 1 month ago

Describe the bug

If NPC continues previously interrupted item disassembly, final result is a new intact item instead of components. Very annoying for items with long disassembly times, like appliances, load-bering vests, etc: basically you cannot use NPCs to disassemble them as any sneeze during 2+h disassembly process will interrupt it.

Attach save file

N/A

Steps to reproduce

  1. Create PC & NPC follower with tailor's kit & kevlar shears
  2. Spawn load bearing vest, create "disassemble items" zone
  3. Order NPC to disassemble items
  4. Wait for NPC to start (for "in-progress" item to appear), interrupt him
  5. Order NPC to work on craft & select "in-progress" item
  6. Wait for NPC to finish. Wut?

Expected behavior

Continued disassembly should result in disassembled item with some materials recovered, not a new intact item.

Screenshots

dis1 dis2

Versions and configuration

Additional context

No response

Antrocon commented 1 month ago

Cooperton-trimmed.tar.gz save with reproduced example

PatrikLundell commented 1 month ago

/Confirmed

The load bearing vest is "deconstructed" into itself even if the in-progress item is placed back into the zone and disassembly work is ordered. Getting the vest out of the companion's hands was tricky, because it wasn't available in the trade menu. I had to order the wielding of the gun to have the in-progress item moved into the inventory and then "trade" for it.

Edit: You can't use the load bearing vest present, because it's been "contaminated" into thinking it's constructed from itself. A debug spawned load bearing vest deconstructs normally when an uninterrupted deconstruction is performed (the contaminated one results in itself), but an interrupted and resumed task via the crafting order does indeed result in the item itself. In contrast, a debug spawned vest placed into the zone and the companion ordered to deconstruct it, wait a tick, interrupt the companion, go through the dance to get the in-progress item and place it back into the zone and then an order to deconstruct items results in the item being deconstructed.

It seems deconstruction only works using the deconstruction order, while selecting an in-progress deconstruction task via the crafting interface doesn't. At a guess, the crafting interface assigning a task of ACT_MULTIPLE_CRAFT when called via the crafting interface, but probably ACT_MULTIPLE_DIS via the disassembly order might explain the difference.

I can think of three approaches:

If the first approach was used, it would be useful to expand the disassembly order to also consider in-progress disassembly items in the hands and in the inventory, as well as on an adjacent workbench.

Edit 2: You can achieve the first approach by adding an operation to the "item" class e.g. called "is_disassembly" that checks whether the itemcraft pointer is non null and, if so, its referenced disassembly field is true, and then add a check to verify a matching item isn't a disassembly in crafting.cpp operation npc::do_npc_craft. This causes in-progress disassembly items to be removed from the set of in-progress items that can be resumed when ordering a companion to craft. Thus, if you wanted to resume disassembly you'd have to move the in-progress item back into the zone and then order disassembly again. I haven't found where to redirect crafting to disassembly for an in-progress disassembly for the third approach. I won't progress this further, so if someone is interested, feel free to tackle this.