File: TileElements.cpp

package info (click to toggle)
openrct2 0.4.3%2Bds-1
  • links: PTS, VCS
  • area: contrib
  • in suites: bookworm
  • size: 67,880 kB
  • sloc: cpp: 549,527; ansic: 1,322; sh: 441; python: 269; xml: 180; php: 34; makefile: 19
file content (173 lines) | stat: -rw-r--r-- 8,203 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*****************************************************************************
 * Copyright (c) 2014-2022 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 "TestData.h"

#include <gtest/gtest.h>
#include <memory>
#include <openrct2/Context.h>
#include <openrct2/Game.h>
#include <openrct2/OpenRCT2.h>
#include <openrct2/ParkImporter.h>
#include <openrct2/world/Footpath.h>
#include <openrct2/world/Map.h>

using namespace OpenRCT2;

class TileElementWantsFootpathConnection : public testing::Test
{
protected:
    static void SetUpTestCase()
    {
        std::string parkPath = TestData::GetParkPath("tile-element-tests.sv6");
        gOpenRCT2Headless = true;
        gOpenRCT2NoGraphics = true;
        _context = CreateContext();
        bool initialised = _context->Initialise();
        ASSERT_TRUE(initialised);

        GetContext()->LoadParkFromFile(parkPath);
        game_load_init();

        // Changed in some tests. Store to restore its value
        _gScreenFlags = gScreenFlags;
        SUCCEED();
    }

    static void TearDownTestCase()
    {
        if (_context)
            _context.reset();

        gScreenFlags = _gScreenFlags;
    }

private:
    static std::shared_ptr<IContext> _context;
    static uint8_t _gScreenFlags;
};

std::shared_ptr<IContext> TileElementWantsFootpathConnection::_context;
uint8_t TileElementWantsFootpathConnection::_gScreenFlags;

TEST_F(TileElementWantsFootpathConnection, FlatPath)
{
    // Flat paths want to connect to other paths in any direction
    const TileElement* const pathElement = MapGetFootpathElement(TileCoordsXYZ{ 19, 18, 14 }.ToCoordsXYZ());
    ASSERT_NE(pathElement, nullptr);
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 19, 18, 14, 0 }, nullptr));
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 19, 18, 14, 1 }, nullptr));
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 19, 18, 14, 2 }, nullptr));
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 19, 18, 14, 3 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, SlopedPath)
{
    // Sloped paths only want to connect in two directions, of which is one at a higher offset
    const TileElement* const slopedPathElement = MapGetFootpathElement(TileCoordsXYZ{ 18, 18, 14 }.ToCoordsXYZ());
    ASSERT_NE(slopedPathElement, nullptr);
    ASSERT_TRUE(slopedPathElement->AsPath()->IsSloped());
    // Bottom and top of sloped path want a path connection
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 18, 18, 14, 2 }, nullptr));
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 18, 18, 16, 0 }, nullptr));
    // Other directions at both heights do not want a connection
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 14, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 14, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 14, 3 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 16, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 16, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 16, 3 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, Stall)
{
    // Stalls usually have one path direction flag, but can have multiple (info kiosk for example)
    auto tileCoords = TileCoordsXYZ{ 19, 15, 14 };
    const TrackElement* const stallElement = MapGetTrackElementAt(tileCoords.ToCoordsXYZ());
    ASSERT_NE(stallElement, nullptr);
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 19, 15, 14, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 15, 14, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 15, 14, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 15, 14, 3 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, RideEntrance)
{
    // Ride entrances and exits want a connection in one direction
    const EntranceElement* const entranceElement = MapGetRideEntranceElementAt(TileCoordsXYZ{ 18, 8, 14 }.ToCoordsXYZ(), false);
    ASSERT_NE(entranceElement, nullptr);
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 18, 8, 14, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 8, 14, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 8, 14, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 8, 14, 3 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, RideExit)
{
    // The exit has been rotated; it wants a path connection in direction 1, but not 0 like the entrance
    const EntranceElement* const exitElement = MapGetRideExitElementAt(TileCoordsXYZ{ 18, 10, 14 }.ToCoordsXYZ(), false);
    ASSERT_NE(exitElement, nullptr);
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 10, 14, 0 }, nullptr));
    EXPECT_TRUE(TileElementWantsPathConnectionTowards({ 18, 10, 14, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 10, 14, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 10, 14, 3 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, DifferentHeight)
{
    // Test at different heights, all of these should fail
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 4, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 4, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 4, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 4, 3 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 4, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 6, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 15, 4, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 8, 4, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 10, 4, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 24, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 24, 1 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 24, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 18, 24, 3 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 24, 2 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 18, 26, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 19, 15, 24, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 8, 24, 0 }, nullptr));
    EXPECT_FALSE(TileElementWantsPathConnectionTowards({ 18, 10, 24, 1 }, nullptr));
    SUCCEED();
}

TEST_F(TileElementWantsFootpathConnection, MapEdge)
{
    // Paths at the map edge should have edge flags turned on when placed in scenario editor
    // This tile is a single, unconnected footpath on the map edge - on load, GetEdges() returns 0
    TileElement* pathElement = MapGetFootpathElement(TileCoordsXYZ{ 1, 4, 14 }.ToCoordsXYZ());

    // Enable flag to simulate enabling the scenario editor
    gScreenFlags |= SCREEN_FLAGS_SCENARIO_EDITOR;

    // Calculate the connected edges and set the appropriate edge flags
    FootpathConnectEdges({ 16, 64 }, pathElement, 0);
    auto edges = pathElement->AsPath()->GetEdges();

    // The tiles alongside in the Y direction are both on the map edge so should be marked as an edge
    EXPECT_TRUE(edges & (1 << 1));
    EXPECT_TRUE(edges & (1 << 3));

    // The tile in the -X direction is off the map so should be marked as an edge
    EXPECT_TRUE(edges & (1 << 0));

    // The tile in the -X direction is a normal tile and should not be marked as an edge
    EXPECT_FALSE(edges & (1 << 2));
}