/** * * rct2: 0x0068563D */ rct_string_id research_item_get_name(const rct_research_item* researchItem) { if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { rct_ride_entry* rideEntry = get_ride_entry(researchItem->entryIndex); if (rideEntry == nullptr) { return STR_EMPTY; } else { return rideEntry->naming.name; } } else { rct_scenery_group_entry* sceneryEntry = get_scenery_group_entry(researchItem->entryIndex); if (sceneryEntry == nullptr) { return STR_EMPTY; } else { return sceneryEntry->name; } } }
/** * * rct2: 0x006B3EBA */ void window_new_ride_focus(ride_list_item rideItem) { rct_window *w; rct_ride_entry *rideType; w = window_find_by_class(WC_CONSTRUCT_RIDE); if (w == NULL) return; rideType = get_ride_entry(rideItem.entry_index); if(!gConfigInterface.select_by_track_type) window_new_ride_set_page(w, rideType->category[0]); else window_new_ride_set_page(w, gRideCategories[rideType->ride_type[0]]); ride_list_item *listItem = _windowNewRideListItems; while (listItem->type != RIDE_TYPE_NULL) { if (listItem->type == rideItem.type && listItem->entry_index == rideItem.entry_index) { _windowNewRideHighlightedItem[0] = rideItem; w->new_ride.highlighted_ride_id = rideItem.ride_type_and_entry; window_new_ride_scroll_to_focused_ride(w); } listItem++; } }
void research_populate_list_researched() { // Rides for (int32_t i = 0; i < MAX_RIDE_OBJECTS; i++) { rct_ride_entry* rideEntry = get_ride_entry(i); if (rideEntry == nullptr) { continue; } for (auto rideType : rideEntry->ride_type) { if (rideType != RIDE_TYPE_NULL) { research_insert(true, RESEARCH_ENTRY_RIDE_MASK | (rideType << 8) | i, rideEntry->category[0]); } } } // Scenery for (int32_t i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++) { rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(i); if (sceneryGroupEntry == nullptr) { continue; } research_insert(true, i, RESEARCH_CATEGORY_SCENERY_GROUP); } }
/** * rct2: 0x0088ABA4 * @param (edi) direction * @param (al) al * @param (cl) cl * @param (ebx) image_id * @param (edx) height */ static void paint_crooked_house_structure(paint_session * session, uint8 direction, uint8 x_offset, uint8 y_offset, uint32 segment, sint32 height) { const rct_tile_element * original_tile_element = static_cast<const rct_tile_element *>(session->CurrentlyDrawnItem); Ride * ride = get_ride(track_element_get_ride_index(original_tile_element)); rct_ride_entry * rideEntry = get_ride_entry(ride->subtype); if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) { if (ride->vehicles[0] != SPRITE_INDEX_NULL) { rct_sprite * sprite = get_sprite(ride->vehicles[0]); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = sprite; } } uint32 image_id = (direction + rideEntry->vehicles[0].base_image_id) | session->TrackColours[SCHEME_MISC]; rct_crooked_house_bound_box boundBox = crooked_house_data[segment]; sub_98197C( session, image_id, x_offset, y_offset, boundBox.length_x, boundBox.length_y, 127, height + 3, boundBox.offset_x, boundBox.offset_y, height + 3); }
/** At least 6 open roller coasters. */ static bool award_is_deserved_best_rollercoasters([[maybe_unused]] int32_t activeAwardTypes) { int32_t i, rollerCoasters; Ride* ride; rct_ride_entry* rideEntry; rollerCoasters = 0; FOR_ALL_RIDES (i, ride) { rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { continue; } if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { continue; } if (!ride_entry_has_category(rideEntry, RIDE_CATEGORY_ROLLERCOASTER)) { continue; } rollerCoasters++; }
static void paint_swinging_inverter_ship_structure(rct_ride * ride, uint8 direction, sint8 axisOffset, uint16 height) { rct_map_element * savedMapElement = g_currently_drawn_item; rct_ride_entry * rideType = get_ride_entry(ride->subtype); rct_vehicle * vehicle = NULL; sint8 xOffset = !(direction & 1) ? axisOffset : 0; sint8 yOffset = (direction & 1) ? axisOffset : 0; if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL) { vehicle = GET_VEHICLE(ride->vehicles[0]); gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; g_currently_drawn_item = vehicle; } uint32 vehicleImageId = rideType->vehicles[0].base_image_id + swinging_inverter_ship_base_sprite_offset[direction]; if (vehicle != NULL) { sint32 rotation = (sint8) vehicle->vehicle_sprite_type; if (rotation != 0) { vehicleImageId = rideType->vehicles[0].base_image_id + swinging_inverter_ship_animating_base_sprite_offset[direction]; if (direction & 2) { rotation = -rotation; } if (rotation < 0) { rotation += 72; } vehicleImageId += (rotation - 1) << 1; } } uint32 colourFlags = gTrackColours[SCHEME_MISC]; if (colourFlags == 0x20000000) { colourFlags = ride->vehicle_colours[0].body_colour << 19 | ride->vehicle_colours[0].trim_colour << 24 | 0xA0000000; } swinging_inverter_ship_bound_box boundBox = swinging_inverter_ship_bounds[direction]; vehicleImageId = vehicleImageId | colourFlags; uint32 frameImageId = swinging_inverter_ship_frame_sprites[direction] | gTrackColours[SCHEME_TRACK]; if (direction & 2) { sub_98197C(vehicleImageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height, get_current_rotation()); sub_98199C(frameImageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height, get_current_rotation()); } else { sub_98197C(frameImageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height, get_current_rotation()); sub_98199C(vehicleImageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height, get_current_rotation()); } g_currently_drawn_item = savedMapElement; gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE; }
void research_insert_ride_entry(uint8_t entryIndex, bool researched) { rct_ride_entry* rideEntry = get_ride_entry(entryIndex); uint8_t category = rideEntry->category[0]; for (auto rideType : rideEntry->ride_type) { if (rideType != RIDE_TYPE_NULL) { research_insert(researched, RESEARCH_ENTRY_RIDE_MASK | (rideType << 8) | entryIndex, category); } } }
/** * rct2: 0x0076F72C */ static void paint_haunted_house_structure(paint_session * session, uint8 rideIndex, uint8 direction, sint8 xOffset, sint8 yOffset, uint8 part, uint16 height) { const rct_tile_element * savedTileElement = static_cast<const rct_tile_element *>(session->CurrentlyDrawnItem); uint8 frameNum = 0; Ride * ride = get_ride(rideIndex); rct_ride_entry * rideEntry = get_ride_entry(ride->subtype); uint32 baseImageId = rideEntry->vehicles[0].base_image_id; if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL) { session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; rct_vehicle * vehicle = GET_VEHICLE(ride->vehicles[0]); session->CurrentlyDrawnItem = vehicle; frameNum = vehicle->vehicle_sprite_type; } uint32 imageId = (baseImageId + direction) | session->TrackColours[SCHEME_MISC]; haunted_house_bound_box boundBox = haunted_house_data[part]; sub_98197C( session, imageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height); rct_drawpixelinfo * dpi = session->Unk140E9A8; if (dpi->zoom_level == 0 && frameNum != 0) { switch (direction) { case 0: imageId = baseImageId + 3 + frameNum; break; case 1: imageId = baseImageId + 21 + frameNum; break; case 2: imageId = baseImageId + 39 + frameNum; break; case 3: imageId = baseImageId + 57 + frameNum; break; } imageId = imageId | session->TrackColours[SCHEME_MISC]; sub_98199C( session, imageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x, boundBox.offset_y, height); } session->CurrentlyDrawnItem = savedTileElement; session->InteractionType = VIEWPORT_INTERACTION_ITEM_RIDE; }
bool marketing_is_campaign_type_applicable(sint32 campaignType) { sint32 i; Ride * ride; rct_ride_entry * rideEntry; switch (campaignType) { case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: if (!park_entry_price_unlocked()) return false; return true; case ADVERTISING_CAMPAIGN_RIDE_FREE: if (!park_ride_prices_unlocked()) return false; // fall-through case ADVERTISING_CAMPAIGN_RIDE: // Check if any rides exist FOR_ALL_RIDES(i, ride) { if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) { return true; } } return false; case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: // Check if any food or drink stalls exist FOR_ALL_RIDES(i, ride) { rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { continue; } if ( shop_item_is_food_or_drink(rideEntry->shop_item) || shop_item_is_food_or_drink(rideEntry->shop_item_secondary) ) { return true; } } return false; default: return true; }
/** * * rct2: 0x0069E320 */ static void window_new_campaign_get_shop_items() { int32_t i, numItems; Ride* ride; uint64_t items = 0; FOR_ALL_RIDES (i, ride) { rct_ride_entry* rideEntry = get_ride_entry(ride->subtype); if (rideEntry == nullptr) { continue; } uint8_t itemType = rideEntry->shop_item; if (itemType != SHOP_ITEM_NONE && shop_item_is_food_or_drink(itemType)) items |= 1ULL << itemType; }
bool marketing_is_campaign_type_applicable(int campaignType) { int i; rct_ride *ride; rct_ride_entry *rideEntry; switch (campaignType) { case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY) return false; return true; case ADVERTISING_CAMPAIGN_RIDE_FREE: if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY)) return false; // fall-through case ADVERTISING_CAMPAIGN_RIDE: // Check if any rides exist FOR_ALL_RIDES(i, ride) { if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) { return true; } } return false; case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: // Check if any food or drink stalls exist FOR_ALL_RIDES(i, ride) { rideEntry = get_ride_entry(ride->subtype); if (rideEntry == NULL) { continue; } if ( shop_item_is_food_or_drink(rideEntry->shop_item) || shop_item_is_food_or_drink(rideEntry->shop_item_secondary) ) { return true; } } return false; default: return true; }
/** rct2: 0x00768A3B */ static void paint_space_rings_structure(rct_ride * ride, uint8 direction, uint32 segment, sint32 height) { rct_map_element * savedMapElement = g_currently_drawn_item; uint32 vehicleIndex = (segment - direction) & 0x3; if (ride->num_stations == 0 || vehicleIndex < ride->num_vehicles) { rct_ride_entry * ride_type = get_ride_entry(ride->subtype); rct_vehicle * vehicle = NULL; sint32 frameNum = direction; uint32 baseImageId = ride_type->vehicles[0].base_image_id; if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL) { gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; vehicle = GET_VEHICLE(ride->vehicles[vehicleIndex]); g_currently_drawn_item = vehicle; frameNum += (sint8) vehicle->vehicle_sprite_type * 4; } uint32 imageColourFlags = gTrackColours[SCHEME_MISC]; if ((ride->colour_scheme_type & 3) != RIDE_COLOUR_SCHEME_DIFFERENT_PER_TRAIN) { vehicleIndex = 0; } if (imageColourFlags == IMAGE_TYPE_REMAP) { imageColourFlags = SPRITE_ID_PALETTE_COLOUR_2(ride->vehicle_colours[vehicleIndex].body_colour, ride->vehicle_colours[0].trim_colour); } uint32 imageId = (baseImageId + frameNum) | imageColourFlags; sub_98197C(imageId, 0, 0, 20, 20, 23, height, -10, -10, height, get_current_rotation()); if (vehicle != NULL && vehicle->num_peeps > 0) { rct_peep * rider = GET_PEEP(vehicle->peep[0]); imageColourFlags = SPRITE_ID_PALETTE_COLOUR_2(rider->tshirt_colour, rider->trousers_colour); imageId = ((baseImageId & 0x7FFFF) + 352 + frameNum) | imageColourFlags; sub_98199C(imageId, 0, 0, 20, 20, 23, height, -10, -10, height, get_current_rotation()); } } g_currently_drawn_item = savedMapElement; gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE; }
/** * rct2: 0x0088ABA4 * @param (edi) direction * @param (al) al * @param (cl) cl * @param (ebx) image_id * @param (edx) height */ static void sub_88ABA4(uint8 direction, uint8 x_offset, uint8 y_offset, uint32 segment, int height) { rct_map_element *original_map_element = g_currently_drawn_item; rct_ride *ride = get_ride(original_map_element->properties.track.ride_index); rct_ride_entry *ride_type = get_ride_entry(ride->subtype); if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) { if (ride->vehicles[0] != (uint16)-1) { rct_sprite *sprite = get_sprite(ride->vehicles[0]); gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; g_currently_drawn_item = sprite; } } uint32 image_id = (direction + ride_type->vehicles[0].base_image_id) | gTrackColours[SCHEME_MISC]; rct_crooked_house_bound_box boundBox = crooked_house_data[segment]; sub_98197C(image_id, x_offset, y_offset, boundBox.length_x, boundBox.length_y, 127, height + 3, boundBox.offset_x, boundBox.offset_y, height + 3, get_current_rotation()); }
static rct_string_id window_editor_inventions_list_prepare_name(const rct_research_item* researchItem, bool withGap) { rct_string_id drawString; rct_string_id stringId = research_item_get_name(researchItem); if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE && !RideGroupManager::RideTypeIsIndependent(researchItem->baseRideType)) { drawString = withGap ? STR_INVENTIONS_LIST_RIDE_AND_VEHICLE_NAME_DRAG : STR_WINDOW_COLOUR_2_STRINGID_STRINGID; rct_string_id rideGroupName = get_ride_naming(researchItem->baseRideType, get_ride_entry(researchItem->entryIndex)) .name; set_format_arg(0, rct_string_id, rideGroupName); set_format_arg(2, rct_string_id, stringId); } else { drawString = STR_WINDOW_COLOUR_2_STRINGID; set_format_arg(0, rct_string_id, stringId); } return drawString; }
/** * * rct2: 0x006CF2D6 */ static void window_track_list_invalidate(rct_window *w) { rct_ride_entry *entry; rct_string_id stringId; colour_scheme_update(w); entry = get_ride_entry(_window_track_list_item.entry_index); stringId = entry->name; if (!(entry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) || rideTypeShouldLoseSeparateFlag(entry)) stringId = _window_track_list_item.type + 2; RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = stringId; if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { window_track_list_widgets[WIDX_TITLE].image = STR_TRACK_DESIGNS; window_track_list_widgets[WIDX_TRACK_LIST].tooltip = STR_CLICK_ON_DESIGN_TO_RENAME_OR_DELETE_IT; } else { window_track_list_widgets[WIDX_TITLE].image = STR_SELECT_DESIGN; window_track_list_widgets[WIDX_TRACK_LIST].tooltip = STR_CLICK_ON_DESIGN_TO_BUILD_IT_TIP; } if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) || w->track_list.var_482 != 0) { w->pressed_widgets |= 1 << WIDX_TRACK_PREVIEW; w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW); window_track_list_widgets[WIDX_ROTATE].type = WWT_FLATBTN; window_track_list_widgets[WIDX_TOGGLE_SCENERY].type = WWT_FLATBTN; if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) w->pressed_widgets |= (1 << WIDX_TOGGLE_SCENERY); else w->pressed_widgets &= ~(1 << WIDX_TOGGLE_SCENERY); } else { w->pressed_widgets &= ~(1 << WIDX_TRACK_PREVIEW); w->disabled_widgets |= (1 << WIDX_TRACK_PREVIEW); window_track_list_widgets[WIDX_ROTATE].type = WWT_EMPTY; window_track_list_widgets[WIDX_TOGGLE_SCENERY].type = WWT_EMPTY; } }
/** * * rct2: 0x00685675 */ void research_populate_list_random() { research_reset_items(); // Rides for (int32_t i = 0; i < MAX_RIDE_OBJECTS; i++) { rct_ride_entry* rideEntry = get_ride_entry(i); if (rideEntry == nullptr) { continue; } int32_t researched = (scenario_rand() & 0xFF) > 128; for (auto rideType : rideEntry->ride_type) { if (rideType != RIDE_TYPE_NULL) { research_insert(researched, RESEARCH_ENTRY_RIDE_MASK | (rideType << 8) | i, rideEntry->category[0]); } } } // Scenery for (int32_t i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++) { rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(i); if (sceneryGroupEntry == nullptr) { continue; } int32_t researched = (scenario_rand() & 0xFF) > 85; research_insert(researched, i, RESEARCH_CATEGORY_SCENERY_GROUP); } }
/** * * rct2: 0x006852F4 */ static void window_editor_inventions_list_drag_open(rct_research_item* researchItem) { char buffer[256], *ptr; int32_t stringWidth; rct_window* w; window_close_by_class(WC_EDITOR_INVENTION_LIST_DRAG); _editorInventionsListDraggedItem = researchItem; rct_string_id stringId = research_item_get_name(researchItem); ptr = buffer; if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE && !RideGroupManager::RideTypeIsIndependent(researchItem->baseRideType)) { const auto rideEntry = get_ride_entry(researchItem->entryIndex); const rct_string_id rideGroupName = get_ride_naming(researchItem->baseRideType, rideEntry).name; rct_string_id args[] = { rideGroupName, stringId, }; format_string(ptr, 256, STR_INVENTIONS_LIST_RIDE_AND_VEHICLE_NAME, &args); } else { format_string(ptr, 256, stringId, nullptr); } stringWidth = gfx_get_string_width(buffer); window_editor_inventions_list_drag_widgets[0].right = stringWidth; w = window_create( gTooltipCursorX - (stringWidth / 2), gTooltipCursorY - 7, stringWidth, 14, &window_editor_inventions_list_drag_events, WC_EDITOR_INVENTION_LIST_DRAG, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_NO_SNAPPING); w->widgets = window_editor_inventions_list_drag_widgets; w->colours[1] = COLOUR_WHITE; input_window_position_begin(w, 0, gTooltipCursorX, gTooltipCursorY); }
/** * * rct2: 0x006CF2D6 */ static void window_track_list_invalidate(rct_window *w) { rct_string_id stringId = STR_NONE; rct_ride_entry *entry = get_ride_entry(_window_track_list_item.entry_index); if (entry != NULL && entry != (rct_ride_entry*)-1) { rct_ride_name rideName = get_ride_naming(_window_track_list_item.type, entry); stringId = rideName.name; } set_format_arg(0, rct_string_id, stringId); if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { window_track_list_widgets[WIDX_TITLE].text = STR_TRACK_DESIGNS; window_track_list_widgets[WIDX_TRACK_LIST].tooltip = STR_CLICK_ON_DESIGN_TO_RENAME_OR_DELETE_IT; } else { window_track_list_widgets[WIDX_TITLE].text = STR_SELECT_DESIGN; window_track_list_widgets[WIDX_TRACK_LIST].tooltip = STR_CLICK_ON_DESIGN_TO_BUILD_IT_TIP; } if ((gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) || w->selected_list_item != 0) { w->pressed_widgets |= 1 << WIDX_TRACK_PREVIEW; w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW); window_track_list_widgets[WIDX_ROTATE].type = WWT_FLATBTN; window_track_list_widgets[WIDX_TOGGLE_SCENERY].type = WWT_FLATBTN; if (gTrackDesignSceneryToggle) { w->pressed_widgets &= ~(1 << WIDX_TOGGLE_SCENERY); } else { w->pressed_widgets |= (1 << WIDX_TOGGLE_SCENERY); } } else { w->pressed_widgets &= ~(1 << WIDX_TRACK_PREVIEW); w->disabled_widgets |= (1 << WIDX_TRACK_PREVIEW); window_track_list_widgets[WIDX_ROTATE].type = WWT_EMPTY; window_track_list_widgets[WIDX_TOGGLE_SCENERY].type = WWT_EMPTY; } }
/** * * rct2: 0x0076750D */ static void top_spin_paint_vehicle( paint_session * session, sint8 al, sint8 cl, uint8 rideIndex, uint8 direction, sint32 height, const rct_tile_element * tileElement) { uint16 boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ; // As we will be drawing a vehicle we need to backup the tileElement that // is assigned to the drawings. const rct_tile_element * curTileElement = static_cast<const rct_tile_element *>(session->CurrentlyDrawnItem); height += 3; Ride * ride = get_ride(rideIndex); rct_ride_entry * rideEntry = get_ride_entry(ride->subtype); rct_vehicle * vehicle = nullptr; uint8 seatRotation = 0; sint8 armRotation = 0; if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL) { vehicle = GET_VEHICLE(ride->vehicles[0]); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = vehicle; armRotation = vehicle->vehicle_sprite_type; seatRotation = vehicle->bank_rotation; } boundBoxOffsetX = al + 16; boundBoxOffsetY = cl + 16; boundBoxOffsetZ = height; // di uint8 lengthX = 24; // si uint8 lengthY = 24; uint32 image_id = session->TrackColours[SCHEME_MISC]; if (image_id == IMAGE_TYPE_REMAP) { image_id = SPRITE_ID_PALETTE_COLOUR_2(ride->track_colour_main[0], ride->track_colour_supports[0]); } image_id += (direction & 1) << 1; image_id += rideEntry->vehicles[0].base_image_id; // Left back bottom support image_id += 572; sub_98197C(session, image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ); image_id = session->TrackColours[SCHEME_MISC]; if (image_id == IMAGE_TYPE_REMAP) { image_id = SPRITE_ID_PALETTE_COLOUR_2(ride->track_colour_main[0], ride->track_colour_additional[0]); } sint32 var_1F = armRotation; if (direction & 2) { var_1F = -var_1F; if (var_1F != 0) var_1F += 48; } image_id += var_1F; image_id += (direction & 1) * 48; image_id += rideEntry->vehicles[0].base_image_id; // Left hand arm image_id += 380; sub_98199C(session, image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ); uint32 seatImageId; if (vehicle != nullptr && vehicle->restraints_position >= 64) { // Open Restraints image_id = (vehicle->restraints_position - 64) >> 6; image_id += direction * 3; image_id += rideEntry->vehicles[0].base_image_id; image_id += 64; seatImageId = image_id; }
void research_fix() { // Fix invalid research items for (int32_t i = 0; i < MAX_RESEARCH_ITEMS; i++) { rct_research_item* researchItem = &gResearchItems[i]; if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) continue; if (researchItem->rawValue == RESEARCHED_ITEMS_END) { if (i == MAX_RESEARCH_ITEMS - 1) { (--researchItem)->rawValue = RESEARCHED_ITEMS_END; } (++researchItem)->rawValue = RESEARCHED_ITEMS_END_2; break; } if (researchItem->rawValue == RESEARCHED_ITEMS_END_2) break; if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { rct_ride_entry* rideEntry = get_ride_entry(researchItem->entryIndex); if (rideEntry == nullptr) { research_remove(researchItem); i--; } } else { rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem->rawValue); if (sceneryGroupEntry == nullptr) { research_remove(researchItem); i--; } } } research_update_uncompleted_types(); if (gResearchUncompletedCategories == 0) gResearchProgressStage = RESEARCH_STAGE_FINISHED_ALL; // Sometimes ride entries are not in the research table. // If all research is done, simply insert all of them as researched. // For good measure, also include scenery groups. if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL) { for (uint8_t i = 0; i < MAX_RIDE_OBJECTS; i++) { const rct_ride_entry* rideEntry = get_ride_entry(i); if (rideEntry != nullptr) { research_insert_ride_entry(i, true); ride_entry_set_invented(i); for (uint8_t j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) { uint32_t rideType = rideEntry->ride_type[j]; if (rideType != RIDE_TYPE_NULL) { ride_type_set_invented(rideEntry->ride_type[j]); } } } } for (uint8_t i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++) { const rct_scenery_group_entry* groupEntry = get_scenery_group_entry(i); if (groupEntry != nullptr) research_insert_scenery_group_entry(i, true); } } }
/** * rct2: 0x006B6F3E * * Note: When the user has selection by track type enabled, the categories are determined by the track type, not those in the rct_ride_entry. */ static void window_new_ride_populate_list() { uint8 currentCategory = _windowNewRideCurrentTab; ride_list_item *nextListItem = _windowNewRideListItems; // For each ride type in the view order list for (int i = 0; i < countof(RideTypeViewOrder); i++) { uint8 rideType = RideTypeViewOrder[i]; if (rideType == RIDE_TYPE_NULL) continue; if(gConfigInterface.select_by_track_type) { if(gRideCategories[rideType]!=currentCategory) continue; } char preferredVehicleName[9]; safe_strcpy(preferredVehicleName, " ", sizeof(preferredVehicleName)); if (ride_type_is_invented(rideType)) { int dh = 0; uint8 *rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideType); // For each ride entry for this ride type while (*rideEntryIndexPtr != 255) { uint8 rideEntryIndex = *rideEntryIndexPtr++; char rideEntryName[9]; memcpy(rideEntryName,object_entry_groups[OBJECT_TYPE_RIDE].entries[rideEntryIndex].name,8); rideEntryName[8]=0; // Skip if vehicle type is not invented yet if (!ride_entry_is_invented(rideEntryIndex)) continue; // Ride entries rct_ride_entry *rideEntry = get_ride_entry(rideEntryIndex); // Check if ride is in this category if (!gConfigInterface.select_by_track_type && (currentCategory != rideEntry->category[0] && currentCategory != rideEntry->category[1])) continue; // Skip if the vehicle isn't the preferred vehicle for this generic track type if (gConfigInterface.select_by_track_type && (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry))) { if (strcmp(preferredVehicleName, " \0") == 0) { safe_strcpy(preferredVehicleName, rideEntryName, sizeof(preferredVehicleName)); preferredVehicleName[8] = 0; } else { if (vehicle_preference_compare(rideType, preferredVehicleName, rideEntryName) == 1) { safe_strcpy(preferredVehicleName, rideEntryName, sizeof(preferredVehicleName)); preferredVehicleName[8] = 0; } else { continue; } } } if ((rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) && !rideTypeShouldLoseSeparateFlag(rideEntry)) { dh &= ~4; nextListItem->type = rideType; nextListItem->entry_index = rideEntryIndex; nextListItem++; } else if (!(dh & 1)) { dh |= 5; nextListItem->type = rideType; nextListItem->entry_index = rideEntryIndex; nextListItem++; } else if (dh & 4) { if (rideType == rideEntry->ride_type[0]) { nextListItem--; nextListItem->type = rideType; nextListItem->entry_index = rideEntryIndex; nextListItem++; } } } } } nextListItem->type = 255; nextListItem->entry_index = 255; _trackSelectionByType = gConfigInterface.select_by_track_type; }
/** * * rct2: 0x006D3B1F */ static void window_install_track_paint(rct_window* w, rct_drawpixelinfo* dpi) { window_draw_widgets(w, dpi); // Track preview rct_widget* widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW]; int32_t x = w->x + widget->left + 1; int32_t y = w->y + widget->top + 1; int32_t colour = ColourMapA[w->colours[0]].darkest; gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour); rct_g1_element g1temp = {}; g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); g1temp.width = 370; g1temp.height = 217; g1temp.flags = G1_FLAG_BMP; gfx_set_g1_element(SPR_TEMP, &g1temp); gfx_draw_sprite(dpi, SPR_TEMP, x, y, 0); x = w->x + (widget->left + widget->right) / 2; y = w->y + widget->bottom - 12; // Warnings rct_track_td6* td6 = _trackDesign; if (td6->track_flags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE) { if (!gTrackDesignSceneryToggle) { // Scenery not available gfx_draw_string_centred_clipped( dpi, STR_DESIGN_INCLUDES_SCENERY_WHICH_IS_UNAVAILABLE, nullptr, COLOUR_BLACK, x, y, 368); y -= LIST_ROW_HEIGHT; } } // Information x = w->x + widget->left + 1; y = w->y + widget->bottom + 4; // 0x006D3CF1 -- 0x006d3d71 missing // Track design name & type auto trackName = _trackName.c_str(); gfx_draw_string_left(dpi, STR_TRACK_DESIGN_NAME, &trackName, COLOUR_BLACK, x - 1, y); y += LIST_ROW_HEIGHT; rct_ride_name rideName; rct_string_id friendlyTrackName; void* objectEntry = object_manager_load_object(&td6->vehicle_object); if (objectEntry != nullptr) { int32_t groupIndex = object_manager_get_loaded_object_entry_index(objectEntry); rideName = get_ride_naming(td6->type, get_ride_entry(groupIndex)); friendlyTrackName = rideName.name; } else { // Fall back on the technical track name if the vehicle object cannot be loaded friendlyTrackName = RideNaming[td6->type].name; } gfx_draw_string_left(dpi, STR_TRACK_DESIGN_TYPE, &friendlyTrackName, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT + 4; // Stats fixed32_2dp rating = td6->excitement * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_EXCITEMENT_RATING, &rating, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; rating = td6->intensity * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_INTENSITY_RATING, &rating, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; rating = td6->nausea * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_NAUSEA_RATING, &rating, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT + 4; if (td6->type != RIDE_TYPE_MAZE) { if (td6->type == RIDE_TYPE_MINI_GOLF) { // Holes uint16_t holes = td6->holes & 0x1F; gfx_draw_string_left(dpi, STR_HOLES, &holes, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } else { // Maximum speed uint16_t speed = ((td6->max_speed << 16) * 9) >> 18; gfx_draw_string_left(dpi, STR_MAX_SPEED, &speed, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; // Average speed speed = ((td6->average_speed << 16) * 9) >> 18; gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &speed, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } // Ride length set_format_arg(0, rct_string_id, STR_RIDE_LENGTH_ENTRY); set_format_arg(2, uint16_t, td6->ride_length); gfx_draw_string_left_clipped(dpi, STR_TRACK_LIST_RIDE_LENGTH, gCommonFormatArgs, COLOUR_BLACK, x, y, 214); y += LIST_ROW_HEIGHT; } if (ride_type_has_flag(td6->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) { // Maximum positive vertical Gs int32_t gForces = td6->max_positive_vertical_g * 32; gfx_draw_string_left(dpi, STR_MAX_POSITIVE_VERTICAL_G, &gForces, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; // Maximum negative vertical Gs gForces = td6->max_negative_vertical_g * 32; gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; // Maximum lateral Gs gForces = td6->max_lateral_g * 32; gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; // If .TD6 if (td6->version_and_colour_scheme / 4 >= 2) { if (td6->total_air_time != 0) { // Total air time int32_t airTime = td6->total_air_time * 25; gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &airTime, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } } } if (ride_type_has_flag(td6->type, RIDE_TYPE_FLAG_HAS_DROPS)) { // Drops uint16_t drops = td6->drops & 0x3F; gfx_draw_string_left(dpi, STR_DROPS, &drops, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; // Drop height is multiplied by 0.75 gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &drops, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } if (td6->type != RIDE_TYPE_MINI_GOLF) { uint16_t inversions = td6->inversions & 0x1F; if (inversions != 0) { // Inversions gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } } y += 4; if (td6->space_required_x != 0xFF) { // Space required set_format_arg(0, uint16_t, td6->space_required_x); set_format_arg(2, uint16_t, td6->space_required_y); gfx_draw_string_left(dpi, STR_TRACK_LIST_SPACE_REQUIRED, gCommonFormatArgs, COLOUR_BLACK, x, y); y += LIST_ROW_HEIGHT; } if (td6->cost != 0) { gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &td6->cost, COLOUR_BLACK, x, y); } }
/** * * rct2: 0x006850BD */ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex) { // Draw background uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); rct_research_item* researchItem = gResearchItems; int32_t researchItemEndMarker; if (scrollIndex == 1) { // Skip pre-researched items for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } researchItem++; researchItemEndMarker = RESEARCHED_ITEMS_END; } else { researchItemEndMarker = RESEARCHED_ITEMS_SEPARATOR; } int16_t boxWidth = (w->widgets[WIDX_RESEARCH_ORDER_SCROLL].right - w->widgets[WIDX_RESEARCH_ORDER_SCROLL].left); int16_t columnSplitOffset = boxWidth / 2; int32_t itemY = -SCROLLABLE_ROW_HEIGHT; do { itemY += SCROLLABLE_ROW_HEIGHT; if (itemY + SCROLLABLE_ROW_HEIGHT < dpi->y || itemY >= dpi->y + dpi->height) continue; if (w->research_item == researchItem) { int32_t top, bottom; if (_editorInventionsListDraggedItem == nullptr) { // Highlight top = itemY; bottom = itemY + SCROLLABLE_ROW_HEIGHT - 1; } else { // Drop horizontal rule top = itemY - 1; bottom = itemY; } gfx_filter_rect(dpi, 0, top, boxWidth, bottom, PALETTE_DARKEN_1); } if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR || researchItem->rawValue == RESEARCHED_ITEMS_END) continue; if (researchItem == _editorInventionsListDraggedItem) continue; utf8 groupNameBuffer[256], vehicleNameBuffer[256]; utf8* groupNamePtr = groupNameBuffer; utf8* vehicleNamePtr = vehicleNameBuffer; uint8_t colour; if (research_item_is_always_researched(researchItem)) { if (w->research_item == researchItem && _editorInventionsListDraggedItem == nullptr) gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK; else gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK; colour = w->colours[1] | COLOUR_FLAG_INSET; } else { // TODO: this is actually just a black colour. colour = COLOUR_BRIGHT_GREEN | COLOUR_FLAG_TRANSLUCENT; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; groupNamePtr = utf8_write_codepoint(groupNamePtr, colour); vehicleNamePtr = utf8_write_codepoint(vehicleNamePtr, colour); } rct_string_id itemNameId = research_item_get_name(researchItem); if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE && !RideGroupManager::RideTypeIsIndependent(researchItem->baseRideType)) { const auto rideEntry = get_ride_entry(researchItem->entryIndex); const rct_string_id rideGroupName = get_ride_naming(researchItem->baseRideType, rideEntry).name; format_string( groupNamePtr, std::size(groupNameBuffer), STR_INVENTIONS_LIST_RIDE_AND_VEHICLE_NAME, (void*)&rideGroupName); format_string(vehicleNamePtr, std::size(vehicleNameBuffer), itemNameId, nullptr); } else { format_string(groupNamePtr, std::size(groupNameBuffer), itemNameId, nullptr); vehicleNamePtr = nullptr; } // Draw group name gfx_clip_string(groupNameBuffer, columnSplitOffset); gfx_draw_string(dpi, groupNameBuffer, colour, 1, itemY); // Draw vehicle name if (vehicleNamePtr) { gfx_clip_string(vehicleNameBuffer, columnSplitOffset - 11); gfx_draw_string(dpi, vehicleNameBuffer, colour, columnSplitOffset + 1, itemY); } } while (researchItem++->rawValue != researchItemEndMarker); }
/** * * rct2: 0x006848D4 */ void research_finish_item(rct_research_item* researchItem) { gResearchLastItem = *researchItem; research_invalidate_related_windows(); if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { // Ride uint32_t base_ride_type = researchItem->baseRideType; int32_t rideEntryIndex = researchItem->entryIndex; rct_ride_entry* rideEntry = get_ride_entry(rideEntryIndex); if (rideEntry != nullptr && base_ride_type != RIDE_TYPE_NULL) { bool ride_group_was_invented_before = false; bool ride_type_was_invented_before = ride_type_is_invented(base_ride_type); rct_string_id availabilityString; // Determine if the ride group this entry belongs to was invented before. if (RideGroupManager::RideTypeHasRideGroups(base_ride_type)) { const RideGroup* rideGroup = RideGroupManager::GetRideGroup(base_ride_type, rideEntry); if (rideGroup->IsInvented()) { ride_group_was_invented_before = true; } } ride_type_set_invented(base_ride_type); openrct2_assert( base_ride_type < std::size(RideTypePossibleTrackConfigurations), "Invalid base_ride_type = %d", base_ride_type); ride_entry_set_invented(rideEntryIndex); bool seenRideEntry[MAX_RIDE_OBJECTS]{}; rct_research_item* researchItem2 = gResearchItems; for (; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) { if (researchItem2->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem2->type == RESEARCH_ENTRY_TYPE_RIDE) { uint8_t index = researchItem2->entryIndex; seenRideEntry[index] = true; } } // RCT2 made non-separated vehicles available at once, by removing all but one from research. // To ensure old files keep working, look for ride entries not in research, and make them available as well. for (int32_t i = 0; i < MAX_RIDE_OBJECTS; i++) { if (!seenRideEntry[i]) { rct_ride_entry* rideEntry2 = get_ride_entry(i); if (rideEntry2 != nullptr) { for (uint8_t j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) { if (rideEntry2->ride_type[j] == base_ride_type) { ride_entry_set_invented(i); break; } } } } } // If a vehicle should be listed separately (maze, mini golf, flat rides, shops) if (RideGroupManager::RideTypeIsIndependent(base_ride_type)) { availabilityString = STR_NEWS_ITEM_RESEARCH_NEW_RIDE_AVAILABLE; set_format_arg(0, rct_string_id, rideEntry->naming.name); } // If a vehicle is the first to be invented for its ride group, show the ride group name. else if ( !ride_type_was_invented_before || (RideGroupManager::RideTypeHasRideGroups(base_ride_type) && !ride_group_was_invented_before)) { rct_ride_name naming = get_ride_naming(base_ride_type, rideEntry); availabilityString = STR_NEWS_ITEM_RESEARCH_NEW_RIDE_AVAILABLE; set_format_arg(0, rct_string_id, naming.name); } // If the vehicle should not be listed separately and it isn't the first to be invented for its ride group, // report it as a new vehicle for the existing ride group. else { availabilityString = STR_NEWS_ITEM_RESEARCH_NEW_VEHICLE_AVAILABLE; rct_ride_name baseRideNaming = get_ride_naming(base_ride_type, rideEntry); set_format_arg(0, rct_string_id, baseRideNaming.name); set_format_arg(2, rct_string_id, rideEntry->naming.name); } if (!gSilentResearch) { if (gConfigNotifications.ride_researched) { news_item_add_to_queue(NEWS_ITEM_RESEARCH, availabilityString, researchItem->rawValue); } } research_invalidate_related_windows(); } } else { // Scenery rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem->entryIndex); if (sceneryGroupEntry != nullptr) { scenery_group_set_invented(researchItem->entryIndex); set_format_arg(0, rct_string_id, sceneryGroupEntry->name); if (!gSilentResearch) { if (gConfigNotifications.ride_researched) { news_item_add_to_queue( NEWS_ITEM_RESEARCH, STR_NEWS_ITEM_RESEARCH_NEW_SCENERY_SET_AVAILABLE, researchItem->rawValue); } } research_invalidate_related_windows(); init_scenery(); } } }