1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00

Merge pull request #17997 from karst/steep-flume

Steep track pieces for log flumes
This commit is contained in:
Michael Steenbeek
2022-12-11 15:20:20 +01:00
committed by GitHub
28 changed files with 300 additions and 6 deletions

View File

@@ -43,7 +43,7 @@
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "9"
#define NETWORK_STREAM_VERSION "10"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION

View File

@@ -982,7 +982,7 @@ namespace OpenRCT2
auto found = os.ReadWriteChunk(
ParkFileChunkType::TILES,
[pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap](OrcaStream::ChunkStream& cs) {
[pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap, &os](OrcaStream::ChunkStream& cs) {
cs.ReadWrite(gMapSize.x);
cs.ReadWrite(gMapSize.y);
@@ -1018,6 +1018,16 @@ namespace OpenRCT2
}
}
}
else if (it.element->GetType() == TileElementType::Track)
{
auto* trackElement = it.element->AsTrack();
if (TrackTypeMustBeMadeInvisible(
trackElement->GetRideType(), trackElement->GetTrackType(),
os.GetHeader().TargetVersion))
{
it.element->SetInvisible(true);
}
}
}
}
ParkEntranceUpdateLocations();

View File

@@ -8,7 +8,7 @@ struct ObjectRepositoryItem;
namespace OpenRCT2
{
// Current version that is saved.
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 15;
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 16;
// The minimum version that is forwards compatible with the current version.
constexpr uint32_t PARK_FILE_MIN_VERSION = 14;

View File

@@ -1692,6 +1692,11 @@ namespace RCT1
dst2->SetMazeEntry(src2->GetMazeEntry());
}
if (TrackTypeMustBeMadeInvisible(rideType, trackType))
{
dst->SetInvisible(true);
}
return 1;
}
case TileElementType::SmallScenery:

View File

@@ -1442,6 +1442,11 @@ namespace RCT2
dst2->SetSeatRotation(src2->GetSeatRotation());
}
if (TrackTypeMustBeMadeInvisible(rideType, dst2->GetTrackType()))
{
dst->SetInvisible(true);
}
break;
}
case RCT12TileElementType::SmallScenery:

View File

@@ -921,3 +921,20 @@ void TrackElement::SetHighlight(bool on)
if (on)
Flags2 |= TRACK_ELEMENT_FLAGS2_HIGHLIGHT;
}
bool TrackTypeMustBeMadeInvisible(ride_type_t rideType, track_type_t trackType, int32_t parkFileVersion)
{
// Lots of Log Flumes exist where the downward slopes are simulated by using other track
// types like the Splash Boats, but not actually made invisible, because they never needed
// to be.
if (rideType == RIDE_TYPE_LOG_FLUME && parkFileVersion <= 15)
{
if (trackType == TrackElemType::Down25ToDown60 || trackType == TrackElemType::Down60
|| trackType == TrackElemType::Down60ToDown25)
{
return true;
}
}
return false;
}

View File

