diff --git a/src/addresses.h b/src/addresses.h index 9987d2e44f..f510eac542 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -297,7 +297,9 @@ #define RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES 0x01357CF2 #define RCT2_ADDRESS_RESEARH_PROGRESS_STAGE 0x01357CF3 +#define RCT2_ADDRESS_NEXT_RESEARCH_ITEM 0x013580E0 #define RCT2_ADDRESS_RESEARH_PROGRESS 0x013580E4 +#define RCT2_ADDRESS_NEXT_RESEARCH_CATEGORY 0x013580E6 #define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7 #define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8 @@ -307,6 +309,8 @@ #define RCT2_TOTAL_RIDE_VALUE 0x013580EE +#define RCT2_RESEARCH_ITEMS 0x01358844 + #define RCT2_ADDRESS_SCENARIO_NAME 0x0135920A #define RCT2_ADDRESS_SCENARIO_DETAILS 0x0135924A diff --git a/src/management/research.c b/src/management/research.c index 2ef174ee7b..6af5ea1b16 100644 --- a/src/management/research.c +++ b/src/management/research.c @@ -23,13 +23,11 @@ #include "../localisation/date.h" #include "research.h" -typedef struct { - sint32 var_0; - uint8 category; -} rct_research_item; - const int _researchRate[] = { 0, 160, 250, 400 }; +// 0x01358844[500] +extern rct_research_item *gResearchItems = (rct_research_item*)RCT2_RESEARCH_ITEMS; + // 0x00EE787C uint8 gResearchUncompletedCategories; @@ -40,11 +38,11 @@ uint8 gResearchUncompletedCategories; void research_update_uncompleted_types() { int uncompletedResearchTypes = 0; - rct_research_item *researchItem = (rct_research_item*)0x001358844; - while (researchItem->var_0 != -1) + rct_research_item *researchItem = gResearchItems; + while (researchItem->entryIndex != -1) researchItem++; researchItem++; - for (; researchItem->var_0 != -2; researchItem++) + for (; researchItem->entryIndex != -2; researchItem++) uncompletedResearchTypes |= (1 << researchItem->category); gResearchUncompletedCategories = uncompletedResearchTypes; @@ -82,6 +80,63 @@ static void research_calculate_expected_date() } } +static void research_invalidate_related_windows() +{ + window_invalidate_by_id(WC_CONSTRUCT_RIDE, 0); + window_invalidate_by_id(WC_RESEARCH, 0); +} + +/** + * + * rct2: 0x00684BE5 + */ +static void research_next_design() +{ + rct_research_item *firstUnresearchedItem, *researchItem, tmp; + int ignoreActiveResearchTypes; + int activeResearchTypes = RCT2_GLOBAL(RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES, uint16); + + // Skip already researched items + firstUnresearchedItem = gResearchItems; + while (firstUnresearchedItem->entryIndex != RESEARCHED_ITEMS_SEPERATOR) + firstUnresearchedItem++; + + ignoreActiveResearchTypes = 0; + researchItem = firstUnresearchedItem; + for (;;) { + researchItem++; + if (researchItem->entryIndex == -2) { + if (!ignoreActiveResearchTypes) { + ignoreActiveResearchTypes = 1; + researchItem = firstUnresearchedItem; + continue; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = RESEARCH_STAGE_INITIAL_RESEARCH; + research_invalidate_related_windows(); + return; + } + } else if (ignoreActiveResearchTypes || (activeResearchTypes & (1 << researchItem->category))) { + break; + } + } + + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_ITEM, uint32) = researchItem->entryIndex; + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_CATEGORY, uint8) = researchItem->category; + RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = RESEARCH_STAGE_DESIGNING; + + // Bubble research item up until it is above the researched items seperator + do { + tmp = *researchItem; + *researchItem = *(researchItem - 1); + *(researchItem - 1) = tmp; + researchItem--; + } while ((researchItem + 1)->entryIndex != RESEARCHED_ITEMS_SEPERATOR); + + research_invalidate_related_windows(); +} + /** * * rct2: 0x00684C7A @@ -106,24 +161,22 @@ void research_update() } else { switch (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8)) { case RESEARCH_STAGE_INITIAL_RESEARCH: - RCT2_CALLPROC_EBPSAFE(0x00684BE5); + research_next_design(); research_calculate_expected_date(); break; case RESEARCH_STAGE_DESIGNING: RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = RESEARCH_STAGE_COMPLETING_DESIGN; research_calculate_expected_date(); - window_invalidate_by_id(WC_CONSTRUCT_RIDE, 0); - window_invalidate_by_id(WC_RESEARCH, 0); + research_invalidate_related_windows(); break; case RESEARCH_STAGE_COMPLETING_DESIGN: - RCT2_CALLPROC_X(0x006848D4, RCT2_GLOBAL(0x013580E0, uint32), 0, 0, 0, 0, 0, 0); + RCT2_CALLPROC_X(0x006848D4, RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_ITEM, uint32), 0, 0, 0, 0, 0, 0); RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = 0; research_calculate_expected_date(); research_update_uncompleted_types(); - window_invalidate_by_id(WC_CONSTRUCT_RIDE, 0); - window_invalidate_by_id(WC_RESEARCH, 0); + research_invalidate_related_windows(); break; } } diff --git a/src/management/research.h b/src/management/research.h index 19554a906b..0407fd3ece 100644 --- a/src/management/research.h +++ b/src/management/research.h @@ -23,6 +23,14 @@ #include "../common.h" +typedef struct { + // Bit 16 (0: scenery entry, 1: ride entry) + sint32 entryIndex; + uint8 category; +} rct_research_item; + +#define RESEARCHED_ITEMS_SEPERATOR -1 + enum { RESEARCH_FUNDING_NONE, RESEARCH_FUNDING_MINIMUM, @@ -37,6 +45,7 @@ enum { RESEARCH_STAGE_UNKNOWN }; +extern rct_research_item *gResearchItems; extern uint8 gResearchUncompletedCategories; void research_update_uncompleted_types(); diff --git a/src/scenario.h b/src/scenario.h index 6f0fdd33f7..06b960acb4 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -176,14 +176,15 @@ typedef struct { uint8 guests_in_park_history[32]; // SC6[10] - uint16 word_01357CF2; - uint32 word_01357CF4; + uint8 active_research_types; + uint8 research_progress_stage; + uint32 dword_01357CF4; uint8 byte_01357CF8[1000]; - uint32 dword_013580E0[32]; - uint16 word_013580E4[16]; - uint8 byte_013580E6; - uint8 byte_013580E7; - uint8 byte_013580E8; + uint32 dword_013580E0; + uint16 research_progress; + uint8 next_research_category; + uint8 next_research_expected_day; + uint8 next_research_expected_month; uint8 byte_013580E9; uint16 park_size; uint16 guest_generation_probability; diff --git a/src/windows/new_ride.c b/src/windows/new_ride.c index d44b5445ec..96261a7cea 100644 --- a/src/windows/new_ride.c +++ b/src/windows/new_ride.c @@ -735,9 +735,9 @@ static void window_new_ride_paint() // Research type rct_string_id stringId = STR_RESEARCH_UNKNOWN; if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) { - stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(0x013580E6, uint8); + stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_CATEGORY, uint8); if (RCT2_GLOBAL(0x01357CF3, uint8) != 1) { - uint32 typeId = RCT2_GLOBAL(0x013580E0, uint32); + uint32 typeId = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_ITEM, uint32); if (typeId >= 0x10000) { rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*); stringId = rideEntry->var_008 & 0x1000 ? diff --git a/src/windows/research.c b/src/windows/research.c index bb7e9f6512..7a4e3b2af5 100644 --- a/src/windows/research.c +++ b/src/windows/research.c @@ -341,9 +341,9 @@ static void window_research_development_paint() // Research type stringId = STR_RESEARCH_UNKNOWN; if (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) != 0) { - stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(0x013580E6, uint8); + stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_CATEGORY, uint8); if (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) != 1) { - uint32 typeId = RCT2_GLOBAL(0x013580E0, uint32); + uint32 typeId = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_ITEM, uint32); if (typeId >= 0x10000) { rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*); stringId = rideEntry->var_008 & 0x1000 ?