Ensure one footpath surface and railing is selected

This commit is contained in:
Ted John 2021-04-24 16:23:34 +01:00
parent 43985a52c3
commit dff8d443f6
11 changed files with 64 additions and 14 deletions

View File

@ -3679,6 +3679,9 @@ STR_6436 :Toggle invisibility
STR_6437 :Invisible
STR_6438 :I
STR_6439 :Tile Inspector: Toggle invisibility
STR_6440 :At least one footpath non-queue surface object must be selected.
STR_6441 :At least one footpath queue surface object must be selected.
STR_6442 :At least one footpath railing object must be selected.
#############
# Scenarios #

View File

@ -98,15 +98,18 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[] = {
{ STR_OBJECT_SELECTION_LARGE_SCENERY, SPR_TAB_SCENERY_URBAN, true },
{ STR_OBJECT_SELECTION_WALLS_FENCES, SPR_TAB_SCENERY_WALLS, true },
{ STR_OBJECT_SELECTION_PATH_SIGNS, SPR_TAB_SCENERY_SIGNAGE, true },
{ STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false },
{ STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, true },
{ STR_OBJECT_SELECTION_PATH_EXTRAS, SPR_TAB_SCENERY_PATH_ITEMS, false },
{ STR_OBJECT_SELECTION_SCENERY_GROUPS, SPR_TAB_SCENERY_STATUES, false },
{ STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false },
{ STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false },
{ STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, true },
{ STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, true },
{ STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, true },
// Dummy place holder for string objects
{ STR_NONE, static_cast<uint32_t>(SPR_NONE), false },
{ STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, true },
{ STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, true },
{ STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, true },
{ 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 },
@ -833,7 +836,7 @@ static void window_editor_object_selection_invalidate(rct_window* w)
for (size_t i = 0; i < std::size(ObjectSelectionPages); i++)
{
auto widget = &w->widgets[WIDX_TAB_1 + i];
if (!advancedMode && ObjectSelectionPages[i].IsAdvanced)
if (!advancedMode && ObjectSelectionPages[i].IsAdvanced || ObjectSelectionPages[i].Image == SPR_NONE)
{
widget->type = WindowWidgetType::Empty;
}
@ -1536,8 +1539,5 @@ static std::string object_get_description(const Object* object)
static ObjectType get_selected_object_type(rct_window* w)
{
auto tab = w->selected_tab;
if (tab >= EnumValue(ObjectType::ScenarioText))
return static_cast<ObjectType>(tab + 1);
else
return static_cast<ObjectType>(tab);
return static_cast<ObjectType>(tab);
}

View File

@ -715,7 +715,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget
_dropdownEntries.clear();
std::optional<size_t> defaultIndex;
for (size_t i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
{
const auto* pathType = static_cast<FootpathSurfaceObject*>(objManager.GetLoadedObject(ObjectType::FootpathSurface, i));
if (pathType == nullptr)
@ -742,7 +742,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget
numPathTypes++;
}
for (size_t i = 0; i < MAX_PATH_OBJECTS; i++)
for (ObjectEntryIndex i = 0; i < MAX_PATH_OBJECTS; i++)
{
auto* pathObj = static_cast<FootpathObject*>(objManager.GetLoadedObject(ObjectType::Paths, i));
if (pathObj == nullptr)

View File

@ -489,10 +489,20 @@ namespace Editor
if (!isTrackDesignerManager)
{
if (!editor_check_object_group_at_least_one_selected(ObjectType::Paths))
if (!editor_check_object_group_at_least_one_surface_selected(false))
{
gGameCommandErrorText = STR_AT_LEAST_ONE_PATH_OBJECT_MUST_BE_SELECTED;
return ObjectType::Paths;
gGameCommandErrorText = STR_AT_LEAST_ONE_FOOTPATH_NON_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED;
return ObjectType::FootpathSurface;
}
if (!editor_check_object_group_at_least_one_surface_selected(true))
{
gGameCommandErrorText = STR_AT_LEAST_ONE_FOOTPATH_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED;
return ObjectType::FootpathSurface;
}
if (!editor_check_object_group_at_least_one_selected(ObjectType::FootpathRailings))
{
gGameCommandErrorText = STR_AT_LEAST_ONE_FOOTPATH_RAILING_OBJECT_MUST_BE_SELECTED;
return ObjectType::FootpathRailings;
}
}

View File

@ -644,6 +644,23 @@ bool editor_check_object_group_at_least_one_selected(ObjectType checkObjectType)
return false;
}
bool editor_check_object_group_at_least_one_surface_selected(bool queue)
{
auto numObjects = std::min(object_repository_get_items_count(), _objectSelectionFlags.size());
const auto* items = object_repository_get_items();
for (size_t i = 0; i < numObjects; i++)
{
const auto& ori = items[i];
auto isQueue = (ori.FootpathSurfaceInfo.Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0;
if (ori.Type == ObjectType::FootpathSurface && (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)
&& queue == isQueue)
{
return true;
}
}
return false;
}
int32_t editor_remove_unused_objects()
{
sub_6AB211();

View File

@ -28,6 +28,7 @@ extern std::vector<uint8_t> _objectSelectionFlags;
extern int32_t _numSelectedObjectsForType[EnumValue(ObjectType::Count)];
bool editor_check_object_group_at_least_one_selected(ObjectType checkObjectType);
bool editor_check_object_group_at_least_one_surface_selected(bool queue);
void editor_object_flags_free();
void unload_unselected_objects();
void sub_6AB211();

View File

@ -3938,6 +3938,10 @@ enum
STR_TILE_INSPECTOR_INVISIBLE_SHORT = 6438,
STR_SHORTCUT_TOGGLE_INVISIBILITY = 6439,
STR_AT_LEAST_ONE_FOOTPATH_NON_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6440,
STR_AT_LEAST_ONE_FOOTPATH_QUEUE_SURFACE_OBJECT_MUST_BE_SELECTED = 6441,
STR_AT_LEAST_ONE_FOOTPATH_RAILING_OBJECT_MUST_BE_SELECTED = 6442,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
};

View File

@ -11,6 +11,7 @@
#include "../core/IStream.hpp"
#include "../core/Json.hpp"
#include "../object/ObjectRepository.h"
void FootpathSurfaceObject::Load()
{
@ -61,3 +62,8 @@ void FootpathSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root)
PopulateTablesFromJson(context, root);
}
void FootpathSurfaceObject::SetRepositoryItem(ObjectRepositoryItem* item) const
{
item->FootpathSurfaceInfo.Flags = Flags;
}

View File

@ -26,4 +26,6 @@ public:
void Unload() override;
void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override;
void SetRepositoryItem(ObjectRepositoryItem* item) const override;
};

View File

@ -152,6 +152,9 @@ protected:
ds << item.SceneryGroupInfo.Entries;
break;
}
case ObjectType::FootpathSurface:
ds << item.FootpathSurfaceInfo.Flags;
break;
default:
// Switch processes only ObjectType::Ride and ObjectType::SceneryGroup
break;

View File

@ -56,6 +56,10 @@ struct ObjectRepositoryItem
{
std::vector<ObjectEntryDescriptor> Entries;
} SceneryGroupInfo;
struct
{
uint8_t Flags{};
} FootpathSurfaceInfo;
ObjectSourceGame GetFirstSourceGame() const
{