mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 20:13:07 +01:00
Add path surface object type
This commit is contained in:
@@ -109,6 +109,7 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[] = {
|
||||
{ STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false },
|
||||
{ STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false },
|
||||
{ STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false },
|
||||
{ STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false },
|
||||
};
|
||||
|
||||
#pragma region Widgets
|
||||
@@ -295,8 +296,7 @@ static void visible_list_refresh(rct_window* w)
|
||||
{
|
||||
uint8_t selectionFlags = _objectSelectionFlags[i];
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
if (objectType == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item)
|
||||
if (item->Type == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item)
|
||||
&& filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags))
|
||||
{
|
||||
auto filter = std::make_unique<rct_object_filters>();
|
||||
@@ -1425,7 +1425,7 @@ static bool filter_string(const ObjectRepositoryItem* item)
|
||||
|
||||
// Check if the searched string exists in the name, ride type, or filename
|
||||
bool inName = strstr(name_lower, filter_lower) != nullptr;
|
||||
bool inRideType = (item->ObjectEntry.GetType() == ObjectType::Ride) && strstr(type_lower, filter_lower) != nullptr;
|
||||
bool inRideType = (item->Type == ObjectType::Ride) && strstr(type_lower, filter_lower) != nullptr;
|
||||
bool inPath = strstr(object_path, filter_lower) != nullptr;
|
||||
|
||||
return inName || inRideType || inPath;
|
||||
@@ -1468,7 +1468,7 @@ static bool filter_source(const ObjectRepositoryItem* item)
|
||||
|
||||
static bool filter_chunks(const ObjectRepositoryItem* item)
|
||||
{
|
||||
if (item->ObjectEntry.GetType() == ObjectType::Ride)
|
||||
if (item->Type == ObjectType::Ride)
|
||||
{
|
||||
uint8_t rideType = 0;
|
||||
for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
||||
@@ -1498,8 +1498,7 @@ static void filter_update_counts()
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
if (filter_source(item) && filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags[i]))
|
||||
{
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
_filter_object_counts[EnumValue(objectType)]++;
|
||||
_filter_object_counts[EnumValue(item->Type)]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ static void setup_track_manager_objects()
|
||||
{
|
||||
uint8_t* selectionFlags = &_objectSelectionFlags[i];
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
ObjectType object_type = item->ObjectEntry.GetType();
|
||||
if (object_type == ObjectType::Ride)
|
||||
if (item->Type == ObjectType::Ride)
|
||||
{
|
||||
*selectionFlags |= OBJECT_SELECTION_FLAG_6;
|
||||
|
||||
@@ -85,8 +84,7 @@ static void setup_track_designer_objects()
|
||||
{
|
||||
uint8_t* selectionFlags = &_objectSelectionFlags[i];
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
if (objectType == ObjectType::Ride)
|
||||
if (item->Type == ObjectType::Ride)
|
||||
{
|
||||
*selectionFlags |= OBJECT_SELECTION_FLAG_6;
|
||||
|
||||
@@ -271,7 +269,7 @@ void sub_6AB211()
|
||||
const ObjectRepositoryItem* items = object_repository_get_items();
|
||||
for (int32_t i = 0; i < numObjects; i++)
|
||||
{
|
||||
ObjectType objectType = items[i].ObjectEntry.GetType();
|
||||
auto objectType = items[i].Type;
|
||||
_numAvailableObjectsForType[EnumValue(objectType)]++;
|
||||
}
|
||||
|
||||
@@ -445,7 +443,7 @@ void reset_selected_object_count_and_size()
|
||||
const ObjectRepositoryItem* items = object_repository_get_items();
|
||||
for (int32_t i = 0; i < numObjects; i++)
|
||||
{
|
||||
ObjectType objectType = items[i].ObjectEntry.GetType();
|
||||
auto objectType = items[i].Type;
|
||||
if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)
|
||||
{
|
||||
_numSelectedObjectsForType[EnumValue(objectType)]++;
|
||||
@@ -527,7 +525,7 @@ bool window_editor_object_selection_select_object(uint8_t isMasterObject, int32_
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
ObjectType objectType = item->Type;
|
||||
if (objectType == ObjectType::SceneryGroup && (flags & INPUT_FLAG_EDITOR_OBJECT_SELECT_OBJECTS_IN_SCENERY_GROUP))
|
||||
{
|
||||
for (const auto& sgEntry : item->SceneryGroupInfo.Entries)
|
||||
@@ -554,7 +552,7 @@ bool window_editor_object_selection_select_object(uint8_t isMasterObject, int32_
|
||||
return true;
|
||||
}
|
||||
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
ObjectType objectType = item->Type;
|
||||
uint16_t maxObjects = object_entry_group_counts[EnumValue(objectType)];
|
||||
|
||||
if (maxObjects <= _numSelectedObjectsForType[EnumValue(objectType)])
|
||||
@@ -617,7 +615,7 @@ bool editor_check_object_group_at_least_one_selected(ObjectType checkObjectType)
|
||||
|
||||
for (size_t i = 0; i < numObjects; i++)
|
||||
{
|
||||
ObjectType objectType = items[i].ObjectEntry.GetType();
|
||||
auto objectType = items[i].Type;
|
||||
if (checkObjectType == objectType && (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED))
|
||||
{
|
||||
return true;
|
||||
@@ -643,7 +641,7 @@ int32_t editor_remove_unused_objects()
|
||||
&& !(_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED))
|
||||
{
|
||||
const ObjectRepositoryItem* item = &items[i];
|
||||
ObjectType objectType = item->ObjectEntry.GetType();
|
||||
ObjectType objectType = item->Type;
|
||||
|
||||
if (objectType >= ObjectType::SceneryGroup)
|
||||
{
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
<ClInclude Include="object\FootpathItemObject.h" />
|
||||
<ClInclude Include="object\FootpathObject.h" />
|
||||
<ClInclude Include="object\FootpathRailingsObject.h" />
|
||||
<ClInclude Include="object\FootpathSurfaceObject.h" />
|
||||
<ClInclude Include="object\ImageTable.h" />
|
||||
<ClInclude Include="object\LargeSceneryObject.h" />
|
||||
<ClInclude Include="object\MusicObject.h" />
|
||||
@@ -674,6 +675,7 @@
|
||||
<ClCompile Include="object\FootpathItemObject.cpp" />
|
||||
<ClCompile Include="object\FootpathObject.cpp" />
|
||||
<ClCompile Include="object\FootpathRailingsObject.cpp" />
|
||||
<ClCompile Include="object\FootpathSurfaceObject.cpp" />
|
||||
<ClCompile Include="object\ImageTable.cpp" />
|
||||
<ClCompile Include="object\LargeSceneryObject.cpp" />
|
||||
<ClCompile Include="object\MusicObject.cpp" />
|
||||
|
||||
@@ -19,11 +19,6 @@ private:
|
||||
rct_scenery_entry _legacyType = {};
|
||||
|
||||
public:
|
||||
explicit BannerObject(const rct_object_entry& entry)
|
||||
: SceneryObject(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -18,11 +18,6 @@ private:
|
||||
rct_entrance_type _legacyType = {};
|
||||
|
||||
public:
|
||||
explicit EntranceObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -18,11 +18,6 @@ private:
|
||||
rct_scenery_entry _legacyType = {};
|
||||
|
||||
public:
|
||||
explicit FootpathItemObject(const rct_object_entry& entry)
|
||||
: SceneryObject(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -21,11 +21,6 @@ private:
|
||||
PathRailingsEntry _pathRailingsEntry = {};
|
||||
|
||||
public:
|
||||
explicit FootpathObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -25,11 +25,6 @@ public:
|
||||
colour_t Colour{};
|
||||
|
||||
public:
|
||||
explicit FootpathRailingsObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
63
src/openrct2/object/FootpathSurfaceObject.cpp
Normal file
63
src/openrct2/object/FootpathSurfaceObject.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2021 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 "FootpathSurfaceObject.h"
|
||||
|
||||
#include "../core/IStream.hpp"
|
||||
#include "../core/Json.hpp"
|
||||
|
||||
void FootpathSurfaceObject::Load()
|
||||
{
|
||||
GetStringTable().Sort();
|
||||
NameStringId = language_allocate_object_string(GetName());
|
||||
|
||||
auto numImages = GetImageTable().GetCount();
|
||||
if (numImages != 0)
|
||||
{
|
||||
BaseImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount());
|
||||
PreviewImageId = BaseImageId + 72;
|
||||
}
|
||||
}
|
||||
|
||||
void FootpathSurfaceObject::Unload()
|
||||
{
|
||||
language_free_object_string(NameStringId);
|
||||
gfx_object_free_images(BaseImageId, GetImageTable().GetCount());
|
||||
|
||||
NameStringId = 0;
|
||||
PreviewImageId = 0;
|
||||
BaseImageId = 0;
|
||||
}
|
||||
|
||||
void FootpathSurfaceObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const
|
||||
{
|
||||
auto screenCoords = ScreenCoordsXY{ width / 2 - 16, height / 2 };
|
||||
gfx_draw_sprite(dpi, BaseImageId + 3, screenCoords, 0);
|
||||
gfx_draw_sprite(dpi, BaseImageId + 16, { screenCoords.x + 32, screenCoords.y - 16 }, 0);
|
||||
gfx_draw_sprite(dpi, BaseImageId + 8, { screenCoords.x + 32, screenCoords.y + 16 }, 0);
|
||||
}
|
||||
|
||||
void FootpathSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root)
|
||||
{
|
||||
Guard::Assert(root.is_object(), "FootpathSurfaceObject::ReadJson expects parameter root to be object");
|
||||
|
||||
auto properties = root["properties"];
|
||||
if (properties.is_object())
|
||||
{
|
||||
Flags = Json::GetFlags<uint8_t>(
|
||||
properties,
|
||||
{
|
||||
{ "editorOnly", FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR },
|
||||
{ "isQueue", FOOTPATH_ENTRY_FLAG_IS_QUEUE },
|
||||
{ "noSlopeRailings", FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS },
|
||||
});
|
||||
}
|
||||
|
||||
PopulateTablesFromJson(context, root);
|
||||
}
|
||||
29
src/openrct2/object/FootpathSurfaceObject.h
Normal file
29
src/openrct2/object/FootpathSurfaceObject.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2021 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.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../world/Footpath.h"
|
||||
#include "Object.h"
|
||||
|
||||
class FootpathSurfaceObject final : public Object
|
||||
{
|
||||
public:
|
||||
rct_string_id NameStringId{};
|
||||
uint32_t PreviewImageId{};
|
||||
uint32_t BaseImageId{};
|
||||
uint8_t Flags{};
|
||||
|
||||
public:
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override;
|
||||
};
|
||||
@@ -24,11 +24,6 @@ private:
|
||||
std::unique_ptr<rct_large_scenery_text> _3dFont;
|
||||
|
||||
public:
|
||||
explicit LargeSceneryObject(const rct_object_entry& entry)
|
||||
: SceneryObject(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -41,11 +41,6 @@ private:
|
||||
public:
|
||||
rct_string_id NameStringId{};
|
||||
|
||||
explicit MusicObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
@@ -103,12 +103,6 @@ bool ObjectEntryDescriptor::operator!=(const ObjectEntryDescriptor& rhs) const
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
Object::Object(const rct_object_entry& entry)
|
||||
{
|
||||
_type = entry.GetType();
|
||||
_objectEntry = entry;
|
||||
}
|
||||
|
||||
void* Object::GetLegacyData()
|
||||
{
|
||||
throw std::runtime_error("Not supported.");
|
||||
|
||||
@@ -42,6 +42,7 @@ enum class ObjectType : uint8_t
|
||||
TerrainEdge,
|
||||
Station,
|
||||
Music,
|
||||
FootpathSurface,
|
||||
FootpathRailings,
|
||||
|
||||
Count,
|
||||
@@ -167,7 +168,7 @@ struct ObjectEntryDescriptor
|
||||
ObjectGeneration Generation = ObjectGeneration::JSON;
|
||||
|
||||
// DAT
|
||||
rct_object_entry Entry;
|
||||
rct_object_entry Entry{};
|
||||
|
||||
// JSON
|
||||
ObjectType Type{};
|
||||
@@ -251,9 +252,8 @@ struct IReadObjectContext
|
||||
class Object
|
||||
{
|
||||
private:
|
||||
ObjectType _type = ObjectType::None;
|
||||
std::string _identifier;
|
||||
rct_object_entry _objectEntry{};
|
||||
ObjectEntryDescriptor _descriptor{};
|
||||
StringTable _stringTable;
|
||||
ImageTable _imageTable;
|
||||
std::vector<ObjectSourceGame> _sourceGames;
|
||||
@@ -289,7 +289,6 @@ protected:
|
||||
std::string GetString(int32_t language, ObjectStringID index) const;
|
||||
|
||||
public:
|
||||
explicit Object(const rct_object_entry& entry);
|
||||
virtual ~Object() = default;
|
||||
|
||||
std::string_view GetIdentifier() const
|
||||
@@ -313,29 +312,28 @@ public:
|
||||
|
||||
ObjectType GetObjectType() const
|
||||
{
|
||||
return _type;
|
||||
return _descriptor.GetType();
|
||||
}
|
||||
|
||||
ObjectEntryDescriptor GetDescriptor() const
|
||||
{
|
||||
if (_generation == ObjectGeneration::DAT)
|
||||
{
|
||||
return ObjectEntryDescriptor(_objectEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ObjectEntryDescriptor(_type, _identifier);
|
||||
}
|
||||
return _descriptor;
|
||||
}
|
||||
void SetDescriptor(const ObjectEntryDescriptor& value)
|
||||
{
|
||||
_descriptor = value;
|
||||
}
|
||||
|
||||
// Legacy data structures
|
||||
std::string_view GetLegacyIdentifier() const
|
||||
{
|
||||
return _objectEntry.GetName();
|
||||
return _descriptor.GetName();
|
||||
}
|
||||
|
||||
// TODO remove this, we should no longer assume objects have a legacy object entry
|
||||
const rct_object_entry& GetObjectEntry() const
|
||||
{
|
||||
return _objectEntry;
|
||||
return _descriptor.Entry;
|
||||
}
|
||||
virtual void* GetLegacyData();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "FootpathItemObject.h"
|
||||
#include "FootpathObject.h"
|
||||
#include "FootpathRailingsObject.h"
|
||||
#include "FootpathSurfaceObject.h"
|
||||
#include "LargeSceneryObject.h"
|
||||
#include "MusicObject.h"
|
||||
#include "Object.h"
|
||||
@@ -239,7 +240,7 @@ namespace ObjectFactory
|
||||
|
||||
if (entry.GetType() != ObjectType::ScenarioText)
|
||||
{
|
||||
result = CreateObject(entry);
|
||||
result = CreateObject(entry.GetType());
|
||||
|
||||
utf8 objectName[DAT_NAME_LENGTH + 1] = { 0 };
|
||||
object_entry_get_name_fixed(objectName, sizeof(objectName), &entry);
|
||||
@@ -271,9 +272,11 @@ namespace ObjectFactory
|
||||
Guard::ArgumentNotNull(entry, GUARD_LINE);
|
||||
Guard::ArgumentNotNull(data, GUARD_LINE);
|
||||
|
||||
auto result = CreateObject(*entry);
|
||||
auto result = CreateObject(entry->GetType());
|
||||
if (result != nullptr)
|
||||
{
|
||||
result->SetDescriptor(ObjectEntryDescriptor(*entry));
|
||||
|
||||
utf8 objectName[DAT_NAME_LENGTH + 1];
|
||||
object_entry_get_name_fixed(objectName, sizeof(objectName), entry);
|
||||
|
||||
@@ -293,57 +296,60 @@ namespace ObjectFactory
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Object> CreateObject(const rct_object_entry& entry)
|
||||
std::unique_ptr<Object> CreateObject(ObjectType type)
|
||||
{
|
||||
std::unique_ptr<Object> result;
|
||||
switch (entry.GetType())
|
||||
switch (type)
|
||||
{
|
||||
case ObjectType::Ride:
|
||||
result = std::make_unique<RideObject>(entry);
|
||||
result = std::make_unique<RideObject>();
|
||||
break;
|
||||
case ObjectType::SmallScenery:
|
||||
result = std::make_unique<SmallSceneryObject>(entry);
|
||||
result = std::make_unique<SmallSceneryObject>();
|
||||
break;
|
||||
case ObjectType::LargeScenery:
|
||||
result = std::make_unique<LargeSceneryObject>(entry);
|
||||
result = std::make_unique<LargeSceneryObject>();
|
||||
break;
|
||||
case ObjectType::Walls:
|
||||
result = std::make_unique<WallObject>(entry);
|
||||
result = std::make_unique<WallObject>();
|
||||
break;
|
||||
case ObjectType::Banners:
|
||||
result = std::make_unique<BannerObject>(entry);
|
||||
result = std::make_unique<BannerObject>();
|
||||
break;
|
||||
case ObjectType::Paths:
|
||||
result = std::make_unique<FootpathObject>(entry);
|
||||
result = std::make_unique<FootpathObject>();
|
||||
break;
|
||||
case ObjectType::PathBits:
|
||||
result = std::make_unique<FootpathItemObject>(entry);
|
||||
result = std::make_unique<FootpathItemObject>();
|
||||
break;
|
||||
case ObjectType::SceneryGroup:
|
||||
result = std::make_unique<SceneryGroupObject>(entry);
|
||||
result = std::make_unique<SceneryGroupObject>();
|
||||
break;
|
||||
case ObjectType::ParkEntrance:
|
||||
result = std::make_unique<EntranceObject>(entry);
|
||||
result = std::make_unique<EntranceObject>();
|
||||
break;
|
||||
case ObjectType::Water:
|
||||
result = std::make_unique<WaterObject>(entry);
|
||||
result = std::make_unique<WaterObject>();
|
||||
break;
|
||||
case ObjectType::ScenarioText:
|
||||
break;
|
||||
case ObjectType::TerrainSurface:
|
||||
result = std::make_unique<TerrainSurfaceObject>(entry);
|
||||
result = std::make_unique<TerrainSurfaceObject>();
|
||||
break;
|
||||
case ObjectType::TerrainEdge:
|
||||
result = std::make_unique<TerrainEdgeObject>(entry);
|
||||
result = std::make_unique<TerrainEdgeObject>();
|
||||
break;
|
||||
case ObjectType::Station:
|
||||
result = std::make_unique<StationObject>(entry);
|
||||
result = std::make_unique<StationObject>();
|
||||
break;
|
||||
case ObjectType::Music:
|
||||
result = std::make_unique<MusicObject>(entry);
|
||||
result = std::make_unique<MusicObject>();
|
||||
break;
|
||||
case ObjectType::FootpathSurface:
|
||||
result = std::make_unique<FootpathSurfaceObject>();
|
||||
break;
|
||||
case ObjectType::FootpathRailings:
|
||||
result = std::make_unique<FootpathRailingsObject>(entry);
|
||||
result = std::make_unique<FootpathRailingsObject>();
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Invalid object type");
|
||||
@@ -381,6 +387,8 @@ namespace ObjectFactory
|
||||
return ObjectType::Station;
|
||||
if (s == "music")
|
||||
return ObjectType::Music;
|
||||
if (s == "footpath_surface")
|
||||
return ObjectType::FootpathSurface;
|
||||
if (s == "footpath_railings")
|
||||
return ObjectType::FootpathRailings;
|
||||
return ObjectType::None;
|
||||
@@ -476,22 +484,28 @@ namespace ObjectFactory
|
||||
{
|
||||
auto id = Json::GetString(jRoot["id"]);
|
||||
|
||||
rct_object_entry entry = {};
|
||||
ObjectEntryDescriptor descriptor;
|
||||
auto originalId = Json::GetString(jRoot["originalId"]);
|
||||
auto originalName = originalId;
|
||||
if (originalId.length() == 8 + 1 + 8 + 1 + 8)
|
||||
{
|
||||
entry.flags = std::stoul(originalId.substr(0, 8), nullptr, 16);
|
||||
originalName = originalId.substr(9, 8);
|
||||
entry.checksum = std::stoul(originalId.substr(18, 8), nullptr, 16);
|
||||
}
|
||||
// Always set, since originalId might be missing or incorrect.
|
||||
entry.SetType(objectType);
|
||||
auto minLength = std::min<size_t>(8, originalName.length());
|
||||
std::memcpy(entry.name, originalName.c_str(), minLength);
|
||||
auto originalName = originalId.substr(9, 8);
|
||||
|
||||
result = CreateObject(entry);
|
||||
rct_object_entry entry = {};
|
||||
entry.flags = std::stoul(originalId.substr(0, 8), nullptr, 16);
|
||||
entry.checksum = std::stoul(originalId.substr(18, 8), nullptr, 16);
|
||||
entry.SetType(objectType);
|
||||
auto minLength = std::min<size_t>(8, originalName.length());
|
||||
std::memcpy(entry.name, originalName.c_str(), minLength);
|
||||
descriptor = ObjectEntryDescriptor(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptor = ObjectEntryDescriptor(objectType, id);
|
||||
}
|
||||
|
||||
result = CreateObject(objectType);
|
||||
result->SetIdentifier(id);
|
||||
result->SetDescriptor(descriptor);
|
||||
result->MarkAsJsonObject();
|
||||
auto readContext = ReadObjectContext(objectRepository, id, !gOpenRCT2NoGraphics, fileRetriever);
|
||||
result->ReadJson(&readContext, jRoot);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
struct IObjectRepository;
|
||||
class Object;
|
||||
struct rct_object_entry;
|
||||
enum class ObjectType : uint8_t;
|
||||
|
||||
namespace ObjectFactory
|
||||
{
|
||||
@@ -24,7 +25,7 @@ namespace ObjectFactory
|
||||
std::unique_ptr<Object> CreateObjectFromLegacyData(
|
||||
IObjectRepository& objectRepository, const rct_object_entry* entry, const void* data, size_t dataSize);
|
||||
std::unique_ptr<Object> CreateObjectFromZipFile(IObjectRepository& objectRepository, std::string_view path);
|
||||
std::unique_ptr<Object> CreateObject(const rct_object_entry& entry);
|
||||
std::unique_ptr<Object> CreateObject(ObjectType type);
|
||||
|
||||
std::unique_ptr<Object> CreateObjectFromJsonFile(IObjectRepository& objectRepository, const std::string& path);
|
||||
} // namespace ObjectFactory
|
||||
|
||||
@@ -26,6 +26,7 @@ constexpr const uint16_t MAX_TERRAIN_SURFACE_OBJECTS = 100;
|
||||
constexpr const uint16_t MAX_TERRAIN_EDGE_OBJECTS = 100;
|
||||
constexpr const uint16_t MAX_STATION_OBJECTS = 100;
|
||||
constexpr const uint16_t MAX_MUSIC_OBJECTS = 255;
|
||||
constexpr const uint16_t MAX_FOOTPATH_SURFACE_OBJECTS = 32;
|
||||
constexpr const uint16_t MAX_FOOTPATH_RAILINGS_OBJECTS = 32;
|
||||
|
||||
// clang-format off
|
||||
@@ -45,6 +46,7 @@ constexpr const uint16_t OBJECT_ENTRY_COUNT =
|
||||
MAX_TERRAIN_EDGE_OBJECTS +
|
||||
MAX_STATION_OBJECTS +
|
||||
MAX_MUSIC_OBJECTS +
|
||||
MAX_FOOTPATH_SURFACE_OBJECTS +
|
||||
MAX_FOOTPATH_RAILINGS_OBJECTS;
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ int32_t object_entry_group_counts[] = {
|
||||
MAX_TERRAIN_EDGE_OBJECTS,
|
||||
MAX_STATION_OBJECTS,
|
||||
MAX_MUSIC_OBJECTS,
|
||||
MAX_FOOTPATH_SURFACE_OBJECTS,
|
||||
MAX_FOOTPATH_RAILINGS_OBJECTS,
|
||||
};
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ private:
|
||||
loadedObject = ori->LoadedObject;
|
||||
if (loadedObject == nullptr)
|
||||
{
|
||||
ObjectType objectType = ori->ObjectEntry.GetType();
|
||||
ObjectType objectType = ori->Type;
|
||||
if (slot)
|
||||
{
|
||||
if (_loadedObjects.size() > static_cast<size_t>(*slot) && _loadedObjects[*slot] != nullptr)
|
||||
|
||||
@@ -130,6 +130,8 @@ public:
|
||||
protected:
|
||||
void Serialise(DataSerialiser& ds, ObjectRepositoryItem& item) const override
|
||||
{
|
||||
ds << item.Type;
|
||||
ds << item.Generation;
|
||||
ds << item.Identifier;
|
||||
ds << item.ObjectEntry;
|
||||
ds << item.Path;
|
||||
@@ -138,7 +140,7 @@ protected:
|
||||
ds << item.Sources;
|
||||
ds << item.Authors;
|
||||
|
||||
switch (item.ObjectEntry.GetType())
|
||||
switch (item.Type)
|
||||
{
|
||||
case ObjectType::Ride:
|
||||
ds << item.RideInfo.RideFlags;
|
||||
@@ -435,7 +437,10 @@ private:
|
||||
{
|
||||
_newItemMap[item.Identifier] = index;
|
||||
}
|
||||
_itemMap[item.ObjectEntry] = index;
|
||||
if (!item.ObjectEntry.IsEmpty())
|
||||
{
|
||||
_itemMap[item.ObjectEntry] = index;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -649,8 +654,7 @@ bool IsObjectCustom(const ObjectRepositoryItem* object)
|
||||
|
||||
// Do not count our new object types as custom yet, otherwise the game
|
||||
// will try to pack them into saved games.
|
||||
auto type = object->ObjectEntry.GetType();
|
||||
if (type > ObjectType::ScenarioText)
|
||||
if (object->Type > ObjectType::ScenarioText)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,11 +24,6 @@ private:
|
||||
std::vector<std::array<CoordsXY, 3>> _peepLoadingWaypoints[MAX_VEHICLES_PER_RIDE_ENTRY];
|
||||
|
||||
public:
|
||||
explicit RideObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -66,6 +66,25 @@ void SceneryGroupObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int3
|
||||
gfx_draw_sprite(dpi, imageId, screenCoords - ScreenCoordsXY{ 15, 14 }, 0);
|
||||
}
|
||||
|
||||
static std::optional<uint8_t> GetSceneryType(ObjectType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ObjectType::SmallScenery:
|
||||
return SCENERY_TYPE_SMALL;
|
||||
case ObjectType::LargeScenery:
|
||||
return SCENERY_TYPE_LARGE;
|
||||
case ObjectType::Walls:
|
||||
return SCENERY_TYPE_WALL;
|
||||
case ObjectType::Banners:
|
||||
return SCENERY_TYPE_BANNER;
|
||||
case ObjectType::PathBits:
|
||||
return SCENERY_TYPE_PATH_ITEM;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneryGroupObject::UpdateEntryIndexes()
|
||||
{
|
||||
auto context = GetContext();
|
||||
@@ -84,7 +103,7 @@ void SceneryGroupObject::UpdateEntryIndexes()
|
||||
auto entryIndex = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject);
|
||||
Guard::Assert(entryIndex != OBJECT_ENTRY_INDEX_NULL, GUARD_LINE);
|
||||
|
||||
auto sceneryType = ori->ObjectEntry.GetSceneryType();
|
||||
auto sceneryType = GetSceneryType(ori->Type);
|
||||
if (sceneryType != std::nullopt)
|
||||
{
|
||||
_legacyType.scenery_entries[_legacyType.entry_count] = { *sceneryType, entryIndex };
|
||||
|
||||
@@ -25,11 +25,6 @@ private:
|
||||
std::vector<ObjectEntryDescriptor> _items;
|
||||
|
||||
public:
|
||||
explicit SceneryGroupObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -19,10 +19,6 @@ private:
|
||||
ObjectEntryDescriptor _primarySceneryGroupEntry = {};
|
||||
|
||||
public:
|
||||
explicit SceneryObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
virtual ~SceneryObject() = default;
|
||||
|
||||
const ObjectEntryDescriptor& GetPrimarySceneryGroup() const
|
||||
|
||||
@@ -21,11 +21,6 @@ private:
|
||||
std::vector<uint8_t> _frameOffsets;
|
||||
|
||||
public:
|
||||
explicit SmallSceneryObject(const rct_object_entry& entry)
|
||||
: SceneryObject(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -28,11 +28,6 @@ public:
|
||||
int32_t Height{};
|
||||
uint8_t ScrollingMode{};
|
||||
|
||||
explicit StationObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
@@ -21,11 +21,6 @@ public:
|
||||
uint32_t NumImagesLoaded{};
|
||||
bool HasDoors{};
|
||||
|
||||
explicit TerrainEdgeObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
@@ -56,11 +56,6 @@ public:
|
||||
|
||||
uint32_t NumImagesLoaded{};
|
||||
|
||||
explicit TerrainSurfaceObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void ReadJson(IReadObjectContext* context, json_t& root) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
@@ -18,11 +18,6 @@ private:
|
||||
rct_scenery_entry _legacyType = {};
|
||||
|
||||
public:
|
||||
explicit WallObject(const rct_object_entry& entry)
|
||||
: SceneryObject(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -20,11 +20,6 @@ private:
|
||||
rct_water_type _legacyType = {};
|
||||
|
||||
public:
|
||||
explicit WaterObject(const rct_object_entry& entry)
|
||||
: Object(entry)
|
||||
{
|
||||
}
|
||||
|
||||
void* GetLegacyData() override
|
||||
{
|
||||
return &_legacyType;
|
||||
|
||||
@@ -536,7 +536,7 @@ private:
|
||||
auto foundObject = objectRepository.FindObject(objectName);
|
||||
if (foundObject != nullptr)
|
||||
{
|
||||
ObjectType objectType = foundObject->ObjectEntry.GetType();
|
||||
auto objectType = foundObject->Type;
|
||||
switch (objectType)
|
||||
{
|
||||
case ObjectType::SmallScenery:
|
||||
|
||||
Reference in New Issue
Block a user