| 49 | } |
| 50 | |
| 51 | void InitialGameStateExtractor::extractBuildings(GameState &state, UString bldFileName, |
| 52 | sp<City> city, bool alienBuilding) const |
| 53 | { |
| 54 | auto &data = this->ufo2p; |
| 55 | |
| 56 | auto fileName = "xcom3/ufodata/" + bldFileName + ".bld"; |
| 57 | |
| 58 | auto inFile = fw().data->fs.open(fileName); |
| 59 | if (!inFile) |
| 60 | { |
| 61 | LogError("Failed to open \"%s\"", fileName); |
| 62 | } |
| 63 | auto fileSize = inFile.size(); |
| 64 | auto bldCount = fileSize / sizeof(struct BldFileEntry); |
| 65 | |
| 66 | LogInfo("Loading %lu buildings from %s", (unsigned long)bldCount, fileName); |
| 67 | |
| 68 | for (unsigned i = 0; i < bldCount; i++) |
| 69 | { |
| 70 | struct BldFileEntry entry; |
| 71 | inFile.read((char *)&entry, sizeof(entry)); |
| 72 | |
| 73 | auto b = mksp<Building>(); |
| 74 | if (alienBuilding) |
| 75 | { |
| 76 | b->name = data.alien_building_names->get(entry.function_idx); |
| 77 | b->function = {&state, |
| 78 | format("%s%s", BuildingFunction::getPrefix(), canon_string(b->name))}; |
| 79 | LogInfo("Alien bld %d %s func %d %s", entry.name_idx, b->name, entry.function_idx, |
| 80 | b->function.id); |
| 81 | |
| 82 | b->accessTopic = {&state, format("RESEARCH_ALIEN_BUILDING_%d", i)}; |
| 83 | if (i < 9) |
| 84 | { |
| 85 | b->researchUnlock.emplace_back(&state, |
| 86 | format("RESEARCH_UNLOCK_ALIEN_BUILDING_%d", i + 1)); |
| 87 | } |
| 88 | else |
| 89 | { |
| 90 | b->victory = true; |
| 91 | } |
| 92 | |
| 93 | // Load crew |
| 94 | auto crew = ufo2p.crew_alien_building->get(entry.function_idx); |
| 95 | UFO2P::fillCrew(state, crew, b->preset_crew); |
| 96 | } |
| 97 | else |
| 98 | { |
| 99 | b->name = data.building_names->get(entry.name_idx); |
| 100 | b->function = {&state, |
| 101 | format("%s%s", BuildingFunction::getPrefix(), |
| 102 | canon_string(data.building_functions->get(entry.function_idx)))}; |
| 103 | |
| 104 | b->isPurchesable = entry.is_purchaseable; |
| 105 | b->purchasePrice = static_cast<int>(entry.price) * 2000; |
| 106 | b->maintenanceCosts = static_cast<int>(entry.maintenance_costs); |
| 107 | b->currentWorkforce = static_cast<int>(entry.current_workforce); |
| 108 | b->maximumWorkforce = static_cast<int>(entry.maximum_workforce); |