mirror of https://github.com/OpenRCT2/OpenRCT2.git
* Feature #11817: Show authors field in object selection - authors field in JSON shows as last line in bottom right on object selection - authors field added to Object class - ObjectFileIndex version bump as authors is serialised * fix sign comparison warning * Start object selection corner text higher to avoid overlap * Use references to reduce unneccessary copies * make GetAuthors const * Clip drawing of authors string so it doesn't cross widgets At max length the leftmost aligns exactly with description left * Add a changelog message * make SetAuthors use an rvalue reference * remove unnecessary nullptr check
This commit is contained in:
parent
5f68927e88
commit
c4ae579a84
|
@ -14,6 +14,7 @@
|
|||
- Feature: [#11959] Hacked go-kart tracks can now use 2x2 bends, 3x3 bends and S-bends.
|
||||
- Feature: [#12090] Boosters for the Wooden Roller Coaster (if the "Show all track pieces" cheat is enabled).
|
||||
- Feature: [#12184] .sea (RCT Classic) scenario files can now be imported.
|
||||
- Feature: [#12591] Show authors of an object on the object selection dialog.
|
||||
- Change: [#11209] Warn when user is running OpenRCT2 through Wine.
|
||||
- Change: [#11358] Switch copy and paste button positions in tile inspector.
|
||||
- Change: [#11449] Remove complete circuit requirement from Air Powered Vertical Coaster (for RCT1 parity).
|
||||
|
|
|
@ -1083,7 +1083,7 @@ static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinf
|
|||
dpi, gCommonFormatArgs, screenPos + ScreenCoordsXY{ 0, 5 }, width, STR_WINDOW_COLOUR_2_STRINGID, COLOUR_BLACK);
|
||||
}
|
||||
|
||||
auto screenPos = w->windowPos + ScreenCoordsXY{ w->width - 5, w->height - (LIST_ROW_HEIGHT * 4) };
|
||||
auto screenPos = w->windowPos + ScreenCoordsXY{ w->width - 5, w->height - (LIST_ROW_HEIGHT * 5) };
|
||||
|
||||
// Draw ride type.
|
||||
if (get_selected_object_type(w) == OBJECT_TYPE_RIDE)
|
||||
|
@ -1100,14 +1100,35 @@ static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinf
|
|||
screenPos.y += LIST_ROW_HEIGHT;
|
||||
|
||||
// Draw object dat name
|
||||
const char* path = path_get_filename(listItem->repositoryItem->Path.c_str());
|
||||
auto ft = Formatter::Common();
|
||||
ft.Add<rct_string_id>(STR_STRING);
|
||||
ft.Add<const char*>(path);
|
||||
gfx_draw_string_right(
|
||||
dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, { w->windowPos.x + w->width - 5, screenPos.y });
|
||||
}
|
||||
{
|
||||
const char* path = path_get_filename(listItem->repositoryItem->Path.c_str());
|
||||
auto ft = Formatter::Common();
|
||||
ft.Add<rct_string_id>(STR_STRING);
|
||||
ft.Add<const char*>(path);
|
||||
gfx_draw_string_right(
|
||||
dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, { w->windowPos.x + w->width - 5, screenPos.y });
|
||||
screenPos.y += LIST_ROW_HEIGHT;
|
||||
}
|
||||
|
||||
// Draw object author (will be blank space if no author in file or a non JSON object)
|
||||
{
|
||||
auto ft = Formatter::Common();
|
||||
std::string authorsString;
|
||||
for (size_t i = 0; i < listItem->repositoryItem->Authors.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
authorsString.append(", ");
|
||||
}
|
||||
authorsString.append(listItem->repositoryItem->Authors[i]);
|
||||
}
|
||||
ft.Add<rct_string_id>(STR_STRING);
|
||||
ft.Add<const char*>(authorsString.c_str());
|
||||
gfx_draw_string_right_clipped(
|
||||
dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, { w->windowPos.x + w->width - 5, screenPos.y },
|
||||
w->width - w->widgets[WIDX_LIST].right - 4);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AADA3
|
||||
|
|
|
@ -116,6 +116,16 @@ void rct_object_entry::SetName(const std::string_view& value)
|
|||
std::memcpy(name, value.data(), std::min(sizeof(name), value.size()));
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Object::GetAuthors() const
|
||||
{
|
||||
return _authors;
|
||||
}
|
||||
|
||||
void Object::SetAuthors(const std::vector<std::string>&& authors)
|
||||
{
|
||||
_authors = authors;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> rct_object_entry::GetSceneryType() const
|
||||
{
|
||||
switch (GetType())
|
||||
|
|
|
@ -169,6 +169,7 @@ private:
|
|||
StringTable _stringTable;
|
||||
ImageTable _imageTable;
|
||||
std::vector<uint8_t> _sourceGames;
|
||||
std::vector<std::string> _authors;
|
||||
bool _isJsonObject{};
|
||||
|
||||
protected:
|
||||
|
@ -247,6 +248,9 @@ public:
|
|||
std::vector<uint8_t> GetSourceGames();
|
||||
void SetSourceGames(const std::vector<uint8_t>& sourceGames);
|
||||
|
||||
const std::vector<std::string>& GetAuthors() const;
|
||||
void SetAuthors(const std::vector<std::string>&& authors);
|
||||
|
||||
const ImageTable& GetImageTable() const
|
||||
{
|
||||
return _imageTable;
|
||||
|
|
|
@ -442,6 +442,26 @@ namespace ObjectFactory
|
|||
{
|
||||
throw std::runtime_error("Object has errors");
|
||||
}
|
||||
|
||||
auto authors = json_object_get(jRoot, "authors");
|
||||
if (json_is_array(authors))
|
||||
{
|
||||
std::vector<std::string> authorVector;
|
||||
for (size_t j = 0; j < json_array_size(authors); j++)
|
||||
{
|
||||
json_t* tryString = json_array_get(authors, j);
|
||||
if (json_is_string(tryString))
|
||||
{
|
||||
authorVector.emplace_back(json_string_value(tryString));
|
||||
}
|
||||
}
|
||||
result->SetAuthors(std::move(authorVector));
|
||||
}
|
||||
else if (json_is_string(authors))
|
||||
{
|
||||
result->SetAuthors({ json_string_value(authors) });
|
||||
}
|
||||
|
||||
auto sourceGames = json_object_get(jRoot, "sourceGame");
|
||||
if (json_is_array(sourceGames))
|
||||
{
|
||||
|
|
|
@ -74,7 +74,7 @@ class ObjectFileIndex final : public FileIndex<ObjectRepositoryItem>
|
|||
{
|
||||
private:
|
||||
static constexpr uint32_t MAGIC_NUMBER = 0x5844494F; // OIDX
|
||||
static constexpr uint16_t VERSION = 20;
|
||||
static constexpr uint16_t VERSION = 21;
|
||||
static constexpr auto PATTERN = "*.dat;*.pob;*.json;*.parkobj";
|
||||
|
||||
IObjectRepository& _objectRepository;
|
||||
|
@ -114,6 +114,7 @@ public:
|
|||
item.ObjectEntry = *object->GetObjectEntry();
|
||||
item.Path = path;
|
||||
item.Name = object->GetName();
|
||||
item.Authors = object->GetAuthors();
|
||||
item.Sources = object->GetSourceGames();
|
||||
object->SetRepositoryItem(&item);
|
||||
delete object;
|
||||
|
@ -128,6 +129,7 @@ protected:
|
|||
stream->WriteValue(item.ObjectEntry);
|
||||
stream->WriteString(item.Path);
|
||||
stream->WriteString(item.Name);
|
||||
|
||||
uint8_t sourceLength = static_cast<uint8_t>(item.Sources.size());
|
||||
stream->WriteValue(sourceLength);
|
||||
for (auto source : item.Sources)
|
||||
|
@ -135,6 +137,13 @@ protected:
|
|||
stream->WriteValue(source);
|
||||
}
|
||||
|
||||
uint8_t authorsLength = static_cast<uint8_t>(item.Authors.size());
|
||||
stream->WriteValue(authorsLength);
|
||||
for (const auto& author : item.Authors)
|
||||
{
|
||||
stream->WriteString(author);
|
||||
}
|
||||
|
||||
switch (item.ObjectEntry.GetType())
|
||||
{
|
||||
case OBJECT_TYPE_RIDE:
|
||||
|
@ -165,6 +174,7 @@ protected:
|
|||
item.ObjectEntry = stream->ReadValue<rct_object_entry>();
|
||||
item.Path = stream->ReadStdString();
|
||||
item.Name = stream->ReadStdString();
|
||||
|
||||
auto sourceLength = stream->ReadValue<uint8_t>();
|
||||
for (size_t i = 0; i < sourceLength; i++)
|
||||
{
|
||||
|
@ -172,6 +182,13 @@ protected:
|
|||
item.Sources.push_back(value);
|
||||
}
|
||||
|
||||
auto authorsLength = stream->ReadValue<uint8_t>();
|
||||
for (size_t i = 0; i < authorsLength; i++)
|
||||
{
|
||||
auto author = stream->ReadStdString();
|
||||
item.Authors.emplace_back(author);
|
||||
}
|
||||
|
||||
switch (item.ObjectEntry.GetType())
|
||||
{
|
||||
case OBJECT_TYPE_RIDE:
|
||||
|
|
|
@ -40,6 +40,7 @@ struct ObjectRepositoryItem
|
|||
rct_object_entry ObjectEntry;
|
||||
std::string Path;
|
||||
std::string Name;
|
||||
std::vector<std::string> Authors;
|
||||
std::vector<uint8_t> Sources;
|
||||
Object* LoadedObject{};
|
||||
struct
|
||||
|
|
Loading…
Reference in New Issue