diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ap_state.cpp | 87 | ||||
| -rw-r--r-- | src/ap_state.h | 6 | ||||
| -rw-r--r-- | src/area_popup.cpp | 4 | ||||
| -rw-r--r-- | src/game_data.cpp | 113 | ||||
| -rw-r--r-- | src/game_data.h | 7 | ||||
| -rw-r--r-- | src/tracker_panel.cpp | 10 | ||||
| -rw-r--r-- | src/tracker_state.cpp | 20 | ||||
| -rw-r--r-- | src/tracker_state.h | 2 |
8 files changed, 143 insertions, 106 deletions
| diff --git a/src/ap_state.cpp b/src/ap_state.cpp index ced4f83..8bc7ed0 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp | |||
| @@ -52,11 +52,6 @@ struct APState { | |||
| 52 | std::set<int64_t> checked_locations; | 52 | std::set<int64_t> checked_locations; |
| 53 | std::map<std::string, bool> data_storage; | 53 | std::map<std::string, bool> data_storage; |
| 54 | 54 | ||
| 55 | std::map<std::tuple<int, int>, int64_t> ap_id_by_location_id; | ||
| 56 | std::map<std::string, int64_t> ap_id_by_item_name; | ||
| 57 | std::map<LingoColor, int64_t> ap_id_by_color; | ||
| 58 | std::map<int64_t, std::string> progressive_item_by_ap_id; | ||
| 59 | |||
| 60 | DoorShuffleMode door_shuffle_mode = kNO_DOORS; | 55 | DoorShuffleMode door_shuffle_mode = kNO_DOORS; |
| 61 | bool color_shuffle = false; | 56 | bool color_shuffle = false; |
| 62 | bool painting_shuffle = false; | 57 | bool painting_shuffle = false; |
| @@ -302,78 +297,18 @@ struct APState { | |||
| 302 | } | 297 | } |
| 303 | 298 | ||
| 304 | if (connected) { | 299 | if (connected) { |
| 305 | for (const MapArea& map_area : GD_GetMapAreas()) { | ||
| 306 | for (int section_id = 0; section_id < map_area.locations.size(); | ||
| 307 | section_id++) { | ||
| 308 | const Location& location = map_area.locations.at(section_id); | ||
| 309 | |||
| 310 | int64_t ap_id = apclient->get_location_id(location.ap_location_name); | ||
| 311 | if (ap_id == APClient::INVALID_NAME_ID) { | ||
| 312 | TrackerLog("Could not find AP location ID for " + | ||
| 313 | location.ap_location_name); | ||
| 314 | } else { | ||
| 315 | ap_id_by_location_id[{map_area.id, section_id}] = ap_id; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | for (const Door& door : GD_GetDoors()) { | ||
| 321 | if (!door.skip_item) { | ||
| 322 | ap_id_by_item_name[door.item_name] = GetItemId(door.item_name); | ||
| 323 | |||
| 324 | if (!door.group_name.empty() && | ||
| 325 | !ap_id_by_item_name.count(door.group_name)) { | ||
| 326 | ap_id_by_item_name[door.group_name] = GetItemId(door.group_name); | ||
| 327 | } | ||
| 328 | |||
| 329 | for (const ProgressiveRequirement& prog_req : door.progressives) { | ||
| 330 | ap_id_by_item_name[prog_req.item_name] = | ||
| 331 | GetItemId(prog_req.item_name); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | ap_id_by_color[LingoColor::kBlack] = GetItemId("Black"); | ||
| 337 | ap_id_by_color[LingoColor::kRed] = GetItemId("Red"); | ||
| 338 | ap_id_by_color[LingoColor::kBlue] = GetItemId("Blue"); | ||
| 339 | ap_id_by_color[LingoColor::kYellow] = GetItemId("Yellow"); | ||
| 340 | ap_id_by_color[LingoColor::kPurple] = GetItemId("Purple"); | ||
| 341 | ap_id_by_color[LingoColor::kOrange] = GetItemId("Orange"); | ||
| 342 | ap_id_by_color[LingoColor::kGreen] = GetItemId("Green"); | ||
| 343 | ap_id_by_color[LingoColor::kBrown] = GetItemId("Brown"); | ||
| 344 | ap_id_by_color[LingoColor::kGray] = GetItemId("Gray"); | ||
| 345 | |||
| 346 | RefreshTracker(); | 300 | RefreshTracker(); |
| 347 | } else { | 301 | } else { |
| 348 | client_active = false; | 302 | client_active = false; |
| 349 | } | 303 | } |
| 350 | } | 304 | } |
| 351 | 305 | ||
| 352 | bool HasCheckedGameLocation(int area_id, int section_id) { | 306 | bool HasCheckedGameLocation(int location_id) { |
| 353 | std::tuple<int, int> location_key = {area_id, section_id}; | 307 | return checked_locations.count(location_id); |
| 354 | |||
| 355 | if (ap_id_by_location_id.count(location_key)) { | ||
| 356 | return checked_locations.count(ap_id_by_location_id.at(location_key)); | ||
| 357 | } else { | ||
| 358 | return false; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | bool HasColorItem(LingoColor color) { | ||
| 363 | if (ap_id_by_color.count(color)) { | ||
| 364 | return inventory.count(ap_id_by_color.at(color)); | ||
| 365 | } else { | ||
| 366 | return false; | ||
| 367 | } | ||
| 368 | } | 308 | } |
| 369 | 309 | ||
| 370 | bool HasItem(const std::string& item, int quantity) { | 310 | bool HasItem(int item_id, int quantity) { |
| 371 | if (ap_id_by_item_name.count(item)) { | 311 | return inventory.count(item_id) && inventory.at(item_id) >= quantity; |
| 372 | int64_t ap_id = ap_id_by_item_name.at(item); | ||
| 373 | return inventory.count(ap_id) && inventory.at(ap_id) >= quantity; | ||
| 374 | } else { | ||
| 375 | return false; | ||
| 376 | } | ||
| 377 | } | 312 | } |
| 378 | 313 | ||
| 379 | bool HasAchievement(const std::string& name) { | 314 | bool HasAchievement(const std::string& name) { |
| @@ -417,16 +352,12 @@ void AP_Connect(std::string server, std::string player, std::string password) { | |||
| 417 | GetState().Connect(server, player, password); | 352 | GetState().Connect(server, player, password); |
| 418 | } | 353 | } |
| 419 | 354 | ||
| 420 | bool AP_HasCheckedGameLocation(int area_id, int section_id) { | 355 | bool AP_HasCheckedGameLocation(int location_id) { |
| 421 | return GetState().HasCheckedGameLocation(area_id, section_id); | 356 | return GetState().HasCheckedGameLocation(location_id); |
| 422 | } | 357 | } |
| 423 | 358 | ||
| 424 | bool AP_HasColorItem(LingoColor color) { | 359 | bool AP_HasItem(int item_id, int quantity) { |
| 425 | return GetState().HasColorItem(color); | 360 | return GetState().HasItem(item_id, quantity); |
| 426 | } | ||
| 427 | |||
| 428 | bool AP_HasItem(const std::string& item, int quantity) { | ||
| 429 | return GetState().HasItem(item, quantity); | ||
| 430 | } | 361 | } |
| 431 | 362 | ||
| 432 | DoorShuffleMode AP_GetDoorShuffleMode() { return GetState().door_shuffle_mode; } | 363 | DoorShuffleMode AP_GetDoorShuffleMode() { return GetState().door_shuffle_mode; } |
| @@ -451,6 +382,8 @@ bool AP_IsLocationVisible(int classification) { | |||
| 451 | return classification & kLOCATION_REDUCED; | 382 | return classification & kLOCATION_REDUCED; |
| 452 | case kPANELSANITY: | 383 | case kPANELSANITY: |
| 453 | return classification & kLOCATION_INSANITY; | 384 | return classification & kLOCATION_INSANITY; |
| 385 | default: | ||
| 386 | return false; | ||
| 454 | } | 387 | } |
| 455 | } | 388 | } |
| 456 | 389 | ||
| diff --git a/src/ap_state.h b/src/ap_state.h index e9b9f92..64caeea 100644 --- a/src/ap_state.h +++ b/src/ap_state.h | |||
| @@ -18,11 +18,9 @@ void AP_SetTrackerFrame(TrackerFrame* tracker_frame); | |||
| 18 | 18 | ||
| 19 | void AP_Connect(std::string server, std::string player, std::string password); | 19 | void AP_Connect(std::string server, std::string player, std::string password); |
| 20 | 20 | ||
| 21 | bool AP_HasCheckedGameLocation(int area_id, int section_id); | 21 | bool AP_HasCheckedGameLocation(int location_id); |
| 22 | 22 | ||
| 23 | bool AP_HasColorItem(LingoColor color); | 23 | bool AP_HasItem(int item_id, int quantity = 1); |
| 24 | |||
| 25 | bool AP_HasItem(const std::string& item, int quantity = 1); | ||
| 26 | 24 | ||
| 27 | DoorShuffleMode AP_GetDoorShuffleMode(); | 25 | DoorShuffleMode AP_GetDoorShuffleMode(); |
| 28 | 26 | ||
| diff --git a/src/area_popup.cpp b/src/area_popup.cpp index 28554d0..0657ea3 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp | |||
| @@ -57,8 +57,8 @@ void AreaPopup::UpdateIndicators() { | |||
| 57 | container_sizer->Show(eye_indicators_[section_id]); | 57 | container_sizer->Show(eye_indicators_[section_id]); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | bool checked = AP_HasCheckedGameLocation(area_id_, section_id); | 60 | bool checked = AP_HasCheckedGameLocation(location.ap_location_id); |
| 61 | bool reachable = IsLocationReachable(area_id_, section_id); | 61 | bool reachable = IsLocationReachable(location.ap_location_id); |
| 62 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | 62 | const wxColour* text_color = reachable ? wxWHITE : wxRED; |
| 63 | 63 | ||
| 64 | section_labels_[section_id]->SetForegroundColour(*text_color); | 64 | section_labels_[section_id]->SetForegroundColour(*text_color); |
| diff --git a/src/game_data.cpp b/src/game_data.cpp index 06eb80a..f51d7ac 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp | |||
| @@ -30,7 +30,10 @@ LingoColor GetColorForString(const std::string &str) { | |||
| 30 | } else if (str == "purple") { | 30 | } else if (str == "purple") { |
| 31 | return LingoColor::kPurple; | 31 | return LingoColor::kPurple; |
| 32 | } else { | 32 | } else { |
| 33 | std::cout << "Invalid color: " << str << std::endl; | 33 | std::ostringstream errmsg; |
| 34 | errmsg << "Invalid color: " << str; | ||
| 35 | TrackerLog(errmsg.str()); | ||
| 36 | |||
| 34 | return LingoColor::kNone; | 37 | return LingoColor::kNone; |
| 35 | } | 38 | } |
| 36 | } | 39 | } |
| @@ -52,6 +55,8 @@ struct GameData { | |||
| 52 | 55 | ||
| 53 | std::vector<int> achievement_panels_; | 56 | std::vector<int> achievement_panels_; |
| 54 | 57 | ||
| 58 | std::map<LingoColor, int> ap_id_by_color_; | ||
| 59 | |||
| 55 | bool loaded_area_data_ = false; | 60 | bool loaded_area_data_ = false; |
| 56 | std::set<std::string> malconfigured_areas_; | 61 | std::set<std::string> malconfigured_areas_; |
| 57 | 62 | ||
| @@ -59,6 +64,31 @@ struct GameData { | |||
| 59 | YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml"); | 64 | YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml"); |
| 60 | YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml"); | 65 | YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml"); |
| 61 | YAML::Node pilgrimage_config = YAML::LoadFile("assets/pilgrimage.yaml"); | 66 | YAML::Node pilgrimage_config = YAML::LoadFile("assets/pilgrimage.yaml"); |
| 67 | YAML::Node ids_config = YAML::LoadFile("assets/ids.yaml"); | ||
| 68 | |||
| 69 | auto init_color_id = [this, &ids_config](const std::string &color_name) { | ||
| 70 | if (ids_config["special_items"] && | ||
| 71 | ids_config["special_items"][color_name]) { | ||
| 72 | std::string input_name = color_name; | ||
| 73 | input_name[0] = std::tolower(input_name[0]); | ||
| 74 | ap_id_by_color_[GetColorForString(input_name)] = | ||
| 75 | ids_config["special_items"][color_name].as<int>(); | ||
| 76 | } else { | ||
| 77 | std::ostringstream errmsg; | ||
| 78 | errmsg << "Missing AP item ID for color " << color_name; | ||
| 79 | TrackerLog(errmsg.str()); | ||
| 80 | } | ||
| 81 | }; | ||
| 82 | |||
| 83 | init_color_id("Black"); | ||
| 84 | init_color_id("Red"); | ||
| 85 | init_color_id("Blue"); | ||
| 86 | init_color_id("Yellow"); | ||
| 87 | init_color_id("Green"); | ||
| 88 | init_color_id("Orange"); | ||
| 89 | init_color_id("Purple"); | ||
| 90 | init_color_id("Brown"); | ||
| 91 | init_color_id("Gray"); | ||
| 62 | 92 | ||
| 63 | rooms_.reserve(lingo_config.size() * 2); | 93 | rooms_.reserve(lingo_config.size() * 2); |
| 64 | 94 | ||
| @@ -225,6 +255,17 @@ struct GameData { | |||
| 225 | if (panel_it.second["non_counting"]) { | 255 | if (panel_it.second["non_counting"]) { |
| 226 | panel_obj.non_counting = panel_it.second["non_counting"].as<bool>(); | 256 | panel_obj.non_counting = panel_it.second["non_counting"].as<bool>(); |
| 227 | } | 257 | } |
| 258 | |||
| 259 | if (ids_config["panels"] && ids_config["panels"][room_obj.name] && | ||
| 260 | ids_config["panels"][room_obj.name][panel_obj.name]) { | ||
| 261 | panel_obj.ap_location_id = | ||
| 262 | ids_config["panels"][room_obj.name][panel_obj.name].as<int>(); | ||
| 263 | } else { | ||
| 264 | std::ostringstream errmsg; | ||
| 265 | errmsg << "Missing AP location ID for panel " << room_obj.name | ||
| 266 | << " - " << panel_obj.name; | ||
| 267 | TrackerLog(errmsg.str()); | ||
| 268 | } | ||
| 228 | } | 269 | } |
| 229 | } | 270 | } |
| 230 | 271 | ||
| @@ -272,8 +313,34 @@ struct GameData { | |||
| 272 | door_obj.item_name = room_obj.name + " - " + door_obj.name; | 313 | door_obj.item_name = room_obj.name + " - " + door_obj.name; |
| 273 | } | 314 | } |
| 274 | 315 | ||
| 316 | if (!door_it.second["skip_item"] && !door_it.second["event"]) { | ||
| 317 | if (ids_config["doors"] && ids_config["doors"][room_obj.name] && | ||
| 318 | ids_config["doors"][room_obj.name][door_obj.name] && | ||
| 319 | ids_config["doors"][room_obj.name][door_obj.name]["item"]) { | ||
| 320 | door_obj.ap_item_id = | ||
| 321 | ids_config["doors"][room_obj.name][door_obj.name]["item"] | ||
| 322 | .as<int>(); | ||
| 323 | } else { | ||
| 324 | std::ostringstream errmsg; | ||
| 325 | errmsg << "Missing AP item ID for door " << room_obj.name << " - " | ||
| 326 | << door_obj.name; | ||
| 327 | TrackerLog(errmsg.str()); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 275 | if (door_it.second["group"]) { | 331 | if (door_it.second["group"]) { |
| 276 | door_obj.group_name = door_it.second["group"].as<std::string>(); | 332 | door_obj.group_name = door_it.second["group"].as<std::string>(); |
| 333 | |||
| 334 | if (ids_config["door_groups"] && | ||
| 335 | ids_config["door_groups"][door_obj.group_name]) { | ||
| 336 | door_obj.group_ap_item_id = | ||
| 337 | ids_config["door_groups"][door_obj.group_name].as<int>(); | ||
| 338 | } else { | ||
| 339 | std::ostringstream errmsg; | ||
| 340 | errmsg << "Missing AP item ID for door group " | ||
| 341 | << door_obj.group_name; | ||
| 342 | TrackerLog(errmsg.str()); | ||
| 343 | } | ||
| 277 | } | 344 | } |
| 278 | 345 | ||
| 279 | if (door_it.second["location_name"]) { | 346 | if (door_it.second["location_name"]) { |
| @@ -282,18 +349,34 @@ struct GameData { | |||
| 282 | } else if (!door_it.second["skip_location"] && | 349 | } else if (!door_it.second["skip_location"] && |
| 283 | !door_it.second["event"]) { | 350 | !door_it.second["event"]) { |
| 284 | if (has_external_panels) { | 351 | if (has_external_panels) { |
| 285 | std::cout | 352 | std::ostringstream errmsg; |
| 353 | errmsg | ||
| 286 | << room_obj.name << " - " << door_obj.name | 354 | << room_obj.name << " - " << door_obj.name |
| 287 | << " has panels from other rooms but does not have an " | 355 | << " has panels from other rooms but does not have an " |
| 288 | "explicit " | 356 | "explicit " |
| 289 | "location name and is not marked skip_location or event" | 357 | "location name and is not marked skip_location or event"; |
| 290 | << std::endl; | 358 | TrackerLog(errmsg.str()); |
| 291 | } | 359 | } |
| 292 | 360 | ||
| 293 | door_obj.location_name = | 361 | door_obj.location_name = |
| 294 | room_obj.name + " - " + hatkirby::implode(panel_names, ", "); | 362 | room_obj.name + " - " + hatkirby::implode(panel_names, ", "); |
| 295 | } | 363 | } |
| 296 | 364 | ||
| 365 | if (!door_it.second["skip_location"] && !door_it.second["event"]) { | ||
| 366 | if (ids_config["doors"] && ids_config["doors"][room_obj.name] && | ||
| 367 | ids_config["doors"][room_obj.name][door_obj.name] && | ||
| 368 | ids_config["doors"][room_obj.name][door_obj.name]["location"]) { | ||
| 369 | door_obj.ap_location_id = | ||
| 370 | ids_config["doors"][room_obj.name][door_obj.name]["location"] | ||
| 371 | .as<int>(); | ||
| 372 | } else { | ||
| 373 | std::ostringstream errmsg; | ||
| 374 | errmsg << "Missing AP location ID for door " << room_obj.name | ||
| 375 | << " - " << door_obj.name; | ||
| 376 | TrackerLog(errmsg.str()); | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 297 | if (door_it.second["include_reduce"]) { | 380 | if (door_it.second["include_reduce"]) { |
| 298 | door_obj.exclude_reduce = | 381 | door_obj.exclude_reduce = |
| 299 | !door_it.second["include_reduce"].as<bool>(); | 382 | !door_it.second["include_reduce"].as<bool>(); |
| @@ -330,6 +413,18 @@ struct GameData { | |||
| 330 | std::string progressive_item_name = | 413 | std::string progressive_item_name = |
| 331 | progression_it.first.as<std::string>(); | 414 | progression_it.first.as<std::string>(); |
| 332 | 415 | ||
| 416 | int progressive_item_id = -1; | ||
| 417 | if (ids_config["progression"] && | ||
| 418 | ids_config["progression"][progressive_item_name]) { | ||
| 419 | progressive_item_id = | ||
| 420 | ids_config["progression"][progressive_item_name].as<int>(); | ||
| 421 | } else { | ||
| 422 | std::ostringstream errmsg; | ||
| 423 | errmsg << "Missing AP item ID for progressive item " | ||
| 424 | << progressive_item_name; | ||
| 425 | TrackerLog(errmsg.str()); | ||
| 426 | } | ||
| 427 | |||
| 333 | int index = 1; | 428 | int index = 1; |
| 334 | for (const auto &stage : progression_it.second) { | 429 | for (const auto &stage : progression_it.second) { |
| 335 | int door_id = -1; | 430 | int door_id = -1; |
| @@ -342,7 +437,9 @@ struct GameData { | |||
| 342 | } | 437 | } |
| 343 | 438 | ||
| 344 | doors_[door_id].progressives.push_back( | 439 | doors_[door_id].progressives.push_back( |
| 345 | {.item_name = progressive_item_name, .quantity = index}); | 440 | {.item_name = progressive_item_name, |
| 441 | .ap_item_id = progressive_item_id, | ||
| 442 | .quantity = index}); | ||
| 346 | index++; | 443 | index++; |
| 347 | } | 444 | } |
| 348 | } | 445 | } |
| @@ -393,6 +490,7 @@ struct GameData { | |||
| 393 | map_area.locations.push_back( | 490 | map_area.locations.push_back( |
| 394 | {.name = panel.name, | 491 | {.name = panel.name, |
| 395 | .ap_location_name = room_name + " - " + panel.name, | 492 | .ap_location_name = room_name + " - " + panel.name, |
| 493 | .ap_location_id = panel.ap_location_id, | ||
| 396 | .room = panel.room, | 494 | .room = panel.room, |
| 397 | .panels = {panel.id}, | 495 | .panels = {panel.id}, |
| 398 | .classification = classification}); | 496 | .classification = classification}); |
| @@ -436,6 +534,7 @@ struct GameData { | |||
| 436 | // room field should be the original room ID | 534 | // room field should be the original room ID |
| 437 | map_area.locations.push_back({.name = section_name, | 535 | map_area.locations.push_back({.name = section_name, |
| 438 | .ap_location_name = door.location_name, | 536 | .ap_location_name = door.location_name, |
| 537 | .ap_location_id = door.ap_location_id, | ||
| 439 | .room = door.room, | 538 | .room = door.room, |
| 440 | .panels = door.panels, | 539 | .panels = door.panels, |
| 441 | .classification = classification}); | 540 | .classification = classification}); |
| @@ -564,3 +663,7 @@ int GD_GetRoomForPainting(const std::string &painting_id) { | |||
| 564 | const std::vector<int> &GD_GetAchievementPanels() { | 663 | const std::vector<int> &GD_GetAchievementPanels() { |
| 565 | return GetState().achievement_panels_; | 664 | return GetState().achievement_panels_; |
| 566 | } | 665 | } |
| 666 | |||
| 667 | int GD_GetItemIdForColor(LingoColor color) { | ||
| 668 | return GetState().ap_id_by_color_.at(color); | ||
| 669 | } | ||
| diff --git a/src/game_data.h b/src/game_data.h index d9c909b..b3e2466 100644 --- a/src/game_data.h +++ b/src/game_data.h | |||
| @@ -36,10 +36,12 @@ struct Panel { | |||
| 36 | bool achievement = false; | 36 | bool achievement = false; |
| 37 | std::string achievement_name; | 37 | std::string achievement_name; |
| 38 | bool non_counting = false; | 38 | bool non_counting = false; |
| 39 | int ap_location_id = -1; | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | struct ProgressiveRequirement { | 42 | struct ProgressiveRequirement { |
| 42 | std::string item_name; | 43 | std::string item_name; |
| 44 | int ap_item_id = -1; | ||
| 43 | int quantity = 0; | 45 | int quantity = 0; |
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| @@ -55,6 +57,9 @@ struct Door { | |||
| 55 | std::vector<int> panels; | 57 | std::vector<int> panels; |
| 56 | bool exclude_reduce = true; | 58 | bool exclude_reduce = true; |
| 57 | std::vector<ProgressiveRequirement> progressives; | 59 | std::vector<ProgressiveRequirement> progressives; |
| 60 | int ap_item_id = -1; | ||
| 61 | int group_ap_item_id = -1; | ||
| 62 | int ap_location_id = -1; | ||
| 58 | }; | 63 | }; |
| 59 | 64 | ||
| 60 | struct Exit { | 65 | struct Exit { |
| @@ -78,6 +83,7 @@ struct Room { | |||
| 78 | struct Location { | 83 | struct Location { |
| 79 | std::string name; | 84 | std::string name; |
| 80 | std::string ap_location_name; | 85 | std::string ap_location_name; |
| 86 | int ap_location_id = -1; | ||
| 81 | int room; | 87 | int room; |
| 82 | std::vector<int> panels; | 88 | std::vector<int> panels; |
| 83 | int classification = 0; | 89 | int classification = 0; |
| @@ -101,5 +107,6 @@ const Door& GD_GetDoor(int door_id); | |||
| 101 | const Panel& GD_GetPanel(int panel_id); | 107 | const Panel& GD_GetPanel(int panel_id); |
| 102 | int GD_GetRoomForPainting(const std::string& painting_id); | 108 | int GD_GetRoomForPainting(const std::string& painting_id); |
| 103 | const std::vector<int>& GD_GetAchievementPanels(); | 109 | const std::vector<int>& GD_GetAchievementPanels(); |
| 110 | int GD_GetItemIdForColor(LingoColor color); | ||
| 104 | 111 | ||
| 105 | #endif /* end of include guard: GAME_DATA_H_9C42AC51 */ | 112 | #endif /* end of include guard: GAME_DATA_H_9C42AC51 */ |
| diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 40d3ced..5580068 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp | |||
| @@ -104,12 +104,10 @@ void TrackerPanel::Redraw() { | |||
| 104 | 104 | ||
| 105 | bool has_reachable_unchecked = false; | 105 | bool has_reachable_unchecked = false; |
| 106 | bool has_unreachable_unchecked = false; | 106 | bool has_unreachable_unchecked = false; |
| 107 | for (int section_id = 0; section_id < map_area.locations.size(); | 107 | for (const Location §ion : map_area.locations) { |
| 108 | section_id++) { | 108 | if (AP_IsLocationVisible(section.classification) && |
| 109 | if (AP_IsLocationVisible( | 109 | !AP_HasCheckedGameLocation(section.ap_location_id)) { |
| 110 | map_area.locations.at(section_id).classification) && | 110 | if (IsLocationReachable(section.ap_location_id)) { |
| 111 | !AP_HasCheckedGameLocation(area.area_id, section_id)) { | ||
| 112 | if (IsLocationReachable(area.area_id, section_id)) { | ||
| 113 | has_reachable_unchecked = true; | 111 | has_reachable_unchecked = true; |
| 114 | } else { | 112 | } else { |
| 115 | has_unreachable_unchecked = true; | 113 | has_unreachable_unchecked = true; |
| diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index e462b29..cc19b19 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | namespace { | 12 | namespace { |
| 13 | 13 | ||
| 14 | struct TrackerState { | 14 | struct TrackerState { |
| 15 | std::map<std::tuple<int, int>, bool> reachability; | 15 | std::map<int, bool> reachability; |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | enum Decision { kYes, kNo, kMaybe }; | 18 | enum Decision { kYes, kNo, kMaybe }; |
| @@ -41,13 +41,13 @@ Decision IsDoorReachable_Helper(int door_id, | |||
| 41 | return kYes; | 41 | return kYes; |
| 42 | } else if (AP_GetDoorShuffleMode() == kSIMPLE_DOORS && | 42 | } else if (AP_GetDoorShuffleMode() == kSIMPLE_DOORS && |
| 43 | !door_obj.group_name.empty()) { | 43 | !door_obj.group_name.empty()) { |
| 44 | return AP_HasItem(door_obj.group_name) ? kYes : kNo; | 44 | return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; |
| 45 | } else { | 45 | } else { |
| 46 | bool has_item = AP_HasItem(door_obj.item_name); | 46 | bool has_item = AP_HasItem(door_obj.ap_item_id); |
| 47 | 47 | ||
| 48 | if (!has_item) { | 48 | if (!has_item) { |
| 49 | for (const ProgressiveRequirement& prog_req : door_obj.progressives) { | 49 | for (const ProgressiveRequirement& prog_req : door_obj.progressives) { |
| 50 | if (AP_HasItem(prog_req.item_name, prog_req.quantity)) { | 50 | if (AP_HasItem(prog_req.ap_item_id, prog_req.quantity)) { |
| 51 | has_item = true; | 51 | has_item = true; |
| 52 | break; | 52 | break; |
| 53 | } | 53 | } |
| @@ -127,7 +127,7 @@ Decision IsPanelReachable_Helper(int panel_id, | |||
| 127 | 127 | ||
| 128 | if (AP_IsColorShuffle()) { | 128 | if (AP_IsColorShuffle()) { |
| 129 | for (LingoColor color : panel_obj.colors) { | 129 | for (LingoColor color : panel_obj.colors) { |
| 130 | if (!AP_HasColorItem(color)) { | 130 | if (!AP_HasItem(GD_GetItemIdForColor(color))) { |
| 131 | return kNo; | 131 | return kNo; |
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| @@ -232,16 +232,14 @@ void RecalculateReachability() { | |||
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | GetState().reachability[{map_area.id, section_id}] = reachable; | 235 | GetState().reachability[location_section.ap_location_id] = reachable; |
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | bool IsLocationReachable(int area_id, int section_id) { | 240 | bool IsLocationReachable(int location_id) { |
| 241 | std::tuple<int, int> key = {area_id, section_id}; | 241 | if (GetState().reachability.count(location_id)) { |
| 242 | 242 | return GetState().reachability.at(location_id); | |
| 243 | if (GetState().reachability.count(key)) { | ||
| 244 | return GetState().reachability.at(key); | ||
| 245 | } else { | 243 | } else { |
| 246 | return false; | 244 | return false; |
| 247 | } | 245 | } |
| diff --git a/src/tracker_state.h b/src/tracker_state.h index d8256e2..e73607f 100644 --- a/src/tracker_state.h +++ b/src/tracker_state.h | |||
| @@ -3,6 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | void RecalculateReachability(); | 4 | void RecalculateReachability(); |
| 5 | 5 | ||
| 6 | bool IsLocationReachable(int area_id, int section_id); | 6 | bool IsLocationReachable(int location_id); |
| 7 | 7 | ||
| 8 | #endif /* end of include guard: TRACKER_STATE_H_8639BC90 */ | 8 | #endif /* end of include guard: TRACKER_STATE_H_8639BC90 */ |
