protect against bad tree data

develop
Myk Taylor 2023-02-03 12:52:50 -08:00
parent 972df67eee
commit f2521c4a5c
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
1 changed files with 73 additions and 43 deletions

@ -327,17 +327,24 @@ static bool is_protected(const df::plant * plant, PersistentDataItem &c) {
}
static int32_t estimate_logs(const df::plant *plant) {
if (!plant->tree_info)
return 0;
//adapted from code by aljohnston112 @ github
df::plant_tree_tile** tiles = plant->tree_info->body;
df::plant_tree_tile* tilesRow;
int trunks = 0;
if (!tiles)
return 0;
int32_t trunks = 0;
const int32_t area = plant->tree_info->dim_y * plant->tree_info->dim_x;
for (int i = 0; i < plant->tree_info->body_height; i++) {
tilesRow = tiles[i];
for (int j = 0; j < plant->tree_info->dim_y*plant->tree_info->dim_x; j++) {
df::plant_tree_tile* tilesRow = tiles[i];
if (!tilesRow)
return 0; // tree data is corrupt; let's not touch it
for (int j = 0; j < area; j++)
trunks += tilesRow[j].bits.trunk;
}
}
return trunks;
}
@ -386,41 +393,19 @@ static void bucket_watched_burrows(color_ostream & out,
typedef multimap<int, df::plant *, std::greater<int>> TreesBySize;
// returns the number of trees that were newly marked
static int32_t scan_trees(color_ostream & out, int32_t *expected_yield,
static int32_t scan_tree(color_ostream & out, df::plant *plant, int32_t *expected_yield,
TreesBySize *designatable_trees_by_size, bool designate_clearcut,
const vector<df::unit *> &citizens, int32_t *accessible_trees = NULL,
int32_t *inaccessible_trees = NULL, int32_t *designated_trees = NULL,
int32_t *accessible_yield = NULL,
map<int32_t, int32_t> *tree_counts = NULL,
map<int32_t, int32_t> *designated_tree_counts = NULL) {
TRACE(cycle,out).print("scanning trees\n");
int32_t newly_marked = 0;
if (accessible_trees)
*accessible_trees = 0;
if (inaccessible_trees)
*inaccessible_trees = 0;
if (designated_trees)
*designated_trees = 0;
if (expected_yield)
*expected_yield = 0;
if (accessible_yield)
*accessible_yield = 0;
if (tree_counts)
tree_counts->clear();
if (designated_tree_counts)
designated_tree_counts->clear();
map<int, PersistentDataItem *> clearcut_burrows, chop_burrows;
bucket_watched_burrows(out, clearcut_burrows, chop_burrows);
for (auto plant : world->plants.all) {
const vector<df::unit *> &citizens, int32_t *accessible_trees,
int32_t *inaccessible_trees, int32_t *designated_trees, int32_t *accessible_yield,
map<int32_t, int32_t> *tree_counts,
map<int32_t, int32_t> *designated_tree_counts,
map<int, PersistentDataItem *> &clearcut_burrows,
map<int, PersistentDataItem *> &chop_burrows) {
TRACE(cycle,out).print(" scanning tree at %d,%d,%d\n",
plant->pos.x, plant->pos.y, plant->pos.z);
if (!is_valid_tree(plant))
continue;
return 0;
bool accessible = is_accessible_tree(plant->pos, citizens);
int32_t yield = estimate_logs(plant);
@ -441,9 +426,10 @@ static int32_t scan_trees(color_ostream & out, int32_t *expected_yield,
bucket_tree(plant, designate_clearcut, &designated, &can_chop, tree_counts,
designated_tree_counts, clearcut_burrows, chop_burrows);
int32_t ret = 0;
if (designated) {
if (!was_designated)
++newly_marked;
ret = 1;
if (designated_trees)
++*designated_trees;
if (expected_yield)
@ -452,7 +438,51 @@ static int32_t scan_trees(color_ostream & out, int32_t *expected_yield,
if (designatable_trees_by_size)
designatable_trees_by_size->emplace(yield, plant);
}
}
return ret;
}
// returns the number of trees that were newly marked
static int32_t scan_trees(color_ostream & out, int32_t *expected_yield,
TreesBySize *designatable_trees_by_size, bool designate_clearcut,
const vector<df::unit *> &citizens, int32_t *accessible_trees = NULL,
int32_t *inaccessible_trees = NULL, int32_t *designated_trees = NULL,
int32_t *accessible_yield = NULL,
map<int32_t, int32_t> *tree_counts = NULL,
map<int32_t, int32_t> *designated_tree_counts = NULL) {
TRACE(cycle,out).print("scanning trees\n");
int32_t newly_marked = 0;
if (accessible_trees)
*accessible_trees = 0;
if (inaccessible_trees)
*inaccessible_trees = 0;
if (designated_trees)
*designated_trees = 0;
if (expected_yield)
*expected_yield = 0;
if (accessible_yield)
*accessible_yield = 0;
if (tree_counts)
tree_counts->clear();
if (designated_tree_counts)
designated_tree_counts->clear();
map<int, PersistentDataItem *> clearcut_burrows, chop_burrows;
bucket_watched_burrows(out, clearcut_burrows, chop_burrows);
for (auto plant : world->plants.tree_dry)
newly_marked += scan_tree(out, plant, expected_yield, designatable_trees_by_size,
designate_clearcut, citizens, accessible_trees,
inaccessible_trees, designated_trees, accessible_yield,
tree_counts, designated_tree_counts,
clearcut_burrows, chop_burrows);
for (auto plant : world->plants.tree_wet)
newly_marked += scan_tree(out, plant, expected_yield, designatable_trees_by_size,
designate_clearcut, citizens, accessible_trees,
inaccessible_trees, designated_trees, accessible_yield,
tree_counts, designated_tree_counts,
clearcut_burrows, chop_burrows);
return newly_marked;
}