| 495 | } |
| 496 | |
| 497 | static bool recover_job(color_ostream &out, ProtectedJob *pj) |
| 498 | { |
| 499 | if (pj->isLive()) |
| 500 | return true; |
| 501 | |
| 502 | // Check that the building exists |
| 503 | pj->holder = df::building::find(pj->building_id); |
| 504 | if (!pj->holder) |
| 505 | { |
| 506 | out.printerr("Forgetting job {} ({}): holder building lost.\n", |
| 507 | pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); |
| 508 | forget_job(out, pj); |
| 509 | return true; |
| 510 | } |
| 511 | |
| 512 | // Check its state and postpone or cancel if invalid |
| 513 | if (pj->holder->jobs.size() >= 10) |
| 514 | { |
| 515 | out.printerr("Forgetting job {} ({}): holder building has too many jobs.\n", |
| 516 | pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); |
| 517 | forget_job(out, pj); |
| 518 | return true; |
| 519 | } |
| 520 | |
| 521 | if (!pj->holder->jobs.empty()) |
| 522 | { |
| 523 | df::job_type ftype = pj->holder->jobs[0]->job_type; |
| 524 | if (ftype == job_type::DestroyBuilding) |
| 525 | return false; |
| 526 | |
| 527 | if (ENUM_ATTR(job_type,type,ftype) == job_type_class::StrangeMood) |
| 528 | return false; |
| 529 | } |
| 530 | |
| 531 | // Create and link in the actual job structure |
| 532 | df::job *recovered = Job::cloneJobStruct(pj->job_copy); |
| 533 | |
| 534 | if (!Job::linkIntoWorld(recovered, false)) // reuse same id |
| 535 | { |
| 536 | Job::deleteJobStruct(recovered); |
| 537 | |
| 538 | out.printerr("Inconsistency: job {} ({}) already in list.\n", |
| 539 | pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); |
| 540 | return true; |
| 541 | } |
| 542 | |
| 543 | pj->holder->jobs.push_back(recovered); |
| 544 | |
| 545 | // Done |
| 546 | pj->recover(recovered); |
| 547 | return true; |
| 548 | } |
| 549 | |
| 550 | static void check_lost_jobs(color_ostream &out, int ticks) |
| 551 | { |
no test coverage detected