| 285 | } |
| 286 | |
| 287 | void scan_replacements() |
| 288 | { |
| 289 | for (auto u : Units::citizensRange(world->units.active)) { |
| 290 | if (Units::isBaby(u) || |
| 291 | !Units::casteFlagSet(u->race, u->caste, df::enums::caste_raw_flags::EQUIPS)) |
| 292 | continue; // skip units we don't control or that can't wear clothes |
| 293 | |
| 294 | std::set <df::item_type> equipped; |
| 295 | std::set <df::item_type> ordered; |
| 296 | std::deque<df::item*> damaged; |
| 297 | |
| 298 | for (auto inv : u->inventory) |
| 299 | { |
| 300 | if (inv->mode != df::inv_item_role_type::Worn) |
| 301 | continue; |
| 302 | // skip non-clothing |
| 303 | if (!inv->item->isClothing()) |
| 304 | continue; |
| 305 | if (inv->item->getWear() > 0) |
| 306 | damaged.push_back(inv->item); |
| 307 | else |
| 308 | equipped.insert(inv->item->getType()); |
| 309 | } |
| 310 | |
| 311 | int usize = world->raws.creatures.all[u->race]->adultsize; |
| 312 | sizes[usize] = u->race; |
| 313 | |
| 314 | for (auto w : damaged) |
| 315 | { |
| 316 | // skip armor |
| 317 | if (w->getEffectiveArmorLevel() > 0) |
| 318 | continue; |
| 319 | |
| 320 | auto ty = w->getType(); |
| 321 | |
| 322 | auto makerRace = w->getMakerRace(); |
| 323 | if (makerRace < 0 || makerRace >= (int16_t) world->raws.creatures.all.size()) |
| 324 | continue; |
| 325 | |
| 326 | int isize = world->raws.creatures.all[makerRace]->adultsize; |
| 327 | std::string description; |
| 328 | w->getItemDescription(&description, 0); |
| 329 | |
| 330 | if (equipped.count(ty) == 0) |
| 331 | { |
| 332 | if (ordered.count(ty) == 0) |
| 333 | { |
| 334 | DEBUG(cycle).print ("tailor: {} (size {}) worn by {} (size {}) needs replacement\n", |
| 335 | DF2CONSOLE(description), isize, |
| 336 | DF2CONSOLE(Units::getReadableName(u)), usize); |
| 337 | needed[std::make_pair(ty, usize)] += 1; |
| 338 | ordered.insert(ty); |
| 339 | } |
| 340 | } |
| 341 | |
| 342 | if (confiscate && equipped.count(ty) > 0) |
| 343 | { |
| 344 | if (w->flags.bits.owned) |