forked from OpenLoco/OpenLoco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Object.h
131 lines (116 loc) · 3.01 KB
/
Object.h
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
#pragma once
#include <cstdint>
#include <cstring>
#include <limits>
#include <string_view>
namespace OpenLoco
{
enum class ObjectType : uint8_t
{
interfaceSkin,
sound,
currency,
steam,
cliffEdge,
water,
land,
townNames,
cargo,
wall,
trackSignal,
levelCrossing,
streetLight,
tunnel,
bridge,
trackStation,
trackExtra,
track,
roadStation,
roadExtra,
road,
airport,
dock,
vehicle,
tree,
snow,
climate,
hillShapes,
building,
scaffolding,
industry,
region,
competitor,
scenarioText,
};
#pragma pack(push, 1)
struct ObjectHeader
{
private:
static constexpr char cFF = static_cast<char>(0xFF);
static constexpr uint32_t kFuzzyFlagsMask = 0xFFFE0000;
public:
uint32_t flags = 0xFFFFFFFF;
char name[8] = { cFF, cFF, cFF, cFF, cFF, cFF, cFF, cFF };
uint32_t checksum = 0xFFFFFFFF;
std::string_view getName() const
{
return std::string_view(name, sizeof(name));
}
constexpr uint8_t getSourceGame() const
{
return (flags >> 6) & 0x3;
}
constexpr ObjectType getType() const
{
return static_cast<ObjectType>(flags & 0x3F);
}
constexpr uint32_t getFuzzyFlags() const
{
return flags & kFuzzyFlagsMask;
}
constexpr bool isCustom() const
{
return getSourceGame() == 0;
}
bool isEmpty() const
{
auto ab = reinterpret_cast<const int64_t*>(this);
return ab[0] == -1 && ab[1] == -1;
}
bool operator==(const ObjectHeader& rhs) const
{
// Some vanilla objects reference other vanilla objects using a
// ObjectHeader that is set as custom. To handle those we need
// to check both the lhs and the rhs and only if both are Custom
// do the full check.
if (isCustom() && rhs.isCustom())
{
return std::memcmp(this, &rhs, sizeof(ObjectHeader)) == 0;
}
else
{
return getType() == rhs.getType() && getName() == rhs.getName();
}
}
bool operator!=(const ObjectHeader& rhs) const
{
return !(*this == rhs);
}
};
static_assert(sizeof(ObjectHeader) == 0x10);
#pragma pack(pop)
/**
* Represents an index / ID of a specific object type.
*/
using LoadedObjectId = uint16_t;
/**
* Represents an undefined index / ID for a specific object type.
*/
static constexpr LoadedObjectId NullObjectId = std::numeric_limits<LoadedObjectId>::max();
struct LoadedObjectHandle
{
ObjectType type;
LoadedObjectId id;
};
static_assert(sizeof(LoadedObjectHandle) == 4);
}