Merge pull request #3319 from myk002/myk_accessible

[buildingplan] check items for accessibility for dialogs
develop
Myk 2023-04-27 02:29:13 -07:00 committed by GitHub
commit 719c47cf5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 23 deletions

@ -38,6 +38,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Fixes
- `autoclothing`: eliminate game lag when there are many inventory items in the fort
- `buildingplan`: fixed size limit calculations for rollers
- `buildingplan`: fixed items not being checked for accessibility in the filter and item selection dialogs
- `dig-now`: properly detect and complete smoothing designations that have been converted into active jobs
## Misc Improvements

@ -704,7 +704,7 @@ static int scanAvailableItems(color_ostream &out, df::building_type type, int16_
filter.setMaterials(set<MaterialInfo>());
special.clear();
}
if (itemPassesScreen(item) && matchesFilters(item, jitem, heat, filter, special)) {
if (itemPassesScreen(out, item) && matchesFilters(item, jitem, heat, filter, special)) {
if (item_ids)
item_ids->emplace_back(item->id);
if (counts) {

@ -54,7 +54,7 @@ void set_config_val(DFHack::PersistentDataItem &c, int index, int value);
void set_config_bool(DFHack::PersistentDataItem &c, int index, bool value);
std::vector<df::job_item_vector_id> getVectorIds(DFHack::color_ostream &out, const df::job_item *job_item, bool ignore_filters);
bool itemPassesScreen(df::item * item);
bool itemPassesScreen(DFHack::color_ostream& out, df::item* item);
df::job_item getJobItemWithHeatSafety(const df::job_item *job_item, HeatSafety heat);
bool matchesFilters(df::item * item, const df::job_item * job_item, HeatSafety heat, const ItemFilter &item_filter, const std::set<std::string> &special);
bool isJobReady(DFHack::color_ostream &out, const std::vector<df::job_item *> &jitems);

@ -43,10 +43,27 @@ struct BadFlags {
}
};
bool itemPassesScreen(df::item * item) {
// This is tricky. we want to choose an item that can be brought to the job site, but that's not
// necessarily the same as job->pos. it could be many tiles off in any direction (e.g. for bridges), or
// up or down (e.g. for stairs). For now, just return if the item is on a walkable tile.
static bool isAccessible(color_ostream& out, df::item* item) {
df::coord item_pos = Items::getPosition(item);
df::map_block* block = Maps::getTileBlock(item_pos);
bool is_walkable = false;
if (block) {
uint16_t walkability_group = index_tile(block->walkable, item_pos);
is_walkable = walkability_group != 0;
TRACE(cycle, out).print("item %d in walkability_group %u at (%d,%d,%d) is %saccessible from job site\n",
item->id, walkability_group, item_pos.x, item_pos.y, item_pos.z, is_walkable ? "(probably) " : "not ");
}
return is_walkable;
}
bool itemPassesScreen(color_ostream& out, df::item* item) {
static const BadFlags bad_flags;
return !(item->flags.whole & bad_flags.whole)
&& !item->isAssignedToStockpile();
&& !item->isAssignedToStockpile()
&& isAccessible(out, item);
}
df::job_item getJobItemWithHeatSafety(const df::job_item *job_item, HeatSafety heat) {
@ -165,22 +182,6 @@ static df::building * popInvalidTasks(color_ostream &out, Bucket &task_queue,
return NULL;
}
// This is tricky. we want to choose an item that can be brought to the job site, but that's not
// necessarily the same as job->pos. it could be many tiles off in any direction (e.g. for bridges), or
// up or down (e.g. for stairs). For now, just return if the item is on a walkable tile.
static bool isAccessibleFrom(color_ostream &out, df::item *item, df::job *job) {
df::coord item_pos = Items::getPosition(item);
df::map_block *block = Maps::getTileBlock(item_pos);
bool is_walkable = false;
if (block) {
uint16_t walkability_group = index_tile(block->walkable, item_pos);
is_walkable = walkability_group != 0;
TRACE(cycle,out).print("item %d in walkability_group %u at (%d,%d,%d) is %saccessible from job site\n",
item->id, walkability_group, item_pos.x, item_pos.y, item_pos.z, is_walkable ? "" : "not ");
}
return is_walkable;
}
static void doVector(color_ostream &out, df::job_item_vector_id vector_id,
map<string, Bucket> &buckets,
unordered_map<int32_t, PlannedBuilding> &planned_buildings,
@ -195,7 +196,7 @@ static void doVector(color_ostream &out, df::job_item_vector_id vector_id,
item_it != item_vector.rend();
++item_it) {
auto item = *item_it;
if (!itemPassesScreen(item))
if (!itemPassesScreen(out, item))
continue;
for (auto bucket_it = buckets.begin(); bucket_it != buckets.end(); ) {
TRACE(cycle,out).print("scanning bucket: %s/%s\n",
@ -218,8 +219,7 @@ static void doVector(color_ostream &out, df::job_item_vector_id vector_id,
auto filter_idx = task.second;
const int rev_filter_idx = num_filters - (filter_idx+1);
auto &pb = planned_buildings.at(id);
if (isAccessibleFrom(out, item, job)
&& matchesFilters(item, jitems[filter_idx], pb.heat_safety,
if (matchesFilters(item, jitems[filter_idx], pb.heat_safety,
pb.item_filters[rev_filter_idx], pb.specials)
&& Job::attachJobItem(job, item,
df::job_item_ref::Hauled, filter_idx))