@@ -634,3 +634,16 @@ ResultWithMessage track_remove_station_element(const CoordsXYZD& loc, RideId rid
bool TrackTypeHasSpeedSetting(track_type_t trackType);
std::optional<CoordsXYZD> GetTrackSegmentOrigin(const CoordsXYE& posEl);
/**
* If new pieces get added to existing ride types, this could cause existing parks to change appearance,
* since the formerly unrendered pieces were not explicitly set invisible.
* To avoid this, this function will return true if the piece is question was added after the park was created,
* so that import code can properly set the visibility.
*
* @param rideType The OpenRCT2 ride type
* @param trackType The OpenRCT2 track type
* @param parkFileVersion The current park file version. Pass -1 when converting S4 or S6.
* @return
*/
bool TrackTypeMustBeMadeInvisible(ride_type_t rideType, track_type_t trackType, int32_t parkFileVersion = -1);

View File

@@ -10,6 +10,7 @@
#include "../../interface/Viewport.h"
#include "../../paint/Paint.h"
#include "../../paint/Supports.h"
#include "../../sprites.h"
#include "../Track.h"
#include "../TrackPaint.h"
@@ -849,6 +850,128 @@ static void paint_log_flume_track_reverser(
PaintUtilSetGeneralSupportHeight(session, height + 32, 0x20);
}
// Steep Additions added by OpenRCT2
static void log_flume_track_25_down_60(
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
const TrackElement& trackElement)
{
static constexpr const uint32_t imageIds[4][2] = {
{ SPR_G2_FLUME_25_60_NW_SE_BACK, SPR_G2_FLUME_25_60_NW_SE_BACK_WATER },
{ SPR_G2_EMPTY, SPR_G2_FLUME_25_60_NW_SE },
{ SPR_G2_EMPTY, SPR_G2_FLUME_25_60_NE_SW },
{ SPR_G2_FLUME_25_60_NE_SW_BACK, SPR_G2_FLUME_25_60_NE_SW_BACK_WATER },
};
auto imageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][0]);
auto frontImageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][1]);
PaintAddImageAsParentRotated(session, direction, imageId, { 0, 0, height }, { 32, 1, 42 }, { 0, 27, height + 4 });
PaintAddImageAsParentRotated(session, direction, frontImageId, { 0, 0, height }, { 32, 20, 0 }, { 0, 6, height });
if (direction == 1 || direction == 2)
{
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height, session.TrackColours[SCHEME_SUPPORTS]);
}
PaintUtilPushTunnelRotated(session, direction, height, TUNNEL_14);
}
else
{
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height + 12, session.TrackColours[SCHEME_SUPPORTS]);
}
PaintUtilPushTunnelRotated(session, direction, height + 24, TUNNEL_2);
}
PaintUtilSetSegmentSupportHeight(
session, PaintUtilRotateSegments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
PaintUtilSetGeneralSupportHeight(session, height + 56, 0x20);
}
static void log_flume_track_60_down(
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
const TrackElement& trackElement)
{
static constexpr const uint32_t imageIds[4][2] = {
{ SPR_G2_FLUME_60_NW_SE_BACK, SPR_G2_EMPTY },
{ SPR_G2_EMPTY, SPR_G2_FLUME_60_NW_SE },
{ SPR_G2_EMPTY, SPR_G2_FLUME_60_NE_SW },
{ SPR_G2_FLUME_60_NE_SW_BACK, SPR_G2_EMPTY },
};
auto imageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][0]);
auto frontImageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][1]);
PaintAddImageAsParentRotated(session, direction, imageId, { 0, 0, height }, { 32, 1, 98 }, { 0, 27, height + 4 });
PaintAddImageAsParentRotated(session, direction, frontImageId, { 0, 0, height }, { 32, 20, 2 }, { 0, 6, height });
if (direction == 1 || direction == 2)
{
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height, session.TrackColours[SCHEME_SUPPORTS]);
}
PaintUtilPushTunnelRotated(session, direction, height - 8, TUNNEL_SQUARE_7);
}
else
{
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height + 12, session.TrackColours[SCHEME_SUPPORTS]);
}
PaintUtilPushTunnelRotated(session, direction, height + 56, TUNNEL_SQUARE_8);
}
PaintUtilSetSegmentSupportHeight(
session, PaintUtilRotateSegments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
PaintUtilSetGeneralSupportHeight(session, height + 56, 0x20);
}
static void log_flume_track_60_down_25(
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
const TrackElement& trackElement)
{
static constexpr const uint32_t imageIds[4][2] = {
{ SPR_G2_FLUME_60_25_NW_SE_BACK, SPR_G2_FLUME_60_25_NW_SE_BACK_WATER },
{ SPR_G2_EMPTY, SPR_G2_FLUME_60_25_NW_SE },
{ SPR_G2_EMPTY, SPR_G2_FLUME_60_25_NE_SW },
{ SPR_G2_FLUME_60_25_NE_SW_BACK, SPR_G2_FLUME_60_25_NE_SW_BACK_WATER },
};
auto imageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][0]);
auto frontImageId = session.TrackColours[SCHEME_TRACK].WithIndex(imageIds[direction][1]);
PaintAddImageAsParentRotated(session, direction, imageId, { 0, 0, height }, { 32, 1, 42 }, { 0, 27, height + 4 });
PaintAddImageAsParentRotated(session, direction, frontImageId, { 0, 0, height }, { 32, 20, 0 }, { 0, 6, height });
if (direction == 1 || direction == 2)
{
PaintUtilPushTunnelRotated(session, direction, height, TUNNEL_1);
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height, session.TrackColours[SCHEME_SUPPORTS]);
}
}
else
{
PaintUtilPushTunnelRotated(session, direction, height + 24, TUNNEL_SQUARE_FLAT);
if (track_paint_util_should_paint_supports(session.MapPosition))
{
MetalASupportsPaintSetup(session, METAL_SUPPORTS_BOXED, 4, 8, height + 8, session.TrackColours[SCHEME_SUPPORTS]);
}
}
PaintUtilSetSegmentSupportHeight(
session, PaintUtilRotateSegments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
PaintUtilSetGeneralSupportHeight(session, height + 56, 0x20);
}
TRACK_PAINT_FUNCTION get_track_paint_function_log_flume(int32_t trackType)
{
switch (trackType)
@@ -884,6 +1007,14 @@ TRACK_PAINT_FUNCTION get_track_paint_function_log_flume(int32_t trackType)
return paint_log_flume_track_on_ride_photo;
case TrackElemType::LogFlumeReverser:
return paint_log_flume_track_reverser;
// Added by OpenRCT2
case TrackElemType::Down25ToDown60:
return log_flume_track_25_down_60;
case TrackElemType::Down60:
return log_flume_track_60_down;
case TrackElemType::Down60ToDown25:
return log_flume_track_60_down_25;
}
return nullptr;

