mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor in-memory track design element (#21010)
This commit is contained in:
parent
ee5055a422
commit
baf88ef490
|
@ -441,14 +441,8 @@ private:
|
|||
uint8_t curTrackRotation = rotation;
|
||||
for (const auto& trackElement : td6->track_elements)
|
||||
{
|
||||
int32_t trackType = trackElement.type;
|
||||
if (trackType == TrackElemType::InvertedUp90ToFlatQuarterLoopAlias)
|
||||
{
|
||||
trackType = TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop;
|
||||
}
|
||||
|
||||
// Follow a single track piece shape
|
||||
const auto& ted = GetTrackElementDescriptor(trackType);
|
||||
const auto& ted = GetTrackElementDescriptor(trackElement.Type);
|
||||
const PreviewTrack* trackBlock = ted.Block;
|
||||
while (trackBlock->index != 255)
|
||||
{
|
||||
|
|
|
@ -675,18 +675,26 @@ template<> struct DataSerializerTraitsT<TrackDesignTrackElement>
|
|||
{
|
||||
static void encode(OpenRCT2::IStream* stream, const TrackDesignTrackElement& val)
|
||||
{
|
||||
stream->Write(&val.flags);
|
||||
stream->Write(&val.type);
|
||||
stream->Write(&val.Type);
|
||||
stream->Write(&val.Flags);
|
||||
stream->Write(&val.ColourScheme);
|
||||
stream->Write(&val.StationIndex);
|
||||
stream->Write(&val.BrakeBoosterSpeed);
|
||||
stream->Write(&val.SeatRotation);
|
||||
}
|
||||
static void decode(OpenRCT2::IStream* stream, TrackDesignTrackElement& val)
|
||||
{
|
||||
stream->Read(&val.flags);
|
||||
stream->Read(&val.type);
|
||||
stream->Read(&val.Type);
|
||||
stream->Read(&val.Flags);
|
||||
stream->Read(&val.ColourScheme);
|
||||
stream->Read(&val.StationIndex);
|
||||
stream->Read(&val.BrakeBoosterSpeed);
|
||||
stream->Read(&val.SeatRotation);
|
||||
}
|
||||
static void log(OpenRCT2::IStream* stream, const TrackDesignTrackElement& val)
|
||||
{
|
||||
char msg[128] = {};
|
||||
snprintf(msg, sizeof(msg), "TrackDesignTrackElement(type = %d, flags = %d)", val.type, val.flags);
|
||||
snprintf(msg, sizeof(msg), "TrackDesignTrackElement(type = %d, flags = %d)", val.Type, val.Flags);
|
||||
stream->Write(msg, strlen(msg));
|
||||
}
|
||||
};
|
||||
|
@ -924,4 +932,4 @@ template<> struct DataSerializerTraitsT<Banner>
|
|||
msg, sizeof(msg), "Banner(x = %d, y = %d, text = %s)", banner.position.x, banner.position.y, banner.text.c_str());
|
||||
stream->Write(msg, strlen(msg));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -266,8 +266,8 @@ namespace RCT1
|
|||
_stream.SetPosition(_stream.GetPosition() - 1);
|
||||
_stream.Read(&t4TrackElement, sizeof(TD46TrackElement));
|
||||
TrackDesignTrackElement trackElement{};
|
||||
trackElement.type = RCT1TrackTypeToOpenRCT2(t4TrackElement.Type, td->type);
|
||||
trackElement.flags = t4TrackElement.Flags;
|
||||
trackElement.Type = RCT1TrackTypeToOpenRCT2(t4TrackElement.Type, td->type);
|
||||
ConvertFromTD46Flags(trackElement, t4TrackElement.Flags);
|
||||
td->track_elements.push_back(trackElement);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../rct2/RCT2.h"
|
||||
#include "../ride/Ride.h"
|
||||
#include "../ride/Track.h"
|
||||
#include "../ride/TrackDesign.h"
|
||||
#include "../scenario/Scenario.h"
|
||||
#include "../world/Banner.h"
|
||||
#include "../world/Footpath.h"
|
||||
|
@ -869,3 +870,57 @@ ResearchItem RCT12ResearchItem::ToResearchItem() const
|
|||
|
||||
return newResearchItem;
|
||||
}
|
||||
|
||||
void ConvertFromTD46Flags(TrackDesignTrackElement& target, uint8_t flags)
|
||||
{
|
||||
target.BrakeBoosterSpeed = kRCT2DefaultBlockBrakeSpeed;
|
||||
if (TrackTypeIsStation(target.Type))
|
||||
{
|
||||
auto stationIndex = flags & EnumValue(TD46Flags::StationId);
|
||||
target.StationIndex = StationIndex::FromUnderlying(stationIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto speedOrSeatRotation = flags & EnumValue(TD46Flags::SpeedOrSeatRotation);
|
||||
if (TrackTypeHasSpeedSetting(target.Type) && target.Type != TrackElemType::BlockBrakes)
|
||||
{
|
||||
target.BrakeBoosterSpeed = speedOrSeatRotation << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
target.SeatRotation = speedOrSeatRotation;
|
||||
}
|
||||
}
|
||||
|
||||
target.ColourScheme = (flags & EnumValue(TD46Flags::ColourScheme)) >> 4;
|
||||
if (flags & EnumValue(TD46Flags::IsInverted))
|
||||
target.SetFlag(TrackDesignTrackElementFlag::IsInverted);
|
||||
if (flags & EnumValue(TD46Flags::HasChain))
|
||||
target.SetFlag(TrackDesignTrackElementFlag::HasChain);
|
||||
}
|
||||
|
||||
uint8_t ConvertToTD46Flags(const TrackDesignTrackElement& source)
|
||||
{
|
||||
uint8_t trackFlags = 0;
|
||||
if (TrackTypeIsStation(source.Type))
|
||||
{
|
||||
trackFlags = (source.StationIndex.ToUnderlying() & EnumValue(TD46Flags::StationId));
|
||||
}
|
||||
else if (TrackTypeHasSpeedSetting(source.Type) && source.Type != TrackElemType::BlockBrakes)
|
||||
{
|
||||
trackFlags = (source.BrakeBoosterSpeed >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
trackFlags = source.SeatRotation;
|
||||
}
|
||||
|
||||
trackFlags |= source.ColourScheme << 4;
|
||||
|
||||
if (source.HasFlag(TrackDesignTrackElementFlag::HasChain))
|
||||
trackFlags |= EnumValue(TD46Flags::HasChain);
|
||||
if (source.HasFlag(TrackDesignTrackElementFlag::IsInverted))
|
||||
trackFlags |= EnumValue(TD46Flags::IsInverted);
|
||||
|
||||
return trackFlags;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ constexpr uint8_t RCT12PeepThoughtItemNone = std::numeric_limits<uint8_t>::max()
|
|||
constexpr uint8_t RCT12GuestsInParkHistoryFactor = 20;
|
||||
constexpr uint8_t RCT12ParkHistoryUndefined = std::numeric_limits<uint8_t>::max();
|
||||
|
||||
struct TrackDesignTrackElement;
|
||||
|
||||
enum class RCT12TrackDesignVersion : uint8_t
|
||||
{
|
||||
TD4,
|
||||
|
@ -900,3 +902,15 @@ template<typename T> std::vector<RideId> RCT12GetRidesBeenOn(T* srcPeep)
|
|||
}
|
||||
return ridesBeenOn;
|
||||
}
|
||||
|
||||
enum class TD46Flags : uint8_t
|
||||
{
|
||||
StationId = 0b00000011,
|
||||
SpeedOrSeatRotation = 0b00001111,
|
||||
ColourScheme = 0b00110000,
|
||||
IsInverted = 0b01000000,
|
||||
HasChain = 0b10000000,
|
||||
};
|
||||
|
||||
void ConvertFromTD46Flags(TrackDesignTrackElement& target, uint8_t flags);
|
||||
uint8_t ConvertToTD46Flags(const TrackDesignTrackElement& source);
|
||||
|
|
|
@ -111,13 +111,14 @@ namespace RCT2
|
|||
{
|
||||
for (const auto& trackElement : _trackDesign->track_elements)
|
||||
{
|
||||
auto trackType = OpenRCT2TrackTypeToRCT2(trackElement.type);
|
||||
auto trackType = OpenRCT2TrackTypeToRCT2(trackElement.Type);
|
||||
if (trackType == TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop)
|
||||
{
|
||||
trackType = TrackElemType::InvertedUp90ToFlatQuarterLoopAlias;
|
||||
}
|
||||
tempStream.WriteValue<uint8_t>(static_cast<uint8_t>(trackType));
|
||||
tempStream.WriteValue<uint8_t>(trackElement.flags);
|
||||
auto flags = ConvertToTD46Flags(trackElement);
|
||||
tempStream.WriteValue<uint8_t>(flags);
|
||||
}
|
||||
|
||||
tempStream.WriteValue<uint8_t>(0xFF);
|
||||
|
|
|
@ -171,8 +171,8 @@ namespace RCT2
|
|||
trackType = TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop;
|
||||
}
|
||||
|
||||
trackElement.type = trackType;
|
||||
trackElement.flags = t6TrackElement.Flags;
|
||||
trackElement.Type = trackType;
|
||||
ConvertFromTD46Flags(trackElement, t6TrackElement.Flags);
|
||||
td->track_elements.push_back(trackElement);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,12 +82,6 @@ enum
|
|||
RCT_PREVIEW_TRACK_FLAG_IS_VERTICAL = (1 << 2),
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TRACK_ELEMENT_FLAG_TERMINAL_STATION = 1 << 3,
|
||||
TD6_TRACK_ELEMENT_FLAG_INVERTED = 1 << 6,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TRACK_ELEMENT_FLAGS2_CHAIN_LIFT = 1 << 0,
|
||||
|
|
|
@ -214,43 +214,35 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con
|
|||
|
||||
do
|
||||
{
|
||||
const auto& element = trackElement.element->AsTrack();
|
||||
|
||||
// Remove this check for new track design format
|
||||
if (trackElement.element->AsTrack()->GetTrackType() > TrackElemType::HighestAlias)
|
||||
if (element->GetTrackType() > TrackElemType::HighestAlias)
|
||||
{
|
||||
return { false, STR_TRACK_ELEM_UNSUPPORTED_TD6 };
|
||||
}
|
||||
|
||||
TrackDesignTrackElement track{};
|
||||
track.type = trackElement.element->AsTrack()->GetTrackType();
|
||||
|
||||
uint8_t trackFlags;
|
||||
// This if-else block only applies to td6. New track design format will always encode speed and seat rotation.
|
||||
if (TrackTypeHasSpeedSetting(track.type) && track.type != TrackElemType::BlockBrakes)
|
||||
{
|
||||
trackFlags = trackElement.element->AsTrack()->GetBrakeBoosterSpeed() >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackFlags = trackElement.element->AsTrack()->GetSeatRotation();
|
||||
}
|
||||
track.Type = element->GetTrackType();
|
||||
track.ColourScheme = element->GetColourScheme();
|
||||
track.StationIndex = element->GetStationIndex();
|
||||
track.BrakeBoosterSpeed = element->GetBrakeBoosterSpeed();
|
||||
track.SeatRotation = element->GetSeatRotation();
|
||||
|
||||
// This warning will not apply to new track design format
|
||||
if (track.type == TrackElemType::BlockBrakes
|
||||
&& trackElement.element->AsTrack()->GetBrakeBoosterSpeed() != kRCT2DefaultBlockBrakeSpeed)
|
||||
if (track.Type == TrackElemType::BlockBrakes && element->GetBrakeBoosterSpeed() != kRCT2DefaultBlockBrakeSpeed)
|
||||
{
|
||||
warningMessage = STR_TRACK_DESIGN_BLOCK_BRAKE_SPEED_RESET;
|
||||
}
|
||||
|
||||
if (trackElement.element->AsTrack()->HasChain())
|
||||
trackFlags |= RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT;
|
||||
trackFlags |= trackElement.element->AsTrack()->GetColourScheme() << 4;
|
||||
if (ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE)
|
||||
&& trackElement.element->AsTrack()->IsInverted())
|
||||
if (element->HasChain())
|
||||
track.SetFlag(TrackDesignTrackElementFlag::HasChain);
|
||||
|
||||
if (ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE) && element->IsInverted())
|
||||
{
|
||||
trackFlags |= TD6_TRACK_ELEMENT_FLAG_INVERTED;
|
||||
track.SetFlag(TrackDesignTrackElementFlag::IsInverted);
|
||||
}
|
||||
|
||||
track.flags = trackFlags;
|
||||
track_elements.push_back(track);
|
||||
|
||||
if (!TrackBlockGetNext(&trackElement, &trackElement, nullptr, nullptr))
|
||||
|
@ -898,8 +890,8 @@ static void TrackDesignMirrorRide(TrackDesign* td6)
|
|||
{
|
||||
for (auto& track : td6->track_elements)
|
||||
{
|
||||
const auto& ted = GetTrackElementDescriptor(track.type);
|
||||
track.type = ted.MirrorElement;
|
||||
const auto& ted = GetTrackElementDescriptor(track.Type);
|
||||
track.Type = ted.MirrorElement;
|
||||
}
|
||||
|
||||
for (auto& entrance : td6->entrance_elements)
|
||||
|
@ -1595,7 +1587,7 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi
|
|||
auto newCoords = origin;
|
||||
for (const auto& track : td6->track_elements)
|
||||
{
|
||||
auto trackType = track.type;
|
||||
auto trackType = track.Type;
|
||||
const auto& ted = GetTrackElementDescriptor(trackType);
|
||||
|
||||
TrackDesignUpdatePreviewBounds(tds, newCoords);
|
||||
|
@ -1632,26 +1624,13 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi
|
|||
|
||||
// di
|
||||
int16_t tempZ = newCoords.z - trackCoordinates->z_begin;
|
||||
uint32_t trackColour = (track.flags >> 4) & 0x3;
|
||||
uint32_t brakeSpeed;
|
||||
// RCT2-created track designs write brake speed to all tracks; block brake speed must be treated as
|
||||
// garbage data.
|
||||
if (trackType == TrackElemType::BlockBrakes)
|
||||
{
|
||||
brakeSpeed = kRCT2DefaultBlockBrakeSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
brakeSpeed = (track.flags & 0x0F) * 2;
|
||||
}
|
||||
uint32_t seatRotation = track.flags & 0x0F;
|
||||
|
||||
int32_t liftHillAndAlternativeState = 0;
|
||||
if (track.flags & RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT)
|
||||
if (track.HasFlag(TrackDesignTrackElementFlag::HasChain))
|
||||
{
|
||||
liftHillAndAlternativeState |= 1;
|
||||
}
|
||||
if (track.flags & TD6_TRACK_ELEMENT_FLAG_INVERTED)
|
||||
if (track.HasFlag(TrackDesignTrackElementFlag::IsInverted))
|
||||
{
|
||||
liftHillAndAlternativeState |= 2;
|
||||
}
|
||||
|
@ -1678,8 +1657,8 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi
|
|||
}
|
||||
|
||||
auto trackPlaceAction = TrackPlaceAction(
|
||||
ride.id, trackType, ride.type, { newCoords, tempZ, static_cast<uint8_t>(rotation) }, brakeSpeed,
|
||||
trackColour, seatRotation, liftHillAndAlternativeState, true);
|
||||
ride.id, trackType, ride.type, { newCoords, tempZ, static_cast<uint8_t>(rotation) },
|
||||
track.BrakeBoosterSpeed, track.ColourScheme, track.SeatRotation, liftHillAndAlternativeState, true);
|
||||
trackPlaceAction.SetFlags(flags);
|
||||
|
||||
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&trackPlaceAction)
|
||||
|
|
|
@ -62,15 +62,36 @@ struct TrackDesignSceneryElement
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Track design structure.
|
||||
*/
|
||||
enum class TrackDesignTrackElementFlag : uint8_t
|
||||
{
|
||||
HasChain = (1 << 0),
|
||||
IsInverted = (1 << 1),
|
||||
IsCovered = (1 << 2), // Reserved
|
||||
};
|
||||
|
||||
/* Track Element entry size: 0x03 */
|
||||
struct TrackDesignTrackElement
|
||||
{
|
||||
track_type_t type; // 0x00
|
||||
uint8_t flags; // 0x02
|
||||
track_type_t Type = 0;
|
||||
uint8_t Flags = 0;
|
||||
uint8_t ColourScheme = 0;
|
||||
::StationIndex StationIndex = StationIndex::FromUnderlying(0);
|
||||
uint8_t BrakeBoosterSpeed = 0;
|
||||
uint8_t SeatRotation = 4;
|
||||
|
||||
constexpr bool HasFlag(const TrackDesignTrackElementFlag flag) const
|
||||
{
|
||||
return Flags & EnumValue(flag);
|
||||
}
|
||||
|
||||
constexpr void SetFlag(const TrackDesignTrackElementFlag flag)
|
||||
{
|
||||
Flags |= EnumValue(flag);
|
||||
}
|
||||
|
||||
constexpr void ClearFlag(const TrackDesignTrackElementFlag flag)
|
||||
{
|
||||
Flags &= ~EnumValue(flag);
|
||||
}
|
||||
};
|
||||
|
||||
/* Maze Element entry size: 0x04 */
|
||||
|
|
Loading…
Reference in New Issue