mirror of https://github.com/OpenRCT2/OpenRCT2.git
252 lines
10 KiB
C++
252 lines
10 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 "../../interface/Viewport.h"
|
|
#include "../../paint/Paint.h"
|
|
#include "../../paint/support/MetalSupports.h"
|
|
#include "../../paint/tile_element/Segment.h"
|
|
#include "../../paint/track/Segment.h"
|
|
#include "../RideData.h"
|
|
#include "../Track.h"
|
|
#include "../TrackPaint.h"
|
|
#include "../Vehicle.h"
|
|
#include "../VehiclePaint.h"
|
|
|
|
static uint32_t SubmarineVehicleGetBaseImageId(const Vehicle* vehicle, const CarEntry* carEntry, int32_t imageDirection)
|
|
{
|
|
uint32_t result = imageDirection;
|
|
if (vehicle->restraints_position >= 64)
|
|
{
|
|
if ((carEntry->GroupEnabled(SpriteGroupType::RestraintAnimation)) && !(imageDirection & 3))
|
|
{
|
|
auto restraintFrame = ((vehicle->restraints_position - 64) / 64) * 4;
|
|
result = (carEntry->SpriteByYaw(imageDirection, SpriteGroupType::RestraintAnimation) + restraintFrame)
|
|
* carEntry->base_num_frames
|
|
+ carEntry->GroupImageId(SpriteGroupType::RestraintAnimation);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = (carEntry->SpriteByYaw(imageDirection, SpriteGroupType::SlopeFlat) * carEntry->base_num_frames)
|
|
+ carEntry->GroupImageId(SpriteGroupType::SlopeFlat) + vehicle->SwingSprite;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D44D5
|
|
*/
|
|
void VehicleVisualSubmarine(
|
|
PaintSession& session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const Vehicle* vehicle,
|
|
const CarEntry* carEntry)
|
|
{
|
|
auto baseImageId = SubmarineVehicleGetBaseImageId(vehicle, carEntry, imageDirection);
|
|
auto imageId0 = ImageId(baseImageId + 0, vehicle->colours.Body, vehicle->colours.Trim, vehicle->colours.Tertiary);
|
|
auto imageId1 = ImageId(baseImageId + 1, vehicle->colours.Body, vehicle->colours.Trim, vehicle->colours.Tertiary);
|
|
if (vehicle->IsGhost())
|
|
{
|
|
imageId0 = ImageId(baseImageId + 0).WithRemap(FilterPaletteID::PaletteGhost);
|
|
imageId1 = ImageId(baseImageId + 1).WithRemap(FilterPaletteID::PaletteGhost);
|
|
}
|
|
|
|
const auto& bb = VehicleBoundboxes[carEntry->draw_order][OpenRCT2::Entity::Yaw::YawTo16(imageDirection)];
|
|
PaintAddImageAsParent(
|
|
session, imageId0, { 0, 0, z },
|
|
{ { bb.offset_x, bb.offset_y, bb.offset_z + z }, { bb.length_x, bb.length_y, bb.length_z } });
|
|
PaintAddImageAsParent(
|
|
session, imageId1, { 0, 0, z },
|
|
{ { bb.offset_x, bb.offset_y, bb.offset_z + z - 10 }, { bb.length_x, bb.length_y, 2 } });
|
|
assert(carEntry->effect_visual == 1);
|
|
}
|
|
|
|
static void SubmarineRidePaintTrackStation(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
const auto* stationObj = ride.GetStationObject();
|
|
int32_t heightLower = height - 16;
|
|
ImageId imageId;
|
|
|
|
if (direction & 1)
|
|
{
|
|
imageId = session.TrackColours.WithIndex(SPR_TRACK_SUBMARINE_RIDE_MINI_HELICOPTERS_FLAT_SE_NW);
|
|
PaintAddImageAsParent(session, imageId, { 0, 0, heightLower }, { { 6, 0, heightLower }, { 20, 32, 3 } });
|
|
|
|
PaintUtilPushTunnelRight(session, height, TUNNEL_SQUARE_FLAT);
|
|
TrackPaintUtilDrawPier(
|
|
session, ride, stationObj, session.MapPosition, direction, height, trackElement, session.CurrentRotation);
|
|
}
|
|
else
|
|
{
|
|
imageId = session.TrackColours.WithIndex(SPR_TRACK_SUBMARINE_RIDE_MINI_HELICOPTERS_FLAT_NE_SW);
|
|
PaintAddImageAsParent(session, imageId, { 0, 0, heightLower }, { { 0, 6, heightLower }, { 32, 20, 3 } });
|
|
|
|
PaintUtilPushTunnelLeft(session, height, TUNNEL_SQUARE_FLAT);
|
|
TrackPaintUtilDrawPier(
|
|
session, ride, stationObj, session.MapPosition, direction, height, trackElement, session.CurrentRotation);
|
|
}
|
|
|
|
PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0);
|
|
PaintUtilSetGeneralSupportHeight(session, height + 32, 0x20);
|
|
}
|
|
|
|
static void SubmarineRidePaintTrackFlat(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
int32_t heightLower = height - 16;
|
|
ImageId imageId;
|
|
|
|
if (direction & 1)
|
|
{
|
|
imageId = session.TrackColours.WithIndex(SPR_TRACK_SUBMARINE_RIDE_MINI_HELICOPTERS_FLAT_SE_NW);
|
|
PaintAddImageAsParent(session, imageId, { 0, 0, heightLower }, { { 6, 0, heightLower }, { 20, 32, 3 } });
|
|
PaintUtilPushTunnelRight(session, heightLower, TUNNEL_0);
|
|
}
|
|
else
|
|
{
|
|
imageId = session.TrackColours.WithIndex(SPR_TRACK_SUBMARINE_RIDE_MINI_HELICOPTERS_FLAT_NE_SW);
|
|
PaintAddImageAsParent(session, imageId, { 0, 0, heightLower }, { { 0, 6, heightLower }, { 32, 20, 3 } });
|
|
PaintUtilPushTunnelLeft(session, heightLower, TUNNEL_0);
|
|
}
|
|
|
|
if (TrackPaintUtilShouldPaintSupports(session.MapPosition))
|
|
{
|
|
MetalASupportsPaintSetup(
|
|
session, (direction & 1) ? MetalSupportType::StickAlt : MetalSupportType::Stick, MetalSupportPlace::Centre, -1,
|
|
heightLower, session.SupportColours);
|
|
}
|
|
|
|
PaintUtilSetSegmentSupportHeight(
|
|
session,
|
|
PaintUtilRotateSegments(
|
|
EnumsToFlags(PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), direction),
|
|
0xFFFF, 0);
|
|
PaintUtilSetGeneralSupportHeight(session, height + 16, 0x20);
|
|
}
|
|
|
|
static void SubmarineRidePaintTrackLeftQuarterTurn3Tiles(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
TrackPaintUtilLeftQuarterTurn3TilesPaint(
|
|
session, 3, height - 16, direction, trackSequence, session.TrackColours,
|
|
kTrackSpritesSubmarineRideMiniHelicoptersQuarterTurn3Tiles);
|
|
TrackPaintUtilLeftQuarterTurn3TilesTunnel(session, height - 16, TUNNEL_0, direction, trackSequence);
|
|
|
|
switch (trackSequence)
|
|
{
|
|
case 0:
|
|
MetalASupportsPaintSetup(
|
|
session, MetalSupportType::Stick, MetalSupportPlace::Centre, -1, height - 16, session.SupportColours);
|
|
PaintUtilSetSegmentSupportHeight(
|
|
session,
|
|
PaintUtilRotateSegments(
|
|
EnumsToFlags(
|
|
PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide,
|
|
PaintSegment::topCorner),
|
|
direction),
|
|
0xFFFF, 0);
|
|
break;
|
|
case 2:
|
|
PaintUtilSetSegmentSupportHeight(
|
|
session,
|
|
PaintUtilRotateSegments(
|
|
EnumsToFlags(
|
|
PaintSegment::topLeftSide, PaintSegment::centre, PaintSegment::bottomLeftSide,
|
|
PaintSegment::leftCorner),
|
|
direction),
|
|
0xFFFF, 0);
|
|
break;
|
|
case 3:
|
|
MetalASupportsPaintSetup(
|
|
session, MetalSupportType::Stick, MetalSupportPlace::Centre, -1, height - 16, session.SupportColours);
|
|
PaintUtilSetSegmentSupportHeight(
|
|
session,
|
|
PaintUtilRotateSegments(
|
|
EnumsToFlags(
|
|
PaintSegment::topLeftSide, PaintSegment::centre, PaintSegment::bottomRightSide,
|
|
PaintSegment::bottomCorner),
|
|
direction),
|
|
0xFFFF, 0);
|
|
break;
|
|
}
|
|
|
|
PaintUtilSetGeneralSupportHeight(session, height + 16, 0x20);
|
|
}
|
|
|
|
static constexpr uint8_t submarine_ride_right_quarter_turn_3_tiles_to_left_turn_map[] = {
|
|
3,
|
|
1,
|
|
2,
|
|
0,
|
|
};
|
|
static void SubmarineRidePaintTrackRightQuarterTurn3Tiles(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
trackSequence = submarine_ride_right_quarter_turn_3_tiles_to_left_turn_map[trackSequence];
|
|
SubmarineRidePaintTrackLeftQuarterTurn3Tiles(session, ride, trackSequence, (direction + 3) % 4, height, trackElement);
|
|
}
|
|
|
|
static void SubmarineRidePaintTrackLeftQuarterTurn1Tile(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
TrackPaintUtilLeftQuarterTurn1TilePaint(
|
|
session, 1, height - 16, 0, direction, session.TrackColours, kTrackSpritesSubmarineRideMiniHelicoptersQuarterTurn1Tile);
|
|
TrackPaintUtilLeftQuarterTurn1TileTunnel(session, direction, height - 16, 0, TUNNEL_0, 0, TUNNEL_0);
|
|
|
|
PaintUtilSetSegmentSupportHeight(
|
|
session,
|
|
PaintUtilRotateSegments(
|
|
EnumsToFlags(
|
|
PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::centre, PaintSegment::bottomLeftSide),
|
|
direction),
|
|
0xFFFF, 0);
|
|
PaintUtilSetGeneralSupportHeight(session, height + 16, 0x20);
|
|
}
|
|
|
|
static void SubmarineRidePaintTrackRightQuarterTurn1Tile(
|
|
PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height,
|
|
const TrackElement& trackElement)
|
|
{
|
|
SubmarineRidePaintTrackLeftQuarterTurn1Tile(session, ride, trackSequence, (direction + 3) % 4, height, trackElement);
|
|
}
|
|
|
|
/**
|
|
* rct2: 0x008995D4
|
|
*/
|
|
TRACK_PAINT_FUNCTION GetTrackPaintFunctionSubmarineRide(int32_t trackType)
|
|
{
|
|
switch (trackType)
|
|
{
|
|
case TrackElemType::BeginStation:
|
|
case TrackElemType::MiddleStation:
|
|
case TrackElemType::EndStation:
|
|
return SubmarineRidePaintTrackStation;
|
|
|
|
case TrackElemType::Flat:
|
|
return SubmarineRidePaintTrackFlat;
|
|
|
|
case TrackElemType::LeftQuarterTurn3Tiles:
|
|
return SubmarineRidePaintTrackLeftQuarterTurn3Tiles;
|
|
case TrackElemType::RightQuarterTurn3Tiles:
|
|
return SubmarineRidePaintTrackRightQuarterTurn3Tiles;
|
|
|
|
case TrackElemType::LeftQuarterTurn1Tile:
|
|
return SubmarineRidePaintTrackLeftQuarterTurn1Tile;
|
|
case TrackElemType::RightQuarterTurn1Tile:
|
|
return SubmarineRidePaintTrackRightQuarterTurn1Tile;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|