OpenRCT2/src/openrct2/ride/gentle/FerrisWheel.cpp

183 lines
6.8 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "../../entity/EntityRegistry.h"
#include "../../entity/Guest.h"
#include "../../interface/Viewport.h"
#include "../../paint/Boundbox.h"
#include "../../paint/Paint.h"
#include "../../paint/support/WoodenSupports.h"
#include "../../paint/tile_element/Segment.h"
#include "../../paint/track/Segment.h"
#include "../Ride.h"
#include "../RideEntry.h"
#include "../Track.h"
#include "../TrackPaint.h"
#include "../Vehicle.h"
static constexpr uint8_t Edges1X4NeSw[] = {
EDGE_NW | EDGE_SE,
EDGE_NW | EDGE_SE | EDGE_NE,
EDGE_NW | EDGE_SE,
EDGE_NW | EDGE_SE | EDGE_SW,
};
static constexpr uint8_t Edges1X4NwSe[] = {
EDGE_NE | EDGE_SW,
EDGE_NE | EDGE_SW | EDGE_NW,
EDGE_NE | EDGE_SW,
EDGE_NE | EDGE_SW | EDGE_SE,
};
/** rct2: 0x008A8CA8 */
static constexpr BoundBoxXY FerrisWheelData[] = {
{ { 1, 8 }, { 31, 16 } },
{ { 8, 1 }, { 16, 31 } },
{ { 1, 8 }, { 31, 16 } },
{ { 8, 1 }, { 16, 31 } },
};
static void PaintFerrisWheelRiders(
PaintSession& session, const RideObjectEntry& rideEntry, const Vehicle& vehicle, uint8_t direction, const CoordsXYZ offset,
const BoundBoxXYZ& bb)
{
for (int32_t i = 0; i < 32; i += 2)
{
auto* peep = GetEntity<Guest>(vehicle.peep[i]);
if (peep == nullptr || peep->State != PeepState::OnRide)
continue;
auto frameNum = (vehicle.Pitch + i * 4) % 128;
auto imageIndex = rideEntry.Cars[0].base_image_id + 32 + direction * 128 + frameNum;
auto imageId = ImageId(imageIndex, vehicle.peep_tshirt_colours[i], vehicle.peep_tshirt_colours[i + 1]);
PaintAddImageAsChild(session, imageId, offset, bb);
}
}
static void PaintFerrisWheelStructure(
PaintSession& session, const Ride& ride, uint8_t direction, int8_t axisOffset, uint16_t height, ImageId stationColour)
{
auto rideEntry = ride.GetRideEntry();
if (rideEntry == nullptr)
return;
auto vehicle = GetEntity<Vehicle>(ride.vehicles[0]);
if (ride.lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
session.InteractionType = ViewportInteractionItem::Entity;
session.CurrentlyDrawnEntity = vehicle;
}
auto boundBox = FerrisWheelData[direction];
CoordsXYZ offset((direction & 1) ? 0 : axisOffset, (direction & 1) ? axisOffset : 0, height + 7);
BoundBoxXYZ bb = { { boundBox.offset, height + 7 }, { boundBox.length, 127 } };
auto supportsImageTemplate = session.TrackColours;
auto wheelImageTemplate = ImageId(0, ride.vehicle_colours[0].Body, ride.vehicle_colours[0].Trim);
if (stationColour != TrackStationColour)
{
wheelImageTemplate = stationColour;
}
auto imageOffset = vehicle != nullptr ? vehicle->Pitch % 8 : 0;
auto leftSupportImageId = supportsImageTemplate.WithIndex(22150 + (direction & 1) * 2);
auto wheelImageId = wheelImageTemplate.WithIndex(rideEntry->Cars[0].base_image_id + direction * 8 + imageOffset);
auto rightSupportImageId = leftSupportImageId.WithIndexOffset(1);
PaintAddImageAsParent(session, leftSupportImageId, offset, bb);
PaintAddImageAsChild(session, wheelImageId, offset, bb);
if (vehicle != nullptr)
{
PaintFerrisWheelRiders(session, *rideEntry, *vehicle, direction, offset, bb);
}
PaintAddImageAsChild(session, rightSupportImageId, offset, bb);
session.CurrentlyDrawnEntity = nullptr;
session.InteractionType = ViewportInteractionItem::Ride;
}
static void PaintFerrisWheel(
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
const TrackElement& trackElement)
{
uint8_t relativeTrackSequence = kTrackMap1x4[direction][trackSequence];
int32_t edges;
if (direction & 1)
{
edges = Edges1X4NwSe[relativeTrackSequence];
}
else
{
edges = Edges1X4NeSw[relativeTrackSequence];
}
auto stationColour = GetStationColourScheme(session, trackElement);
WoodenASupportsPaintSetupRotated(
session, WoodenSupportType::Truss, WoodenSupportSubType::NeSw, direction, height, stationColour);
const StationObject* stationObject = ride.GetStationObject();
TrackPaintUtilPaintFloor(session, edges, session.TrackColours, height, kFloorSpritesCork, stationObject);
ImageId imageId;
uint8_t rotation = session.CurrentRotation;
if (edges & EDGE_NW && TrackPaintUtilHasFence(EDGE_NW, session.MapPosition, trackElement, ride, rotation))
{
imageId = stationColour.WithIndex(SPR_FENCE_ROPE_NW);
PaintAddImageAsChild(session, imageId, { 0, 0, height }, { { 0, 2, height + 2 }, { 32, 1, 7 } });
}
if (edges & EDGE_NE && TrackPaintUtilHasFence(EDGE_NE, session.MapPosition, trackElement, ride, rotation))
{
imageId = stationColour.WithIndex(SPR_FENCE_ROPE_NE);
PaintAddImageAsChild(session, imageId, { 0, 0, height }, { { 2, 0, height + 2 }, { 1, 32, 7 } });
}
if (edges & EDGE_SE && TrackPaintUtilHasFence(EDGE_SE, session.MapPosition, trackElement, ride, rotation))
{
// Bound box is slightly different from TrackPaintUtilPaintFences
imageId = stationColour.WithIndex(SPR_FENCE_ROPE_SE);
PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 0, 29, height + 3 }, { 28, 1, 7 } });
}
if (edges & EDGE_SW && TrackPaintUtilHasFence(EDGE_SW, session.MapPosition, trackElement, ride, rotation))
{
imageId = stationColour.WithIndex(SPR_FENCE_ROPE_SW);
PaintAddImageAsParent(session, imageId, { 0, 0, height }, { { 30, 0, height + 2 }, { 1, 32, 7 } });
}
switch (relativeTrackSequence)
{
case 1:
PaintFerrisWheelStructure(session, ride, direction, 48, height, stationColour);
break;
case 2:
PaintFerrisWheelStructure(session, ride, direction, 16, height, stationColour);
break;
case 0:
PaintFerrisWheelStructure(session, ride, direction, -16, height, stationColour);
break;
case 3:
PaintFerrisWheelStructure(session, ride, direction, -48, height, stationColour);
break;
}
PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0);
PaintUtilSetGeneralSupportHeight(session, height + 176, 0x20);
}
TRACK_PAINT_FUNCTION GetTrackPaintFunctionFerrisWheel(int32_t trackType)
{
if (trackType != TrackElemType::FlatTrack1x4C)
{
return nullptr;
}
return PaintFerrisWheel;
}