diff --git a/src/ride.h b/src/ride.h index 115d877b69..ecca01da52 100644 --- a/src/ride.h +++ b/src/ride.h @@ -176,7 +176,7 @@ enum { // Constants used by the lifecycle_flags property at 0x1D0 enum { - RIDE_LIFECYCLE_ON_TRACK = 1, + RIDE_LIFECYCLE_ON_TRACK = 1 << 0, RIDE_LIFECYCLE_TESTED = 1 << 1, RIDE_LIFECYCLE_TEST_IN_PROGRESS = 1 << 2, RIDE_LIFECYCLE_NO_RAW_STATS = 1 << 3, @@ -186,7 +186,7 @@ enum { RIDE_LIFECYCLE_BROKEN_DOWN = 1 << 7, RIDE_LIFECYCLE_CRASHED = 1 << 10, - + RIDE_LIFECYCLE_11 = 1 << 11, RIDE_LIFECYCLE_EVER_BEEN_OPENED = 1 << 12, RIDE_LIFECYCLE_MUSIC = 1 << 13, RIDE_LIFECYCLE_INDESTRUCTIBLE = 1 << 14, diff --git a/src/ride_data.c b/src/ride_data.c index aefda2a666..f1b91e2751 100644 --- a/src/ride_data.c +++ b/src/ride_data.c @@ -582,4 +582,98 @@ const uint8 rideUnknownData3[0x60] = { 10, // 57 Mini Roller Coaster 10, // 58 Mine Ride 10, // 59 LIM Launched Roller Coaster +}; + +const rct_ride_name_convention RideNameConvention[96] = { + { 1229, 1243, 1257, 0 }, // 00 Spiral Roller coaster + { 1229, 1243, 1257, 0 }, // 01 Stand Up Coaster + { 1229, 1243, 1257, 0 }, // 02 Suspended Swinging + { 1229, 1243, 1257, 0 }, // 03 Inverted + { 1229, 1243, 1257, 0 }, // 04 Steel Mini Coaster + { 1229, 1243, 1257, 0 }, // 05 Mini Railroad + { 1229, 1243, 1257, 0 }, // 06 Monorail + { 1264, 1243, 1257, 0 }, // 07 Mini Suspended Coaster + { 1236, 1250, 1250, 0 }, // 08 Bumper Boats + { 1264, 1243, 1257, 0 }, // 09 Wooden Wild Mine/Mouse + { 1264, 1243, 1257, 0 }, // 0a Steeplechase/Motorbike/Soap Box Derby + { 1264, 1243, 1257, 0 }, // 0b Car Ride + { 1264, 1243, 1257, 0 }, // 0c Launched Freefall + { 1229, 1243, 1257, 0 }, // 0d Bobsleigh Coaster + { 1292, 1243, 1257, 0 }, // 0e Observation Tower + { 1229, 1243, 1257, 0 }, // 0f Looping Roller Coaster + { 1236, 1243, 1257, 0 }, // 10 Dinghy Slide + { 1229, 1243, 1257, 0 }, // 11 Mine Train Coaster + { 1264, 1243, 1257, 0 }, // 12 Chairlift + { 1229, 1243, 1257, 0 }, // 13 Corkscrew Roller Coaster + { 1229, 1243, 1257, 0 }, // 14 Maze + { 1229, 1271, 1257, 0 }, // 15 Spiral Slide + { 1264, 1243, 1257, 0 }, // 16 Go Karts + { 1236, 1243, 1257, 0 }, // 17 Log Flume + { 1236, 1243, 1257, 0 }, // 18 River Rapids + { 1264, 1271, 1257, 0 }, // 19 Bumper Cars + { 1285, 1278, 1257, 0 }, // 1a Pirate Ship + { 1285, 1278, 1257, 0 }, // 1b Swinging Inverter Ship + { 1264, 1271, 1257, 0 }, // 1c Food Stall + { 1264, 1271, 1257, 0 }, // 1d (none) + { 1264, 1271, 1257, 0 }, // 1e Drink Stall + { 1264, 1271, 1257, 0 }, // 1f (none) + { 1264, 1271, 1257, 0 }, // 20 Shop (all types) + { 1264, 1278, 1257, 0 }, // 21 Merry Go Round + { 1264, 1271, 1257, 0 }, // 22 Balloon Stall (maybe) + { 1264, 1271, 1257, 0 }, // 23 Information Kiosk + { 1264, 1271, 1257, 0 }, // 24 Bathroom + { 1299, 1278, 1257, 0 }, // 25 Ferris Wheel + { 1264, 1278, 1257, 0 }, // 26 Motion Simulator + { 1271, 1278, 1257, 0 }, // 27 3D Cinema + { 1264, 1278, 1257, 0 }, // 28 Gravitron + { 1306, 1278, 1257, 0 }, // 29 Space Rings + { 1264, 1243, 1257, 0 }, // 2a Reverse Freefall Coaster + { 1292, 1243, 1257, 0 }, // 2b Elevator + { 1229, 1243, 1257, 0 }, // 2c Vertical Drop Roller Coaster + { 1264, 1271, 1257, 0 }, // 2d ATM + { 1278, 1278, 1257, 0 }, // 2e Twist + { 1271, 1278, 1257, 0 }, // 2f Haunted House + { 1264, 1271, 1257, 0 }, // 30 First Aid + { 1271, 1278, 1257, 0 }, // 31 Circus Show + { 1264, 1243, 1257, 0 }, // 32 Ghost Train + { 1229, 1243, 1257, 0 }, // 33 Twister Roller Coaster + { 1229, 1243, 1257, 0 }, // 34 Wooden Roller Coaster + { 1229, 1243, 1257, 0 }, // 35 Side-Friction Roller Coaster + { 1264, 1243, 1257, 0 }, // 36 Wild Mouse + { 1229, 1243, 1257, 0 }, // 37 Multi Dimension Coaster + { 1229, 1243, 1257, 0 }, // 38 (none) + { 1229, 1243, 1257, 0 }, // 39 Flying Roller Coaster + { 1229, 1243, 1257, 0 }, // 3a (none) + { 1264, 1243, 1257, 0 }, // 3b Virginia Reel + { 1236, 1243, 1257, 0 }, // 3c Splash Boats + { 1264, 1243, 1257, 0 }, // 3d Mini Helicopters + { 1229, 1243, 1257, 0 }, // 3e Lay-down Roller Coaster + { 1229, 1243, 1257, 0 }, // 3f Suspended Monorail + { 1229, 1243, 1257, 0 }, // 40 (none) + { 1264, 1243, 1257, 0 }, // 41 Reverser Roller Coaster + { 1264, 1243, 1257, 0 }, // 42 Heartline Twister Roller Coaster + { 1313, 1320, 1257, 0 }, // 43 Mini Golf + { 1229, 1243, 1257, 0 }, // 44 Giga Coaster + { 1264, 1243, 1257, 0 }, // 45 Roto-Drop + { 1264, 1271, 1257, 0 }, // 46 Flying Saucers + { 1271, 1278, 1257, 0 }, // 47 Crooked House + { 1264, 1243, 1257, 0 }, // 48 Monorail Cycles + { 1229, 1243, 1257, 0 }, // 49 Compact Inverted Coaster + { 1236, 1243, 1257, 0 }, // 4a Water Coaster + { 1229, 1243, 1257, 0 }, // 4b Air Powered Vertical Coaster + { 1264, 1243, 1257, 0 }, // 4c Inverted Hairpin Coaster + { 1264, 1278, 1257, 0 }, // 4d Magic Carpet + { 1236, 1243, 1250, 0 }, // 4e Submarine Ride + { 1236, 1243, 1257, 0 }, // 4f River Rafts + { 1264, 1271, 1257, 0 }, // 50 (none) + { 1299, 1278, 1257, 0 }, // 51 Enterprise + { 1264, 1271, 1257, 0 }, // 52 (none) + { 1264, 1271, 1257, 0 }, // 53 (none) + { 1264, 1271, 1257, 0 }, // 54 (none) + { 1229, 1243, 1257, 0 }, // 55 (none) + { 1229, 1243, 1257, 0 }, // 56 Inverted Impulse Coaster + { 1264, 1243, 1257, 0 }, // 57 Mini Roller Coaster + { 1229, 1243, 1257, 0 }, // 58 Mine Ride + { 1264, 1243, 1257, 0 }, // 59 LIM Launched Roller Coaster + { 1229, 1243, 1257, 0 } }; \ No newline at end of file diff --git a/src/ride_data.h b/src/ride_data.h index d107ad6aac..846ce84a9f 100644 --- a/src/ride_data.h +++ b/src/ride_data.h @@ -23,6 +23,14 @@ #include #include "rct2.h" +#include "string_ids.h" + +typedef struct { + rct_string_id vehicle_name; + rct_string_id structure_name; + rct_string_id station_name; + rct_string_id unk_name; +} rct_ride_name_convention; extern const bool hasRunningTrack[0x60]; extern const uint8 initialUpkeepCosts[0x60]; @@ -32,4 +40,6 @@ extern const uint8 rideUnknownData1[0x60]; extern const bool rideUnknownData2[0x60]; extern const uint8 rideUnknownData3[0x60]; +extern const rct_ride_name_convention RideNameConvention[96]; + #endif \ No newline at end of file diff --git a/src/string_ids.h b/src/string_ids.h index 9d86002c2e..4da194827c 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -255,6 +255,7 @@ enum { STR_DEMOLISH_RIDE_TIP = 992, + STR_OVERALL_VIEW = 996, STR_VIEW_SELECTION = 997, STR_OPEN_CLOSE_OR_TEST_RIDE = 1008, @@ -848,6 +849,9 @@ enum { STR_LIST_RIDES_TIP = 3104, STR_LIST_SHOPS_AND_STALLS_TIP = 3105, STR_LIST_KIOSKS_AND_FACILITIES_TIP = 3106, + STR_CLOSE_RIDE = 3107, + STR_TEST_RIDE = 3108, + STR_OPEN_RIDE = 3109, STR_SCROLL_LEFT_TIP = 3145, STR_SCROLL_RIGHT_TIP = STR_SCROLL_LEFT_TIP + 1, diff --git a/src/window.h b/src/window.h index 1098eba380..c537dea00a 100644 --- a/src/window.h +++ b/src/window.h @@ -160,6 +160,7 @@ typedef struct{ typedef struct { sint16 var_480; sint32 var_482; + sint32 var_486; } ride_variables; /** @@ -332,6 +333,7 @@ enum { WC_SAVE_PROMPT = 14, WC_RIDE_LIST = 15, WC_CONSTRUCT_RIDE = 16, + WC_DEMOLISH_RIDE_PROMPT = 17, WC_SCENERY = 18, WC_OPTIONS = 19, WC_FOOTPATH = 20, diff --git a/src/window_ride.c b/src/window_ride.c index f31b3613f4..cc96d7043b 100644 --- a/src/window_ride.c +++ b/src/window_ride.c @@ -23,6 +23,7 @@ #include "game.h" #include "map.h" #include "ride.h" +#include "ride_data.h" #include "string_ids.h" #include "sprite.h" #include "sprites.h" @@ -455,6 +456,66 @@ static void window_ride_construct(rct_window *w) } } +/** + * + * rct2: 0x006AF3B3 + */ +static void window_ride_locate(rct_window *w) +{ + rct_window *mainWindow; + int xy, x, y, z; + + if (w->viewport->width == 0) + return; + + xy = w->ride.var_482; + z = w->ride.var_486; + if (xy == -1) + return; + + if (xy & 0x80000000) { + rct_sprite *sprite = &g_sprite_list[xy]; + x = sprite->unknown.x; + y = sprite->unknown.y; + z = sprite->unknown.z; + } else { + x = (xy & ~0xC0000000) & 0xFFFF; + y = (xy & ~0xC0000000) >> 16; + z = z >> 16; + } + + mainWindow = window_get_main(); + if (mainWindow != NULL) + window_scroll_to_location(mainWindow, x, y, z); +} + +/** + * + * rct2: 0x006B486A + */ +static void window_ride_demolish(rct_window *w) +{ + rct_window *demolishWindow; + int x, y, screenWidth, screenHeight; + + demolishWindow = window_bring_to_front_by_id(WC_DEMOLISH_RIDE_PROMPT, w->number); + if (demolishWindow != NULL) + return; + + screenWidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16); + screenHeight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16); + x = screenWidth / 2 - 100; + y = max(28, screenHeight / 2 - 50); + + demolishWindow = window_create(x, y, 200, 100, (uint32*)0x0098E2E4, WC_DEMOLISH_RIDE_PROMPT, 0); + demolishWindow->widgets = (rct_widget*)0x009AEBA0; + demolishWindow->enabled_widgets = 4 | 8 | 16; + window_init_scroll_widgets(demolishWindow); + demolishWindow->flags |= WF_TRANSPARENT; + demolishWindow->number = w->number; + demolishWindow->colours[0] = 154; +} + /** * * rct2: 0x006AF17E @@ -488,19 +549,167 @@ static void window_ride_main_mouseup() case WIDX_RENAME: break; case WIDX_LOCATE: + window_ride_locate(w); break; case WIDX_DEMOLISH: + window_ride_demolish(w); break; } } +/** + * + * rct2: 0x006AF825 + */ +static void window_ride_show_view_dropdown(rct_window *w, rct_widget *widget) +{ + rct_widget *dropdownWidget; + rct_ride *ride; + int numItems, currentItem, i, j, name; + + dropdownWidget = widget - 1; + ride = GET_RIDE(w->number); + + numItems = 1; + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x2000)) { + numItems += ride->var_0C7; + numItems += ride->var_0C8; + } + + window_dropdown_show_text_custom_width( + w->x + dropdownWidget->left, + w->y + dropdownWidget->top, + dropdownWidget->bottom - dropdownWidget->top + 1, + w->colours[1], + 0, + numItems, + widget->right - dropdownWidget->left + ); + + // First item + gDropdownItemsFormat[0] = 1142; + gDropdownItemsArgs[0] = STR_OVERALL_VIEW; + currentItem = 1; + + // Vehicles + name = RideNameConvention[ride->type].vehicle_name + 6; + for (i = 1; i <= ride->var_0C8; i++) { + gDropdownItemsFormat[currentItem] = 1142; + gDropdownItemsArgs[currentItem] = name | (currentItem << 16); + currentItem++; + } + + // Stations + name = RideNameConvention[ride->type].station_name + 6; + for (i = 1; i <= ride->var_0C7; i++) { + gDropdownItemsFormat[currentItem] = 1142; + gDropdownItemsArgs[currentItem] = name | (i << 16); + currentItem++; + } + + // Set highlighted item + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) { + j = 2; + for (i = 0; i < ride->var_0C8; i++) { + RCT2_GLOBAL(0x009DED34, uint32) |= j; + j <<= 1; + } + } + + // Set checked item + gDropdownItemsChecked |= (1 << w->ride.var_480); +} + +/** + * + * rct2: 0x006AF64C + */ +static void window_ride_show_open_dropdown(rct_window *w, rct_widget *widget) +{ + rct_ride *ride; + int numItems, highlightedIndex, checkedIndex; + + ride = GET_RIDE(w->number); + + numItems = 0; + gDropdownItemsFormat[numItems] = 1142; + gDropdownItemsArgs[numItems] = STR_CLOSE_RIDE; + numItems++; + + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x800)) { + gDropdownItemsFormat[numItems] = 1142; + gDropdownItemsArgs[numItems] = STR_TEST_RIDE; + numItems++; + } + + gDropdownItemsFormat[numItems] = 1142; + gDropdownItemsArgs[numItems] = STR_OPEN_RIDE; + numItems++; + + window_dropdown_show_text( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[1], + 0, + numItems + ); + + checkedIndex = ride->status; + switch (ride->status) { + case RIDE_STATUS_CLOSED: + highlightedIndex = 0; + if ((ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) || (ride->lifecycle_flags & RIDE_LIFECYCLE_11)) + break; + + highlightedIndex = 2; + if (RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x800) + break; + if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) + break; + + highlightedIndex = 1; + break; + case RIDE_STATUS_TESTING: + highlightedIndex = 2; + if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) + break; + + highlightedIndex = 0; + break; + case RIDE_STATUS_OPEN: + highlightedIndex = 0; + break; + } + + if (checkedIndex != RIDE_STATUS_CLOSED) + checkedIndex = 3 - checkedIndex; + + if (RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x800) { + if (checkedIndex != 0) + checkedIndex--; + if (highlightedIndex != 0) + highlightedIndex--; + } + + gDropdownItemsChecked |= (1 << checkedIndex); + RCT2_GLOBAL(0x009DEBA2, sint16) = highlightedIndex; +} + /** * * rct2: 0x006AF1BD */ static void window_ride_main_mousedown(int widgetIndex, rct_window *w, rct_widget *widget) { - + switch (widgetIndex) { + case WIDX_VIEW_DROPDOWN: + window_ride_show_view_dropdown(w, widget); + break; + case WIDX_OPEN: + window_ride_show_open_dropdown(w, widget); + break; + } } /**