Specifically, any "if (verbose) { Core::printerr("blah") }" kind
of stuff definitely doesn't belong in the common API functions.
Also, ref->getUnit() is very expensive.
On the other hand, checks for crash-inducing conflicts with the
ui should be in the core api, and not in client plugins.
if(verbose){Core::printerr("Item %d is not clothing or armor; it cannot be equipped. Please choose a different item (or use the Ignore option if you really want to equip an inappropriate item).\n",item->id);}
if(verbose){Core::printerr("Item %d is of an unrecognized type; it cannot be equipped (because the module wouldn't know where to put it).\n",item->id);}
returnfalse;
}
elseif(itemOwner&&itemOwner->id!=unit->id)
{
if(verbose){Core::printerr("Item %d is owned by someone else. Equipping it on this unit is not recommended. Please use DFHack's Confiscate plugin, choose a different item, or use the Ignore option to proceed in spite of this warning.\n",item->id);}
returnfalse;
}
elseif(item->flags.bits.in_inventory)
{
if(verbose){Core::printerr("Item %d is already in a unit's inventory. Direct inventory transfers are not recommended; please move the item to the ground first (or use the Ignore option).\n",item->id);}
if(verbose){Core::printerr("Item %d is reserved for use in a queued job. Equipping it is not recommended, as this might interfere with the completion of vital jobs. Use the Ignore option to ignore this warning.\n",item->id);}
Core::printerr("Could not allocate UNIT_HOLDER reference.\n");
returnfalse;
}
// ASSERT: anti-requisite conditions have been satisfied (or disregarded)
// Step 2: Try to find a bodypart which is eligible to receive equipment AND which is appropriate for the specified item
// Short-circuit the search process if a BP was specified in the function call
// Note: this causes a bit of inefficient busy-looping, but the search space is tiny (<100) and we NEED to get the correct bpIndex value in order to perform inventory manipulations
if(!targetBodyPart)
{
// The function call did not specify any particular body part; proceed with normal iteration and evaluation of BP eligibility
}
elseif(currPart==targetBodyPart)
{
// A specific body part was included in the function call, and we've found it; proceed with the normal BP evaluation (suitability, emptiness, etc)
// The current body part is not the one that was specified in the function call, but we can keep searching
if(verbose){Core::printerr("Found bodypart %s; not a match; continuing search.\n",currPart->part_code.c_str());}
continue;
}
else
{
// The specified body part has not been found, and we've reached the end of the list. Report failure.
if(verbose){Core::printerr("The specified body part (%s) does not belong to the chosen unit. Please double-check to ensure that your spelling is correct, and that you have not chosen a dismembered bodypart.\n");}
if(verbose){Core::print("Foot found (%s)...",currPart->part_code.c_str());}
}
elseif(targetBodyPart&&ignoreRestrictions)
{
// The BP in question would normally be considered ineligible for equipment. But since it was deliberately specified by the user, we'll proceed anyways.
if(verbose){Core::print("Non-standard bodypart found (%s)...",targetBodyPart->part_code.c_str());}
}
elseif(targetBodyPart)
{
// The BP in question is not eligible for equipment and the ignore flag was not specified. Report failure.
if(verbose){Core::printerr("Non-standard bodypart found, but it is ineligible for standard equipment. Use the Ignore flag to override this warning.\n");}
// This body part is not eligible for the equipment in question; skip it
continue;
}
// ASSERT: The current body part is able to support the specified equipment (or the test has been overridden). Check whether it is currently empty/available.
if(multiEquipLimit==INT_MAX)
{
// Note: this loop/check is skipped if the MultiEquip option is specified; we'll simply add the item to the bodyPart even if it's already holding a dozen gloves, shoes, and millstones (or whatever)
if(verbose){Core::printerr(" but it already carries %d piece(s) of equipment. Either remove the existing equipment or use the Multi option.\n",multiEquipLimit);}
// This body part is not eligible to receive the specified equipment; return to the loop and check the next BP
continue;
}
else
{
// A specific body part was designated in the function call, but it was found to be ineligible.
// Don't return to the BP loop; just fall-through to the failure-reporting code a few lines below.
break;
}
}
}
if(!confirmedBodyPart){
// No matching body parts found; report failure
if(verbose){Core::printerr("\nThe item could not be equipped because the relevant body part(s) of the unit are missing or already occupied. Try again with the Multi option if you're like to over-equip a body part, or choose a different unit-item combination (e.g. stop trying to put shoes on a trout).\n");}
deleteholderReference;
returnfalse;
}
// ASSERT: We've found a bodypart which is suitable for the designated item and ready to receive it (or overridden the relevant checks)
item->flags.bits.in_inventory=true;
// Step 3: Perform the manipulations
if(verbose){Core::print("equipping item...");}
// 3a: attempt to release the item from its current position
if(!detachItem(mc,item))
{
if(verbose){Core::printerr("\nEquipping failed - failed to retrieve item from its current location/container/inventory. Please move it to the ground and try again.\n");}
if(verbose){Core::print("Item is clothing/armor; protection aspects have been enabled.\n");}
}
else
{
if(verbose){Core::print("Item is neither clothing nor armor; unit has NOT been instructed to \"use\" it as such.\n");}
}
// 3e: Remove the item from its current location (note: if this step is skipped then the item will appear BOTH on the ground and in the unit's inventory)
if(inventoryDumpingSkipped){out.printerr("Some inventory items could not be autodumped because the unit/inventory screen is currently active. Please close the unit screen and repeat the operation.\n");}
out.print("Done. %d items %s.\n",dumped_total,destroy?"marked for destruction":"quickdumped");
if(verbose){Core::printerr("Item %d is not clothing or armor; it cannot be equipped. Please choose a different item (or use the Ignore option if you really want to equip an inappropriate item).\n",item->id);}
if(verbose){Core::printerr("Item %d is of an unrecognized type; it cannot be equipped (because the module wouldn't know where to put it).\n",item->id);}
returnfalse;
}
elseif(itemOwner&&itemOwner->id!=unit->id)
{
if(verbose){Core::printerr("Item %d is owned by someone else. Equipping it on this unit is not recommended. Please use DFHack's Confiscate plugin, choose a different item, or use the Ignore option to proceed in spite of this warning.\n",item->id);}
returnfalse;
}
elseif(item->flags.bits.in_inventory)
{
if(verbose){Core::printerr("Item %d is already in a unit's inventory. Direct inventory transfers are not recommended; please move the item to the ground first (or use the Ignore option).\n",item->id);}
returnfalse;
}
elseif(item->flags.bits.in_job)
{
if(verbose){Core::printerr("Item %d is reserved for use in a queued job. Equipping it is not recommended, as this might interfere with the completion of vital jobs. Use the Ignore option to ignore this warning.\n",item->id);}
returnfalse;
}
// ASSERT: anti-requisite conditions have been satisfied (or disregarded)
// Step 2: Try to find a bodypart which is eligible to receive equipment AND which is appropriate for the specified item
// Short-circuit the search process if a BP was specified in the function call
// Note: this causes a bit of inefficient busy-looping, but the search space is tiny (<100) and we NEED to get the correct bpIndex value in order to perform inventory manipulations
if(!targetBodyPart)
{
// The function call did not specify any particular body part; proceed with normal iteration and evaluation of BP eligibility
}
elseif(currPart==targetBodyPart)
{
// A specific body part was included in the function call, and we've found it; proceed with the normal BP evaluation (suitability, emptiness, etc)
// The current body part is not the one that was specified in the function call, but we can keep searching
if(verbose){Core::printerr("Found bodypart %s; not a match; continuing search.\n",currPart->part_code.c_str());}
continue;
}
else
{
// The specified body part has not been found, and we've reached the end of the list. Report failure.
if(verbose){Core::printerr("The specified body part (%s) does not belong to the chosen unit. Please double-check to ensure that your spelling is correct, and that you have not chosen a dismembered bodypart.\n");}
if(verbose){Core::print("Foot found (%s)...",currPart->part_code.c_str());}
}
elseif(targetBodyPart&&ignoreRestrictions)
{
// The BP in question would normally be considered ineligible for equipment. But since it was deliberately specified by the user, we'll proceed anyways.
if(verbose){Core::print("Non-standard bodypart found (%s)...",targetBodyPart->part_code.c_str());}
}
elseif(targetBodyPart)
{
// The BP in question is not eligible for equipment and the ignore flag was not specified. Report failure.
if(verbose){Core::printerr("Non-standard bodypart found, but it is ineligible for standard equipment. Use the Ignore flag to override this warning.\n");}
// This body part is not eligible for the equipment in question; skip it
continue;
}
// ASSERT: The current body part is able to support the specified equipment (or the test has been overridden). Check whether it is currently empty/available.
if(multiEquipLimit==INT_MAX)
{
// Note: this loop/check is skipped if the MultiEquip option is specified; we'll simply add the item to the bodyPart even if it's already holding a dozen gloves, shoes, and millstones (or whatever)
if(verbose){Core::printerr(" but it already carries %d piece(s) of equipment. Either remove the existing equipment or use the Multi option.\n",multiEquipLimit);}
// This body part is not eligible to receive the specified equipment; return to the loop and check the next BP
continue;
}
else
{
// A specific body part was designated in the function call, but it was found to be ineligible.
// Don't return to the BP loop; just fall-through to the failure-reporting code a few lines below.
break;
}
}
}
if(!confirmedBodyPart){
// No matching body parts found; report failure
if(verbose){Core::printerr("\nThe item could not be equipped because the relevant body part(s) of the unit are missing or already occupied. Try again with the Multi option if you're like to over-equip a body part, or choose a different unit-item combination (e.g. stop trying to put shoes on a trout).\n");}
if(verbose){Core::printerr("\nEquipping failed - failed to retrieve item from its current location/container/inventory. Please move it to the ground and try again.\n");}