View File

@@ -19,7 +19,7 @@ constexpr const RideTypeDescriptor LogFlumeRTD =
{
SET_FIELD(AlternateType, RIDE_TYPE_NULL),
SET_FIELD(Category, RIDE_CATEGORY_WATER),
SET_FIELD(EnabledTrackPieces, {TRACK_STRAIGHT, TRACK_STATION_END, TRACK_SLOPE, TRACK_S_BEND, TRACK_CURVE_SMALL, TRACK_ON_RIDE_PHOTO, TRACK_LOG_FLUME_REVERSER}),
SET_FIELD(EnabledTrackPieces, {TRACK_STRAIGHT, TRACK_STATION_END, TRACK_SLOPE, TRACK_S_BEND, TRACK_CURVE_SMALL, TRACK_ON_RIDE_PHOTO, TRACK_LOG_FLUME_REVERSER, TRACK_SLOPE_STEEP_DOWN}),
SET_FIELD(ExtraTrackPieces, {}),
SET_FIELD(CoveredTrackPieces, {}),
SET_FIELD(StartTrackPiece, TrackElemType::EndStation),
@@ -37,7 +37,7 @@ constexpr const RideTypeDescriptor LogFlumeRTD =
SET_FIELD(NameConvention, { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }),
SET_FIELD(EnumName, nameof(RIDE_TYPE_LOG_FLUME)),
SET_FIELD(AvailableBreakdowns, (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE)),
SET_FIELD(Heights, { 9, 24, 7, 9, }),
SET_FIELD(Heights, { 10, 24, 7, 9, }),
SET_FIELD(MaxMass, 255),
SET_FIELD(LiftData, { OpenRCT2::Audio::SoundId::Null, 5, 5 }),
SET_FIELD(RatingsCalculationFunction, ride_ratings_calculate_log_flume),

View File

@@ -1190,9 +1190,26 @@ enum
SPR_G2_LIM_LAUNCHED_TRACK_SMALL_FLAT_TO_STEEP = SPR_G2_LIM_LAUNCHED_TRACK_LARGE_ZERO_G_ROLL + 40,
SPR_G2_LIM_LAUNCHED_TRACK_END = SPR_G2_LIM_LAUNCHED_TRACK_SMALL_FLAT_TO_STEEP + 20,
SPR_G2_FLUME_25_60_NE_SW = SPR_G2_LIM_LAUNCHED_TRACK_END,
SPR_G2_FLUME_25_60_NW_SE,
SPR_G2_FLUME_25_60_NE_SW_BACK_WATER,
SPR_G2_FLUME_25_60_NE_SW_BACK,
SPR_G2_FLUME_25_60_NW_SE_BACK_WATER,
SPR_G2_FLUME_25_60_NW_SE_BACK,
SPR_G2_FLUME_60_NE_SW,
SPR_G2_FLUME_60_NW_SE,
SPR_G2_FLUME_60_NE_SW_BACK,
SPR_G2_FLUME_60_NW_SE_BACK,
SPR_G2_FLUME_60_25_NE_SW,
SPR_G2_FLUME_60_25_NW_SE,
SPR_G2_FLUME_60_25_NE_SW_BACK_WATER,
SPR_G2_FLUME_60_25_NE_SW_BACK,
SPR_G2_FLUME_60_25_NW_SE_BACK_WATER,
SPR_G2_FLUME_60_25_NW_SE_BACK,
// G2 Supports
SPR_G2_SUPPORT_BEGIN = SPR_G2_LIM_LAUNCHED_TRACK_END,
SPR_G2_SUPPORT_BEGIN,
SPR_G2_SUPPORT_END = SPR_G2_SUPPORT_BEGIN + 32,
// G2 New track types