diff --git a/src/interface/viewport.h b/src/interface/viewport.h index 8fb5847be3..0519976250 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -21,6 +21,8 @@ #ifndef _VIEWPORT_H_ #define _VIEWPORT_H_ +#include "../world/map.h" +#include "../world/sprite.h" #include "window.h" enum { @@ -45,18 +47,30 @@ enum { enum { VIEWPORT_INTERACTION_ITEM_NONE, - VIEWPORT_INTERACTION_ITEM_2 = 2, - VIEWPORT_INTERACTION_ITEM_RIDE = 3, + VIEWPORT_INTERACTION_ITEM_SPRITE = 2, + VIEWPORT_INTERACTION_ITEM_RIDE, VIEWPORT_INTERACTION_ITEM_SCENERY = 5, VIEWPORT_INTERACTION_ITEM_FOOTPATH, VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM, - VIEWPORT_INTERACTION_ITEM_PARK_ENTRANCE, + VIEWPORT_INTERACTION_ITEM_PARK, VIEWPORT_INTERACTION_ITEM_WALL, VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY, VIEWPORT_INTERACTION_ITEM_BANNER = 12, }; +typedef struct { + int type; + int x; + int y; + union { + rct_map_element *mapElement; + rct_sprite *sprite; + rct_peep *peep; + rct_vehicle *vehicle; + }; +} viewport_interaction_info; + // rct2: 0x014234BC extern rct_viewport* g_viewport_list; @@ -81,7 +95,7 @@ void viewport_set_visibility(uint8 mode); void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement); -int viewport_interaction_get_item_left(int x, int y, rct_map_element **outMapElement, int *outX, int *outY); +int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info *info); int viewport_interaction_left_over(int x, int y); int viewport_interaction_left_click(int x, int y); int viewport_interaction_get_item_right(int x, int y, rct_map_element **outMapElement, int *outX, int *outY); diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 0868ed6a23..205b76d59b 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -1,9 +1,9 @@ /***************************************************************************** * Copyright (c) 2014 Ted John * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * + * * This file is part of OpenRCT2. - * + * * OpenRCT2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -36,65 +36,113 @@ static void viewport_interaction_remove_footpath_item(rct_map_element *mapElemen static void viewport_interaction_remove_park_entrance(rct_map_element *mapElement, int x, int y); static void viewport_interaction_remove_park_wall(rct_map_element *mapElement, int x, int y); static void viewport_interaction_remove_large_scenery(rct_map_element *mapElement, int x, int y); +static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDistance); /** - * + * * rct2: 0x006ED9D0 */ -int viewport_interaction_get_item_left(int x, int y, rct_map_element **outMapElement, int *outX, int *outY) +int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info *info) { + rct_s6_info *s6Info = (rct_s6_info*)0x00141F570; + rct_map_element *mapElement; + rct_sprite *sprite; + rct_vehicle *vehicle; + // No click input for title screen or scenario editor or track manager + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TITLE_DEMO | SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_MANAGER)) + return 0; + + // + if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) && s6Info->var_000 != 6) + return 0; + + get_map_coordinates_from_pos(x, y, 0xFF79, &info->x, &info->y, &info->type, &info->mapElement); + mapElement = info->mapElement; + sprite = (rct_sprite*)mapElement; + + switch (info->type) { + case VIEWPORT_INTERACTION_ITEM_SPRITE: + switch (sprite->unknown.sprite_identifier) { + case SPRITE_IDENTIFIER_VEHICLE: + vehicle = &(sprite->vehicle); + if (vehicle->var_D6 != 255) + vehicle_set_map_toolbar(vehicle); + else + info->type = VIEWPORT_INTERACTION_ITEM_NONE; + break; + case SPRITE_IDENTIFIER_PEEP: + peep_set_map_tooltip(&sprite->peep); + break; + } + break; + case VIEWPORT_INTERACTION_ITEM_RIDE: + ride_set_map_tooltip(mapElement); + break; + case VIEWPORT_INTERACTION_ITEM_PARK: + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = RCT2_GLOBAL(0x013573D4, uint16); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint32) = RCT2_GLOBAL(0x013573D8, uint32); + break; + default: + info->type = VIEWPORT_INTERACTION_ITEM_NONE; + break; + } + + // If nothing is under cursor, find a closeby peep + if (info->type == VIEWPORT_INTERACTION_ITEM_NONE) { + info->peep = viewport_interaction_get_closest_peep(x, y, 32); + if (info->peep == NULL) + return VIEWPORT_INTERACTION_ITEM_NONE; + + info->type = VIEWPORT_INTERACTION_ITEM_SPRITE; + info->x = info->peep->x; + info->y = info->peep->y; + peep_set_map_tooltip(info->peep); + } + + return info->type; } int viewport_interaction_left_over(int x, int y) { - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0; - RCT2_CALLFUNC_X(0x006ED9D0, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if ((ebx & 0xFF) == 2 || (ebx & 0xFF) == 8 || (ebx & 0xFF) == 3) - return 1; + viewport_interaction_info info; - return 0; + switch (viewport_interaction_get_item_left(x, y, &info)) { + case VIEWPORT_INTERACTION_ITEM_SPRITE: + case VIEWPORT_INTERACTION_ITEM_RIDE: + case VIEWPORT_INTERACTION_ITEM_PARK: + return 1; + default: + return 0; + } } int viewport_interaction_left_click(int x, int y) { - rct_sprite* spr; + viewport_interaction_info info; - int eax = x, ebx = y, ecx = 0, esi = 0, edi = 0, ebp = 0; - RCT2_CALLFUNC_X(0x006ED9D0, &eax, &ebx, &ecx, (int*)&spr, &esi, &edi, &ebp); - if ((ebx & 0xFF) == 2){ - - if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE){ - //Open ride window - RCT2_CALLPROC_X(0x6ACAC2, eax, ebx, ecx, (int)spr, esi, edi, ebp); - } - else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP){ - window_guest_open(&spr->peep); - } - else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_FLOATING_TEXT){ - //Unknown for now - RCT2_CALLPROC_X(0x6E88D7, eax, ebx, ecx, (int)spr, esi, edi, ebp); + switch (viewport_interaction_get_item_left(x, y, &info)) { + case VIEWPORT_INTERACTION_ITEM_SPRITE: + switch (info.sprite->unknown.sprite_identifier) { + case SPRITE_IDENTIFIER_VEHICLE: + window_ride_open_vehicle(info.vehicle); + break; + case SPRITE_IDENTIFIER_PEEP: + window_guest_open(info.peep); + break; + case SPRITE_IDENTIFIER_FLOATING_TEXT: + balloon_pop(info.sprite); + break; } return 1; - } - else if ((ebx & 0xFF) == 3){ - rct_map_element* map_element = (rct_map_element*)spr; - - if (!((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE)){ - eax = RCT2_ADDRESS(0x0099BA64, uint8)[16 * map_element->properties.track.type]; - if (!(eax & 0x10)){//If not station track - //Open ride window in overview mode. - window_ride_main_open(map_element->properties.track.ride_index); - return; - } - } - //Open ride window in station view - RCT2_CALLPROC_X(0x6ACCCE, map_element->properties.track.ride_index, (map_element->properties.track.sequence & 0x70) >> 4, ecx, (int)map_element, esi, edi, ebp); + case VIEWPORT_INTERACTION_ITEM_RIDE: + window_ride_open_track(info.mapElement); return 1; - } - else if ((ebx & 0xFF) == 8){ + case VIEWPORT_INTERACTION_ITEM_PARK: window_park_entrance_open(); return 1; + default: + return 0; } } @@ -109,7 +157,7 @@ int viewport_interaction_get_item_right(int x, int y, rct_map_element **outMapEl rct_scenery_entry *sceneryEntry; rct_banner *banner; rct_ride *ride; - int i, outZ; + int i, stationIndex, outZ; // No click input for title screen or track manager if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TITLE_DEMO | SCREEN_FLAGS_TRACK_MANAGER)) @@ -123,7 +171,7 @@ int viewport_interaction_get_item_right(int x, int y, rct_map_element **outMapEl *outMapElement = mapElement; switch (outZ) { - case VIEWPORT_INTERACTION_ITEM_2: + case VIEWPORT_INTERACTION_ITEM_SPRITE: if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) || mapElement->type != 0) return 0; @@ -169,12 +217,12 @@ int viewport_interaction_get_item_right(int x, int y, rct_map_element **outMapEl RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments; RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = RideNameConvention[ride->type].station_name + 2; - int edi = (mapElement->properties.track.sequence & 0x70) >> 4; - for (i = edi; i >= 0; i--) + stationIndex = map_get_station(mapElement); + for (i = stationIndex; i >= 0; i--) if (ride->station_starts[i] == 0xFFFF) - edi--; - edi++; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = edi; + stationIndex--; + stationIndex++; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = stationIndex; return 3; case VIEWPORT_INTERACTION_ITEM_WALL: @@ -233,7 +281,7 @@ int viewport_interaction_get_item_right(int x, int y, rct_map_element **outMapEl } return 7; - case VIEWPORT_INTERACTION_ITEM_PARK_ENTRANCE: + case VIEWPORT_INTERACTION_ITEM_PARK: if (RCT2_ADDRESS_SCREEN_FLAGS & SCREEN_FLAGS_SCENARIO_EDITOR) return 0; @@ -295,7 +343,7 @@ int viewport_interaction_right_click(int x, int y) case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM: viewport_interaction_remove_footpath_item(mapElement, x, y); break; - case VIEWPORT_INTERACTION_ITEM_PARK_ENTRANCE: + case VIEWPORT_INTERACTION_ITEM_PARK: viewport_interaction_remove_park_entrance(mapElement, x, y); break; case VIEWPORT_INTERACTION_ITEM_WALL: @@ -443,4 +491,44 @@ static void viewport_interaction_remove_large_scenery(rct_map_element *mapElemen 0 ); } +} + +static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDistance) +{ + int distance, closestDistance; + uint16 spriteIndex; + rct_window *w; + rct_viewport *viewport; + rct_peep *peep, *closestPeep; + + w = window_find_from_point(x, y); + if (w == NULL) + return 0; + + viewport = w->viewport; + if (viewport == NULL || viewport->zoom >= 2) + return 0; + + x = ((x - viewport->x) << viewport->zoom) + viewport->view_x; + y = ((y - viewport->y) << viewport->zoom) + viewport->view_y; + + closestPeep = NULL; + closestDistance = 0xFFFF; + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->var_16 == 0x8000) + continue; + + distance = + abs(((peep->var_16 + peep->var_1A) / 2) - x) + + abs(((peep->var_18 + peep->var_1C) / 2) - y); + if (distance > maxDistance) + continue; + + if (distance < closestDistance) { + closestPeep = peep; + closestDistance = distance; + } + } + + return closestPeep; } \ No newline at end of file diff --git a/src/interface/window.h b/src/interface/window.h index 46dac21396..06af018e30 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -25,6 +25,7 @@ #include "../drawing/drawing.h" #include "../peep/peep.h" #include "../ride/ride.h" +#include "../ride/vehicle.h" #include "../world/park.h" struct rct_window; @@ -503,6 +504,9 @@ void window_finances_open(); void window_finances_research_open(); void window_new_campaign_open(sint16 campaignType); rct_window *window_ride_main_open(int rideIndex); +rct_window *window_ride_open_station(int rideIndex, int stationIndex); +rct_window *window_ride_open_track(rct_map_element *mapElement); +rct_window *window_ride_open_vehicle(rct_vehicle *vehicle); void window_ride_demolish_prompt_open(int rideIndex); void window_ride_construct(rct_window *w); void window_ride_list_open(); diff --git a/src/peep/peep.c b/src/peep/peep.c index 020a447a27..20ea706a15 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -1500,3 +1500,27 @@ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_a peep->var_45 |= (1 << 0); } + +void peep_set_map_tooltip(rct_peep *peep) +{ + if (peep->type == PEEP_TYPE_GUEST) { + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = peep->flags & PEEP_FLAGS_TRACKING ? 1450 : 1449; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint32) = get_peep_face_sprite_small(peep); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint16) = peep->name_string_idx; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 8, uint32) = peep->id; + + uint32 arg0, arg1; + get_arguments_from_action(peep, &arg0, &arg1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint32) = arg0; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint32) = arg1; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 1451; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = peep->name_string_idx; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint32) = peep->id; + + uint32 arg0, arg1; + get_arguments_from_action(peep, &arg0, &arg1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 8, uint32) = arg0; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint32) = arg1; + } +} \ No newline at end of file diff --git a/src/peep/peep.h b/src/peep/peep.h index e89ee8f93d..8141e32af2 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -525,4 +525,6 @@ void peep_decrement_num_riders(rct_peep* peep); */ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_arguments); +void peep_set_map_tooltip(rct_peep *peep); + #endif diff --git a/src/ride/ride.c b/src/ride/ride.c index 6d9e0f0cd6..8806f55480 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -2140,4 +2140,115 @@ static void ride_shop_connected(rct_ride* ride, int ride_idx) ride->connected_message_throttle = 3; } +#pragma endregion + +#pragma region Interface + +static void ride_track_set_map_tooltip(rct_map_element *mapElement) +{ + int rideIndex; + rct_ride *ride; + + rideIndex = mapElement->properties.track.ride_index; + ride = GET_RIDE(rideIndex); + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = ride->name; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint32) = ride->name_arguments; + + int arg0, arg1; + ride_get_status(rideIndex, &arg0, &arg1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 8, uint16) = (uint16)arg0; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint32) = arg1; +} + +static void ride_station_set_map_tooltip(rct_map_element *mapElement) +{ + int i, rideIndex, stationIndex; + rct_ride *ride; + + rideIndex = mapElement->properties.track.ride_index; + ride = GET_RIDE(rideIndex); + + stationIndex = map_get_station(mapElement); + for (i = stationIndex; i >= 0; i--) + if (ride->station_starts[i] == 0xFFFF) + stationIndex--; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = ride->num_stations <= 1 ? 1333 : 1334; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint16) = ride->name; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = RideNameConvention[ride->type].station_name + 2; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = stationIndex + 1; + + int arg0, arg1; + ride_get_status(rideIndex, &arg0, &arg1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 14, uint16) = (uint16)arg0; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint32) = arg1; +} + +static void ride_entrance_set_map_tooltip(rct_map_element *mapElement) +{ + int i, rideIndex, stationIndex, queueLength; + rct_ride *ride; + + rideIndex = mapElement->properties.track.ride_index; + ride = GET_RIDE(rideIndex); + + // Get the station + stationIndex = map_get_station(mapElement); + for (i = stationIndex; i >= 0; i--) + if (ride->station_starts[i] == 0xFFFF) + stationIndex--; + + if (mapElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_ENTRANCE) { + // Get the queue length + queueLength = 0; + if (ride->entrances[stationIndex] != 0xFFFF) + queueLength = ride->queue_length[stationIndex]; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = ride->num_stations <= 1 ? 1335 : 1336; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint16) = ride->name; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = stationIndex + 1; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 14, uint16) = + queueLength == 0 ? + 1201 : + queueLength == 1 ? + 1202 : + 1203; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint16) = queueLength; + } else { + // Get the station + stationIndex = map_get_station(mapElement); + for (i = stationIndex; i >= 0; i--) + if (ride->station_starts[i] == 0xFFFF) + stationIndex--; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = ride->num_stations <= 1 ? 1337 : 1338; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = ride->name; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint32) = ride->name_arguments; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = stationIndex + 1; + } +} + +void ride_set_map_tooltip(rct_map_element *mapElement) +{ + if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) { + ride_entrance_set_map_tooltip(mapElement); + } else { + if ( + mapElement->properties.track.type == 2 || + mapElement->properties.track.type == 3 || + mapElement->properties.track.type == 1 + ) { + ride_station_set_map_tooltip(mapElement); + } else { + ride_track_set_map_tooltip(mapElement); + } + } +} + #pragma endregion \ No newline at end of file diff --git a/src/ride/ride.h b/src/ride/ride.h index 6e2e29e1bf..4d3e884ce1 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -627,5 +627,6 @@ rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message void ride_breakdown_add_news_item(int rideIndex); rct_peep *ride_find_closest_mechanic(rct_ride *ride, int forInspection); int sub_6CC3FB(int rideIndex); +void ride_set_map_tooltip(rct_map_element *mapElement); #endif diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 6f2bea8b0e..ee34c474f6 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -24,6 +24,7 @@ #include "../interface/viewport.h" #include "../world/sprite.h" #include "ride.h" +#include "ride_data.h" #include "vehicle.h" static void vehicle_update(rct_vehicle *vehicle); @@ -586,4 +587,31 @@ void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG) if (verticalG != NULL) *verticalG = (sint16)(eax & 0xFFFF); if (lateralG != NULL) *lateralG = (sint16)(edx & 0xFFFF); +} + +void vehicle_set_map_toolbar(rct_vehicle *vehicle) +{ + rct_ride *ride; + int vehicleIndex; + + ride = GET_RIDE(vehicle->ride); + + while (vehicle->var_01 != 0) + vehicle = &(g_sprite_list[vehicle->var_40].vehicle); + + for (vehicleIndex = 0; vehicleIndex < 32; vehicleIndex++) + if (ride->vehicles[vehicleIndex] == vehicle->sprite_index) + break; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = 1165; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint16) = ride->name; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = RideNameConvention[ride->type].vehicle_name + 2; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = vehicleIndex + 1; + + int arg0, arg1; + ride_get_status(vehicle->ride, &arg0, &arg1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 14, uint16) = (uint16)arg0; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint32) = (uint16)arg1; } \ No newline at end of file diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 9e7b0c656b..7272a7efbe 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -25,7 +25,8 @@ typedef struct { uint8 sprite_identifier; // 0x00 - uint8 pad_01[0x03]; + uint8 var_01; + uint8 pad_02[0x02]; uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... @@ -51,7 +52,8 @@ typedef struct { sint16 var_36; uint8 pad_38[0x06]; uint16 next_vehicle_on_train; // 0x3E - uint32 var_40; + uint16 var_40; + uint16 pad_42; uint16 var_44; uint16 var_46; uint16 var_48; @@ -123,6 +125,7 @@ int sub_6BC2F3(rct_vehicle* vehicle); void sub_6BB9FF(rct_vehicle* vehicle); void vehicle_sounds_update(); void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG); +void vehicle_set_map_toolbar(rct_vehicle *vehicle); /** Helper macro until rides are stored in this module. */ #define GET_VEHICLE(sprite_index) &(g_sprite_list[sprite_index].vehicle) diff --git a/src/windows/ride.c b/src/windows/ride.c index fcc3542378..89cad4de60 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -1178,6 +1178,41 @@ rct_window *window_ride_main_open(int rideIndex) return w; } +/** + * + * rct2: 0x006ACCCE + */ +rct_window *window_ride_open_station(int rideIndex, int stationIndex) +{ + RCT2_CALLPROC_X(0x006ACCCE, rideIndex, stationIndex, 0, 0, 0, 0, 0); + return window_find_by_number(WC_RIDE, rideIndex); +} + +rct_window *window_ride_open_track(rct_map_element *mapElement) +{ + int rideIndex = mapElement->properties.track.ride_index; + if ( + ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) || + (RCT2_ADDRESS(0x0099BA64, uint8)[mapElement->properties.track.type * 16] & 0x10) + ) { + // Open ride window in station view + return window_ride_open_station(rideIndex, map_get_station(mapElement)); + } else { + // Open ride window in overview mode. + return window_ride_main_open(rideIndex); + } +} + +/** + * + * rct2: 0x006ACAC2 + */ +rct_window *window_ride_open_vehicle(rct_vehicle *vehicle) +{ + RCT2_CALLPROC_X(0x6ACAC2, 0, 0, 0, (int)vehicle, 0, 0, 0); + return window_find_by_number(WC_RIDE, vehicle->ride); +} + /** * * rct2: 0x006AF1D2 diff --git a/src/world/map.c b/src/world/map.c index 7cf86a85e9..7dd0bab566 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -696,4 +696,9 @@ void game_command_clear_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi void map_invalidate_tile_full(int x, int y) { RCT2_CALLPROC_X(0x006EC6D7, x, 0, y, 0, 0, 0, 0); +} + +int map_get_station(rct_map_element *mapElement) +{ + return (mapElement->properties.track.sequence & 0x70) >> 4; } \ No newline at end of file diff --git a/src/world/map.h b/src/world/map.h index 86ba26880b..e57e2d15d5 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -210,6 +210,7 @@ int sub_664F72(int x, int y, int z); int map_is_location_in_park(int x, int y); void map_invalidate_tile(int x, int y, int zLow, int zHigh); void map_invalidate_tile_full(int x, int y); +int map_get_station(rct_map_element *mapElement); void fountain_update_all(); diff --git a/src/world/sprite.c b/src/world/sprite.c index 33805baf8b..ee6bb9f82c 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -280,4 +280,13 @@ void sub_69E9D3(int x, int y, int z, rct_sprite* sprite){ sprite->unknown.x = x; sprite->unknown.y = y; sprite->unknown.z = z; +} + +/** + * + * rct2: 0x006E88D7 + */ +void balloon_pop(rct_sprite *sprite) +{ + RCT2_CALLPROC_X(0x006E88D7, 0, 0, 0, (int)sprite, 0, 0, 0); } \ No newline at end of file diff --git a/src/world/sprite.h b/src/world/sprite.h index f0be7de49f..39a4511d87 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -103,5 +103,6 @@ void reset_0x69EBE4(); void move_sprite_to_list(rct_sprite *sprite, uint8 cl); void texteffect_update_all(); void sub_69E9D3(int x, int y, int z, rct_sprite* sprite); +void balloon_pop(rct_sprite *sprite); #endif