-
Notifications
You must be signed in to change notification settings - Fork 217
Fix state inconsistency in uniform-unstick #1490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
cdf3ebb
fb3f2d1
0831e6e
5b4072e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ local validArgs = utils.invert({ | |
-- Functions | ||
|
||
local function item_description(item) | ||
return dfhack.df2console(dfhack.items.getDescription(item, 0, true)) | ||
return "item #" .. item.id .. " '" .. dfhack.df2console(dfhack.items.getDescription(item, 0, true)) .. "'" | ||
end | ||
|
||
local function get_item_pos(item) | ||
|
@@ -166,11 +166,10 @@ local function process(unit, args, need_newline) | |
for u_id, item in pairs(assigned_items) do | ||
if not worn_items[u_id] then | ||
if not silent then | ||
need_newline = print_line(unit_name .. " is missing an assigned item, object #" .. u_id .. " '" .. | ||
item_description(item) .. "'", need_newline) | ||
need_newline = print_line(unit_name .. " is missing an assigned item, " .. item_description(item), need_newline) | ||
end | ||
if dfhack.items.getGeneralRef(item, df.general_ref_type.UNIT_HOLDER) then | ||
need_newline = print_line(unit_name .. " cannot equip item: another unit has a claim on object #" .. u_id .. " '" .. item_description(item) .. "'", need_newline) | ||
need_newline = print_line(unit_name .. " cannot equip item: another unit has a claim on " .. item_description(item), need_newline) | ||
if args.free then | ||
print(" Removing from uniform") | ||
assigned_items[u_id] = nil | ||
|
@@ -196,6 +195,22 @@ local function process(unit, args, need_newline) | |
end | ||
end | ||
|
||
-- Make the equipment.assigned_items list consistent with what is present in equipment.uniform | ||
for i=#(squad_position.equipment.assigned_items)-1,0,-1 do | ||
local u_id = squad_position.equipment.assigned_items[i] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I'll just say that I don't like the variable name
I know it's used above, but even considering that, you're using it for a slightly different meaning. Above it means that an item is in the I mean, it works, it's just not as clear as it could be. And this script really needs some clarity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that |
||
-- Quiver, backpack, and flask are assigned in their own locations rather than in equipment.uniform, and thus need their own checks | ||
-- If more separately-assigned items are added in the future, this handling will need to be updated accordingly | ||
if assigned_items[u_id] == nil and u_id ~= squad_position.equipment.quiver and u_id ~= squad_position.equipment.backpack and u_id ~= squad_position.equipment.flask then | ||
local item = df.item.find(u_id) | ||
if item ~= nil then | ||
need_newline = print_line(unit_name .. " has an improperly assigned item, " .. item_description(item) .. '; removing it') | ||
else | ||
need_newline = print_line(unit_name .. " has a nonexistent item assigned, item # " .. u_id .. '; removing it') | ||
end | ||
squad_position.equipment.assigned_items:erase(i) | ||
end | ||
end | ||
|
||
-- Figure out which worn items should be dropped | ||
|
||
-- First, figure out which body parts are covered by the uniform pieces we have. | ||
|
@@ -224,9 +239,7 @@ local function process(unit, args, need_newline) | |
for w_id, item in pairs(worn_items) do | ||
if assigned_items[w_id] == nil then -- don't drop uniform pieces (including shields, weapons for hands) | ||
if uncovered[worn_parts[w_id]] then | ||
need_newline = print_line(unit_name .. | ||
" potentially has object #" .. | ||
w_id .. " '" .. item_description(item) .. "' blocking a missing uniform item.", need_newline) | ||
need_newline = print_line(unit_name .. " potentially has " .. item_description(item) .. " blocking a missing uniform item.", need_newline) | ||
if args.drop then | ||
to_drop[w_id] = item | ||
end | ||
|
@@ -245,12 +258,12 @@ local function do_drop(item_list) | |
for id, item in pairs(item_list) do | ||
local pos = get_item_pos(item) | ||
if not pos then | ||
dfhack.printerr("Could not find drop location for item #" .. id .. " " .. item_description(item)) | ||
dfhack.printerr("Could not find drop location for " .. item_description(item)) | ||
else | ||
if dfhack.items.moveToGround(item, pos) then | ||
print("Dropped item #" .. id .. " '" .. item_description(item) .. "'") | ||
print("Dropped " .. item_description(item)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should use the EDIT: no, it makes no difference here. That's gonna be a rant by itself. |
||
else | ||
dfhack.printerr("Could not drop object #" .. id .. " " .. item_description(item)) | ||
dfhack.printerr("Could not drop " .. item_description(item)) | ||
end | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider extending
item_description()
to gracefully handle the case of a nonexistent item.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unclear on what you mean here by the "case of a nonexistent item"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The case handled on line 208. Literally
df.item.find()
returnednil
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no "valid" response to being asked to describe a null item; the correct response is for the function to throw, which is what it currently does
callers are expected to check for nil or be prepared to accept a throw if they do not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a cursory scan through the code and I think
item
will never be null on calls to this function, but I am not at all sure of that. If you're confident that this code will never be called withitem
as null, it's enough to document thatitem
must never be null. Otherwise, add a test for item being null to this code and provide an appropriate alternative. Otherwise, the script will abort with an exception, which will generally be confusing to users (as most people never look at the console and thus won't see the exception).