mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #10922 from Gymnasiast/cleanup-scenery
Cleanup scenery
This commit is contained in:
commit
ae6e53153b
|
@ -31,6 +31,7 @@ constexpr int32_t WINDOW_SCENERY_HEIGHT = 180;
|
|||
constexpr int32_t SCENERY_BUTTON_WIDTH = 66;
|
||||
constexpr int32_t SCENERY_BUTTON_HEIGHT = 80;
|
||||
constexpr int32_t SCENERY_WINDOW_TABS = MAX_SCENERY_GROUP_OBJECTS + 1; // The + 1 is for the 'Miscellaneous' tab
|
||||
constexpr uint16_t SCENERY_ENTRIES_PER_TAB = 1024;
|
||||
|
||||
// clang-format off
|
||||
enum {
|
||||
|
@ -56,7 +57,7 @@ enum {
|
|||
WINDOW_SCENERY_TAB_20
|
||||
};
|
||||
|
||||
uint16_t gWindowSceneryTabSelections[SCENERY_WINDOW_TABS];
|
||||
ScenerySelection gWindowSceneryTabSelections[SCENERY_WINDOW_TABS];
|
||||
uint8_t gWindowSceneryActiveTabIndex;
|
||||
uint8_t gWindowSceneryPaintEnabled;
|
||||
uint8_t gWindowSceneryRotation;
|
||||
|
@ -191,25 +192,25 @@ static rct_widget window_scenery_widgets[] = {
|
|||
void window_scenery_update_scroll(rct_window* w);
|
||||
|
||||
// rct2: 0x00F64F2C
|
||||
static uint16_t window_scenery_tab_entries[SCENERY_WINDOW_TABS][SCENERY_ENTRIES_BY_TAB + 1];
|
||||
static ScenerySelection window_scenery_tab_entries[SCENERY_WINDOW_TABS][SCENERY_ENTRIES_PER_TAB + 1];
|
||||
|
||||
/**
|
||||
* Was part of 0x006DFA00
|
||||
* The same code repeated five times for every scenery entry type
|
||||
*/
|
||||
static void init_scenery_entry(rct_scenery_entry* sceneryEntry, int32_t index, uint8_t sceneryTabId)
|
||||
static void init_scenery_entry(rct_scenery_entry* sceneryEntry, const ScenerySelection& selection, uint8_t sceneryTabId)
|
||||
{
|
||||
Guard::ArgumentInRange<int32_t>(index, 0, WINDOW_SCENERY_TAB_SELECTION_UNDEFINED);
|
||||
if (scenery_is_invented(index) || gCheatsIgnoreResearchStatus)
|
||||
Guard::ArgumentInRange<int32_t>(selection.EntryIndex, 0, WINDOW_SCENERY_TAB_SELECTION_UNDEFINED);
|
||||
if (scenery_is_invented(selection) || gCheatsIgnoreResearchStatus)
|
||||
{
|
||||
if (sceneryTabId != 0xFF)
|
||||
{
|
||||
for (int32_t i = 0; i < SCENERY_ENTRIES_BY_TAB; i++)
|
||||
for (int32_t i = 0; i < SCENERY_ENTRIES_PER_TAB; i++)
|
||||
{
|
||||
if (window_scenery_tab_entries[sceneryTabId][i] == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (window_scenery_tab_entries[sceneryTabId][i].IsUndefined())
|
||||
{
|
||||
window_scenery_tab_entries[sceneryTabId][i] = index;
|
||||
window_scenery_tab_entries[sceneryTabId][i + 1] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
window_scenery_tab_entries[sceneryTabId][i] = selection;
|
||||
window_scenery_tab_entries[sceneryTabId][i + 1].SetUndefined();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -219,9 +220,9 @@ static void init_scenery_entry(rct_scenery_entry* sceneryEntry, int32_t index, u
|
|||
{
|
||||
int32_t counter = 0;
|
||||
|
||||
while (window_scenery_tab_entries[i][counter] != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
while (!window_scenery_tab_entries[i][counter].IsUndefined())
|
||||
{
|
||||
if (window_scenery_tab_entries[i][counter] == index)
|
||||
if (window_scenery_tab_entries[i][counter] == selection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -230,12 +231,12 @@ static void init_scenery_entry(rct_scenery_entry* sceneryEntry, int32_t index, u
|
|||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < SCENERY_ENTRIES_BY_TAB; i++)
|
||||
for (int32_t i = 0; i < SCENERY_ENTRIES_PER_TAB; i++)
|
||||
{
|
||||
if (window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i] == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i].IsUndefined())
|
||||
{
|
||||
window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i] = index;
|
||||
window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i + 1] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i] = selection;
|
||||
window_scenery_tab_entries[SCENERY_WINDOW_TABS - 1][i + 1].SetUndefined();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +253,7 @@ void window_scenery_init()
|
|||
|
||||
for (int32_t scenerySetIndex = 0; scenerySetIndex < SCENERY_WINDOW_TABS; scenerySetIndex++)
|
||||
{
|
||||
window_scenery_tab_entries[scenerySetIndex][0] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
window_scenery_tab_entries[scenerySetIndex][0].SetUndefined();
|
||||
if (scenerySetIndex == MAX_SCENERY_GROUP_OBJECTS)
|
||||
continue;
|
||||
|
||||
|
@ -263,11 +264,11 @@ void window_scenery_init()
|
|||
int32_t sceneryTabEntryCount = 0;
|
||||
for (int32_t i = 0; i < sceneryGroupEntry->entry_count; i++)
|
||||
{
|
||||
uint16_t sceneryEntryId = sceneryGroupEntry->scenery_entries[i];
|
||||
if (scenery_is_invented(sceneryEntryId) || gCheatsIgnoreResearchStatus)
|
||||
auto sceneryEntry = sceneryGroupEntry->scenery_entries[i];
|
||||
if (scenery_is_invented(sceneryEntry) || gCheatsIgnoreResearchStatus)
|
||||
{
|
||||
window_scenery_tab_entries[scenerySetIndex][sceneryTabEntryCount] = sceneryEntryId;
|
||||
window_scenery_tab_entries[scenerySetIndex][++sceneryTabEntryCount] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
window_scenery_tab_entries[scenerySetIndex][sceneryTabEntryCount] = sceneryEntry;
|
||||
window_scenery_tab_entries[scenerySetIndex][++sceneryTabEntryCount].SetUndefined();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -277,61 +278,53 @@ void window_scenery_init()
|
|||
}
|
||||
|
||||
// small scenery
|
||||
for (uint16_t sceneryId = SCENERY_SMALL_SCENERY_ID_MIN; sceneryId <= SCENERY_SMALL_SCENERY_ID_MAX; sceneryId++)
|
||||
for (uint16_t sceneryId = 0; sceneryId < MAX_SMALL_SCENERY_OBJECTS; sceneryId++)
|
||||
{
|
||||
rct_scenery_entry* sceneryEntry = get_small_scenery_entry(sceneryId);
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->small_scenery.scenery_tab_id);
|
||||
init_scenery_entry(sceneryEntry, { SCENERY_TYPE_SMALL, sceneryId }, sceneryEntry->small_scenery.scenery_tab_id);
|
||||
}
|
||||
|
||||
// large scenery
|
||||
for (int32_t sceneryId = SCENERY_LARGE_SCENERY_ID_MIN; sceneryId <= SCENERY_LARGE_SCENERY_ID_MAX; sceneryId++)
|
||||
for (uint16_t sceneryId = 0; sceneryId < MAX_LARGE_SCENERY_OBJECTS; sceneryId++)
|
||||
{
|
||||
int32_t largeSceneryIndex = sceneryId - SCENERY_LARGE_SCENERY_ID_MIN;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = get_large_scenery_entry(largeSceneryIndex);
|
||||
rct_scenery_entry* sceneryEntry = get_large_scenery_entry(sceneryId);
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->large_scenery.scenery_tab_id);
|
||||
init_scenery_entry(sceneryEntry, { SCENERY_TYPE_LARGE, sceneryId }, sceneryEntry->large_scenery.scenery_tab_id);
|
||||
}
|
||||
|
||||
// walls
|
||||
for (int32_t sceneryId = SCENERY_WALLS_ID_MIN; sceneryId <= SCENERY_WALLS_ID_MAX; sceneryId++)
|
||||
for (uint16_t sceneryId = 0; sceneryId < MAX_WALL_SCENERY_OBJECTS; sceneryId++)
|
||||
{
|
||||
int32_t wallSceneryIndex = sceneryId - SCENERY_WALLS_ID_MIN;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = get_wall_entry(wallSceneryIndex);
|
||||
rct_scenery_entry* sceneryEntry = get_wall_entry(sceneryId);
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->wall.scenery_tab_id);
|
||||
init_scenery_entry(sceneryEntry, { SCENERY_TYPE_WALL, sceneryId }, sceneryEntry->wall.scenery_tab_id);
|
||||
}
|
||||
|
||||
// banners
|
||||
for (int32_t sceneryId = SCENERY_BANNERS_ID_MIN; sceneryId <= SCENERY_BANNERS_ID_MAX; sceneryId++)
|
||||
for (uint16_t sceneryId = 0; sceneryId < MAX_BANNER_OBJECTS; sceneryId++)
|
||||
{
|
||||
int32_t bannerIndex = sceneryId - SCENERY_BANNERS_ID_MIN;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = get_banner_entry(bannerIndex);
|
||||
rct_scenery_entry* sceneryEntry = get_banner_entry(sceneryId);
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->banner.scenery_tab_id);
|
||||
init_scenery_entry(sceneryEntry, { SCENERY_TYPE_BANNER, sceneryId }, sceneryEntry->banner.scenery_tab_id);
|
||||
}
|
||||
|
||||
// path bits
|
||||
for (int32_t sceneryId = SCENERY_PATH_SCENERY_ID_MIN; sceneryId <= SCENERY_PATH_SCENERY_ID_MAX; sceneryId++)
|
||||
for (uint16_t sceneryId = 0; sceneryId < MAX_PATH_ADDITION_OBJECTS; sceneryId++)
|
||||
{
|
||||
int32_t pathBitIndex = sceneryId - SCENERY_PATH_SCENERY_ID_MIN;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = get_footpath_item_entry(pathBitIndex);
|
||||
rct_scenery_entry* sceneryEntry = get_footpath_item_entry(sceneryId);
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->path_bit.scenery_tab_id);
|
||||
init_scenery_entry(sceneryEntry, { SCENERY_TYPE_PATH_ITEM, sceneryId }, sceneryEntry->path_bit.scenery_tab_id);
|
||||
}
|
||||
|
||||
for (rct_widgetindex widgetIndex = WIDX_SCENERY_TAB_1; widgetIndex < WIDX_SCENERY_LIST; widgetIndex++)
|
||||
|
@ -385,7 +378,7 @@ void window_scenery_init()
|
|||
|
||||
if (left != 3 || tabIndex != SCENERY_WINDOW_TABS - 1)
|
||||
{
|
||||
if (window_scenery_tab_entries[tabIndex][0] == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (window_scenery_tab_entries[tabIndex][0].IsUndefined())
|
||||
continue;
|
||||
|
||||
if (enabledScenerySets[tabIndex])
|
||||
|
@ -419,11 +412,11 @@ void window_scenery_set_default_placement_configuration()
|
|||
window_scenery_init();
|
||||
|
||||
for (int32_t i = 0; i < SCENERY_WINDOW_TABS; i++)
|
||||
gWindowSceneryTabSelections[i] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
gWindowSceneryTabSelections[i] = ScenerySelection::CreateUndefined();
|
||||
|
||||
for (int32_t i = 0; i < SCENERY_WINDOW_TABS; i++)
|
||||
{
|
||||
if (window_scenery_tab_entries[i][0] != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (!window_scenery_tab_entries[i][0].IsUndefined())
|
||||
{
|
||||
gWindowSceneryActiveTabIndex = i;
|
||||
return;
|
||||
|
@ -477,7 +470,7 @@ rct_window* window_scenery_open()
|
|||
gWindowSceneryRotation = 3;
|
||||
gSceneryCtrlPressed = false;
|
||||
gSceneryShiftPressed = false;
|
||||
window->scenery.selected_scenery_id = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
window->scenery.SelectedScenery = ScenerySelection::CreateUndefined();
|
||||
window->scenery.hover_counter = 0;
|
||||
window_push_others_below(window);
|
||||
gSceneryGhostType = 0;
|
||||
|
@ -522,22 +515,22 @@ struct scenery_item
|
|||
{
|
||||
int32_t allRows;
|
||||
int32_t selected_item;
|
||||
uint16_t sceneryId;
|
||||
ScenerySelection scenerySelection;
|
||||
};
|
||||
|
||||
static scenery_item window_scenery_count_rows_with_selected_item(int32_t tabIndex)
|
||||
{
|
||||
scenery_item sceneryItem = { 0, 0, WINDOW_SCENERY_TAB_SELECTION_UNDEFINED };
|
||||
scenery_item sceneryItem = { 0, 0, ScenerySelection::CreateUndefined() };
|
||||
int32_t totalItems = 0;
|
||||
uint16_t id = 0;
|
||||
uint16_t sceneryId = gWindowSceneryTabSelections[tabIndex];
|
||||
ScenerySelection currentEntry = { 0, 0 };
|
||||
ScenerySelection scenerySelection = gWindowSceneryTabSelections[tabIndex];
|
||||
|
||||
while ((id = window_scenery_tab_entries[tabIndex][totalItems]) != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
while ((currentEntry = window_scenery_tab_entries[tabIndex][totalItems]), !currentEntry.IsUndefined())
|
||||
{
|
||||
if (id == sceneryId)
|
||||
if (currentEntry == scenerySelection)
|
||||
{
|
||||
sceneryItem.selected_item = totalItems;
|
||||
sceneryItem.sceneryId = sceneryId;
|
||||
sceneryItem.scenerySelection = scenerySelection;
|
||||
}
|
||||
totalItems++;
|
||||
}
|
||||
|
@ -550,7 +543,7 @@ static int32_t window_scenery_count_rows()
|
|||
int32_t tabIndex = gWindowSceneryActiveTabIndex;
|
||||
int32_t totalItems = 0;
|
||||
|
||||
while (window_scenery_tab_entries[tabIndex][totalItems] != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
while (!window_scenery_tab_entries[tabIndex][totalItems].IsUndefined())
|
||||
{
|
||||
totalItems++;
|
||||
}
|
||||
|
@ -632,12 +625,12 @@ void window_scenery_update_scroll(rct_window* w)
|
|||
|
||||
int32_t maxTop = std::max(0, w->scrolls[0].v_bottom - listHeight);
|
||||
int32_t rowSelected = count_rows(sceneryItem.selected_item);
|
||||
if (sceneryItem.sceneryId == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (sceneryItem.scenerySelection.IsUndefined())
|
||||
{
|
||||
rowSelected = 0;
|
||||
uint16_t sceneryId = window_scenery_tab_entries[tabIndex][0];
|
||||
if (sceneryId != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
gWindowSceneryTabSelections[tabIndex] = sceneryId;
|
||||
ScenerySelection scenery = window_scenery_tab_entries[tabIndex][0];
|
||||
if (!scenery.IsUndefined())
|
||||
gWindowSceneryTabSelections[tabIndex] = scenery;
|
||||
}
|
||||
|
||||
w->scrolls[0].v_top = window_scenery_rows_height(rowSelected);
|
||||
|
@ -748,9 +741,9 @@ static void window_scenery_dropdown(rct_window* w, rct_widgetindex widgetIndex,
|
|||
*/
|
||||
static void window_scenery_periodic_update(rct_window* w)
|
||||
{
|
||||
if (w->scenery.selected_scenery_id != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (!w->scenery.SelectedScenery.IsUndefined())
|
||||
{
|
||||
w->scenery.selected_scenery_id = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
w->scenery.SelectedScenery = ScenerySelection::CreateUndefined();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,38 +815,38 @@ static void window_scenery_update(rct_window* w)
|
|||
gCurrentToolId = TOOL_CROSSHAIR;
|
||||
}
|
||||
else if (gWindowSceneryPaintEnabled == 1)
|
||||
{ // the repaint scenery tool is active
|
||||
{
|
||||
gCurrentToolId = TOOL_PAINT_DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t tabIndex = gWindowSceneryActiveTabIndex;
|
||||
int16_t tabSelectedSceneryId = gWindowSceneryTabSelections[tabIndex];
|
||||
ScenerySelection tabSelectedScenery = gWindowSceneryTabSelections[tabIndex];
|
||||
|
||||
if (tabSelectedSceneryId != -1)
|
||||
if (!tabSelectedScenery.IsUndefined())
|
||||
{
|
||||
if (tabSelectedSceneryId >= SCENERY_BANNERS_ID_MIN)
|
||||
{ // banner
|
||||
if (tabSelectedScenery.SceneryType == SCENERY_TYPE_BANNER)
|
||||
{
|
||||
gCurrentToolId = TOOL_ENTRANCE_DOWN;
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_LARGE_SCENERY_ID_MIN)
|
||||
{ // large scenery
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_LARGE)
|
||||
{
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(
|
||||
get_large_scenery_entry(tabSelectedSceneryId - SCENERY_LARGE_SCENERY_ID_MIN)->large_scenery.tool_id);
|
||||
get_large_scenery_entry(tabSelectedScenery.EntryIndex)->large_scenery.tool_id);
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_WALLS_ID_MIN)
|
||||
{ // wall
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(
|
||||
get_wall_entry(tabSelectedSceneryId - SCENERY_WALLS_ID_MIN)->wall.tool_id);
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_WALL)
|
||||
{
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(get_wall_entry(tabSelectedScenery.EntryIndex)->wall.tool_id);
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_PATH_SCENERY_ID_MIN)
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_PATH_ITEM)
|
||||
{ // path bit
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(
|
||||
get_footpath_item_entry(tabSelectedSceneryId - SCENERY_PATH_SCENERY_ID_MIN)->path_bit.tool_id);
|
||||
get_footpath_item_entry(tabSelectedScenery.EntryIndex)->path_bit.tool_id);
|
||||
}
|
||||
else
|
||||
{ // small scenery
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(get_small_scenery_entry(tabSelectedSceneryId)->small_scenery.tool_id);
|
||||
gCurrentToolId = static_cast<TOOL_IDX>(
|
||||
get_small_scenery_entry(tabSelectedScenery.EntryIndex)->small_scenery.tool_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -869,23 +862,23 @@ void window_scenery_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* w
|
|||
*height = window_scenery_rows_height(rows);
|
||||
}
|
||||
|
||||
static uint16_t get_scenery_id_by_cursor_pos(const ScreenCoordsXY& screenCoords)
|
||||
static ScenerySelection get_scenery_id_by_cursor_pos(const ScreenCoordsXY& screenCoords)
|
||||
{
|
||||
int32_t tabSceneryIndex = screenCoords.x / SCENERY_BUTTON_WIDTH + (screenCoords.y / SCENERY_BUTTON_HEIGHT) * 9;
|
||||
uint8_t tabIndex = gWindowSceneryActiveTabIndex;
|
||||
|
||||
int32_t itemCounter = 0;
|
||||
uint16_t sceneryId = 0;
|
||||
ScenerySelection scenery = ScenerySelection::CreateUndefined();
|
||||
while (itemCounter <= tabSceneryIndex)
|
||||
{
|
||||
sceneryId = window_scenery_tab_entries[tabIndex][itemCounter];
|
||||
if (sceneryId == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
return WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
scenery = window_scenery_tab_entries[tabIndex][itemCounter];
|
||||
if (scenery.IsUndefined())
|
||||
return ScenerySelection::CreateUndefined();
|
||||
|
||||
itemCounter++;
|
||||
}
|
||||
|
||||
return sceneryId;
|
||||
return scenery;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -894,12 +887,12 @@ static uint16_t get_scenery_id_by_cursor_pos(const ScreenCoordsXY& screenCoords)
|
|||
*/
|
||||
void window_scenery_scrollmousedown(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
||||
{
|
||||
uint16_t sceneryId = get_scenery_id_by_cursor_pos(screenCoords);
|
||||
if (sceneryId == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
ScenerySelection scenery = get_scenery_id_by_cursor_pos(screenCoords);
|
||||
if (scenery.IsUndefined())
|
||||
return;
|
||||
|
||||
uint8_t tabIndex = gWindowSceneryActiveTabIndex;
|
||||
gWindowSceneryTabSelections[tabIndex] = sceneryId;
|
||||
gWindowSceneryTabSelections[tabIndex] = scenery;
|
||||
|
||||
gWindowSceneryPaintEnabled &= 0xFE;
|
||||
gWindowSceneryEyedropperEnabled = false;
|
||||
|
@ -915,10 +908,10 @@ void window_scenery_scrollmousedown(rct_window* w, int32_t scrollIndex, const Sc
|
|||
*/
|
||||
void window_scenery_scrollmouseover(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
||||
{
|
||||
uint16_t sceneryId = get_scenery_id_by_cursor_pos(screenCoords);
|
||||
if (sceneryId != WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
ScenerySelection scenery = get_scenery_id_by_cursor_pos(screenCoords);
|
||||
if (!scenery.IsUndefined())
|
||||
{
|
||||
w->scenery.selected_scenery_id = sceneryId;
|
||||
w->scenery.SelectedScenery = scenery;
|
||||
w->Invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -995,23 +988,23 @@ void window_scenery_invalidate(rct_window* w)
|
|||
window_scenery_widgets[WIDX_SCENERY_EYEDROPPER_BUTTON].type = WWT_FLATBTN;
|
||||
}
|
||||
|
||||
int16_t tabSelectedSceneryId = gWindowSceneryTabSelections[tabIndex];
|
||||
if (tabSelectedSceneryId != -1)
|
||||
ScenerySelection tabSelectedScenery = gWindowSceneryTabSelections[tabIndex];
|
||||
if (!tabSelectedScenery.IsUndefined())
|
||||
{
|
||||
if (tabSelectedSceneryId <= SCENERY_SMALL_SCENERY_ID_MAX)
|
||||
if (tabSelectedScenery.SceneryType == SCENERY_TYPE_SMALL)
|
||||
{
|
||||
if (!(gWindowSceneryPaintEnabled & 1))
|
||||
{
|
||||
window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_FLATBTN;
|
||||
}
|
||||
|
||||
rct_scenery_entry* sceneryEntry = get_small_scenery_entry(tabSelectedSceneryId);
|
||||
rct_scenery_entry* sceneryEntry = get_small_scenery_entry(tabSelectedScenery.EntryIndex);
|
||||
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_ROTATABLE))
|
||||
{
|
||||
window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_FLATBTN;
|
||||
}
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_LARGE_SCENERY_ID_MIN)
|
||||
else if (tabSelectedScenery.SceneryType >= SCENERY_TYPE_LARGE)
|
||||
{
|
||||
window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_FLATBTN;
|
||||
}
|
||||
|
@ -1036,30 +1029,30 @@ void window_scenery_invalidate(rct_window* w)
|
|||
window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_COLOURBTN;
|
||||
window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_EMPTY;
|
||||
}
|
||||
else if (tabSelectedSceneryId != -1)
|
||||
else if (!tabSelectedScenery.IsUndefined())
|
||||
{
|
||||
rct_scenery_entry* sceneryEntry = nullptr;
|
||||
|
||||
if (tabSelectedSceneryId >= SCENERY_BANNERS_ID_MIN)
|
||||
if (tabSelectedScenery.SceneryType == SCENERY_TYPE_BANNER)
|
||||
{
|
||||
sceneryEntry = get_banner_entry(tabSelectedSceneryId - SCENERY_BANNERS_ID_MIN);
|
||||
sceneryEntry = get_banner_entry(tabSelectedScenery.EntryIndex);
|
||||
if (sceneryEntry->banner.flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
{
|
||||
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLOURBTN;
|
||||
}
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_LARGE_SCENERY_ID_MIN)
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_LARGE)
|
||||
{
|
||||
sceneryEntry = get_large_scenery_entry(tabSelectedSceneryId - SCENERY_LARGE_SCENERY_ID_MIN);
|
||||
sceneryEntry = get_large_scenery_entry(tabSelectedScenery.EntryIndex);
|
||||
|
||||
if (sceneryEntry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLOURBTN;
|
||||
if (sceneryEntry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR)
|
||||
window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLOURBTN;
|
||||
}
|
||||
else if (tabSelectedSceneryId >= SCENERY_WALLS_ID_MIN)
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_WALL)
|
||||
{
|
||||
sceneryEntry = get_wall_entry(tabSelectedSceneryId - SCENERY_WALLS_ID_MIN);
|
||||
sceneryEntry = get_wall_entry(tabSelectedScenery.EntryIndex);
|
||||
if (sceneryEntry->wall.flags & (WALL_SCENERY_HAS_PRIMARY_COLOUR | WALL_SCENERY_HAS_GLASS))
|
||||
{
|
||||
window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLOURBTN;
|
||||
|
@ -1075,9 +1068,9 @@ void window_scenery_invalidate(rct_window* w)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (tabSelectedSceneryId <= SCENERY_SMALL_SCENERY_ID_MAX)
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_SMALL)
|
||||
{
|
||||
sceneryEntry = get_small_scenery_entry(tabSelectedSceneryId);
|
||||
sceneryEntry = get_small_scenery_entry(tabSelectedScenery.EntryIndex);
|
||||
|
||||
if (scenery_small_entry_has_flag(
|
||||
sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS))
|
||||
|
@ -1133,50 +1126,48 @@ void window_scenery_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
|||
dpi, imageId, w->windowPos.x + window_scenery_widgets[selectedWidgetId].left,
|
||||
w->windowPos.y + window_scenery_widgets[selectedWidgetId].top, selectedWidgetId);
|
||||
|
||||
uint16_t selectedSceneryEntryId = w->scenery.selected_scenery_id;
|
||||
if (selectedSceneryEntryId == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
ScenerySelection selectedSceneryEntry = w->scenery.SelectedScenery;
|
||||
if (selectedSceneryEntry.IsUndefined())
|
||||
{
|
||||
if (gWindowSceneryPaintEnabled & 1) // repaint coloured scenery tool is on
|
||||
return;
|
||||
if (gWindowSceneryEyedropperEnabled)
|
||||
return;
|
||||
|
||||
selectedSceneryEntryId = gWindowSceneryTabSelections[tabIndex];
|
||||
selectedSceneryEntry = gWindowSceneryTabSelections[tabIndex];
|
||||
|
||||
if (selectedSceneryEntryId == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (selectedSceneryEntry.IsUndefined())
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t price = 0;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = nullptr;
|
||||
if (selectedSceneryEntryId >= SCENERY_BANNERS_ID_MIN)
|
||||
switch (selectedSceneryEntry.SceneryType)
|
||||
{
|
||||
sceneryEntry = get_banner_entry(selectedSceneryEntryId - SCENERY_BANNERS_ID_MIN);
|
||||
price = sceneryEntry->banner.price;
|
||||
}
|
||||
else if (selectedSceneryEntryId >= SCENERY_LARGE_SCENERY_ID_MIN)
|
||||
{
|
||||
sceneryEntry = get_large_scenery_entry(selectedSceneryEntryId - SCENERY_LARGE_SCENERY_ID_MIN);
|
||||
price = sceneryEntry->large_scenery.price * 10;
|
||||
}
|
||||
else if (selectedSceneryEntryId >= SCENERY_WALLS_ID_MIN)
|
||||
{
|
||||
sceneryEntry = get_wall_entry(selectedSceneryEntryId - SCENERY_WALLS_ID_MIN);
|
||||
price = sceneryEntry->wall.price;
|
||||
}
|
||||
else if (selectedSceneryEntryId >= SCENERY_PATH_SCENERY_ID_MIN)
|
||||
{
|
||||
sceneryEntry = get_footpath_item_entry(selectedSceneryEntryId - SCENERY_PATH_SCENERY_ID_MIN);
|
||||
price = sceneryEntry->path_bit.price;
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneryEntry = get_small_scenery_entry(selectedSceneryEntryId);
|
||||
price = sceneryEntry->small_scenery.price * 10;
|
||||
case SCENERY_TYPE_SMALL:
|
||||
sceneryEntry = get_small_scenery_entry(selectedSceneryEntry.EntryIndex);
|
||||
price = sceneryEntry->small_scenery.price * 10;
|
||||
break;
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
sceneryEntry = get_footpath_item_entry(selectedSceneryEntry.EntryIndex);
|
||||
price = sceneryEntry->path_bit.price;
|
||||
break;
|
||||
case SCENERY_TYPE_WALL:
|
||||
sceneryEntry = get_wall_entry(selectedSceneryEntry.EntryIndex);
|
||||
price = sceneryEntry->wall.price;
|
||||
break;
|
||||
case SCENERY_TYPE_LARGE:
|
||||
sceneryEntry = get_large_scenery_entry(selectedSceneryEntry.EntryIndex);
|
||||
price = sceneryEntry->large_scenery.price * 10;
|
||||
break;
|
||||
case SCENERY_TYPE_BANNER:
|
||||
sceneryEntry = get_banner_entry(selectedSceneryEntry.EntryIndex);
|
||||
price = sceneryEntry->banner.price;
|
||||
break;
|
||||
}
|
||||
|
||||
if (w->scenery.selected_scenery_id == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED && gSceneryPlaceCost != MONEY32_UNDEFINED)
|
||||
if (w->scenery.SelectedScenery.IsUndefined() && gSceneryPlaceCost != MONEY32_UNDEFINED)
|
||||
{
|
||||
price = gSceneryPlaceCost;
|
||||
}
|
||||
|
@ -1208,17 +1199,17 @@ void window_scenery_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t s
|
|||
uint8_t tabIndex = gWindowSceneryActiveTabIndex;
|
||||
|
||||
int32_t sceneryTabItemIndex = 0;
|
||||
uint16_t currentSceneryGlobalId = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
ScenerySelection currentSceneryGlobal = ScenerySelection::CreateUndefined();
|
||||
int16_t left = 0, top = 0;
|
||||
|
||||
while ((currentSceneryGlobalId = window_scenery_tab_entries[tabIndex][sceneryTabItemIndex])
|
||||
!= WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
while ((currentSceneryGlobal = window_scenery_tab_entries[tabIndex][sceneryTabItemIndex]),
|
||||
!currentSceneryGlobal.IsUndefined())
|
||||
{
|
||||
uint16_t tabSelectedSceneryId = gWindowSceneryTabSelections[tabIndex];
|
||||
ScenerySelection tabSelectedScenery = gWindowSceneryTabSelections[tabIndex];
|
||||
|
||||
if (gWindowSceneryPaintEnabled == 1 || gWindowSceneryEyedropperEnabled)
|
||||
{
|
||||
if (w->scenery.selected_scenery_id == currentSceneryGlobalId)
|
||||
if (w->scenery.SelectedScenery == currentSceneryGlobal)
|
||||
{
|
||||
gfx_fill_rect_inset(
|
||||
dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1],
|
||||
|
@ -1227,13 +1218,13 @@ void window_scenery_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t s
|
|||
}
|
||||
else
|
||||
{
|
||||
if (tabSelectedSceneryId == currentSceneryGlobalId)
|
||||
if (tabSelectedScenery == currentSceneryGlobal)
|
||||
{
|
||||
gfx_fill_rect_inset(
|
||||
dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1],
|
||||
(INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_MID_LIGHT));
|
||||
}
|
||||
else if (w->scenery.selected_scenery_id == currentSceneryGlobalId)
|
||||
else if (w->scenery.SelectedScenery == currentSceneryGlobal)
|
||||
{
|
||||
gfx_fill_rect_inset(
|
||||
dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1],
|
||||
|
@ -1245,27 +1236,27 @@ void window_scenery_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t s
|
|||
rct_drawpixelinfo clipdpi;
|
||||
if (clip_drawpixelinfo(&clipdpi, dpi, left + 1, top + 1, SCENERY_BUTTON_WIDTH - 2, SCENERY_BUTTON_HEIGHT - 2))
|
||||
{
|
||||
if (currentSceneryGlobalId >= SCENERY_BANNERS_ID_MIN)
|
||||
if (currentSceneryGlobal.SceneryType == SCENERY_TYPE_BANNER)
|
||||
{
|
||||
sceneryEntry = get_banner_entry(currentSceneryGlobalId - SCENERY_BANNERS_ID_MIN);
|
||||
sceneryEntry = get_banner_entry(currentSceneryGlobal.EntryIndex);
|
||||
uint32_t imageId = sceneryEntry->image + gWindowSceneryRotation * 2;
|
||||
imageId |= (gWindowSceneryPrimaryColour << 19) | IMAGE_TYPE_REMAP;
|
||||
|
||||
gfx_draw_sprite(&clipdpi, imageId, 0x21, 0x28, w->colours[1]);
|
||||
gfx_draw_sprite(&clipdpi, imageId + 1, 0x21, 0x28, w->colours[1]);
|
||||
}
|
||||
else if (currentSceneryGlobalId >= SCENERY_LARGE_SCENERY_ID_MIN)
|
||||
else if (currentSceneryGlobal.SceneryType == SCENERY_TYPE_LARGE)
|
||||
{
|
||||
sceneryEntry = get_large_scenery_entry(currentSceneryGlobalId - SCENERY_LARGE_SCENERY_ID_MIN);
|
||||
sceneryEntry = get_large_scenery_entry(currentSceneryGlobal.EntryIndex);
|
||||
uint32_t imageId = sceneryEntry->image + gWindowSceneryRotation;
|
||||
imageId |= (gWindowSceneryPrimaryColour << 19) | IMAGE_TYPE_REMAP;
|
||||
imageId |= (gWindowScenerySecondaryColour << 24) | IMAGE_TYPE_REMAP_2_PLUS;
|
||||
|
||||
gfx_draw_sprite(&clipdpi, imageId, 0x21, 0, w->colours[1]);
|
||||
}
|
||||
else if (currentSceneryGlobalId >= SCENERY_WALLS_ID_MIN)
|
||||
else if (currentSceneryGlobal.SceneryType == SCENERY_TYPE_WALL)
|
||||
{
|
||||
sceneryEntry = get_wall_entry(currentSceneryGlobalId - SCENERY_WALLS_ID_MIN);
|
||||
sceneryEntry = get_wall_entry(currentSceneryGlobal.EntryIndex);
|
||||
uint32_t imageId = sceneryEntry->image;
|
||||
uint8_t tertiaryColour = w->colours[1];
|
||||
uint16_t spriteTop = (sceneryEntry->wall.height * 2) + 0x32;
|
||||
|
@ -1305,16 +1296,16 @@ void window_scenery_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t s
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (currentSceneryGlobalId >= SCENERY_PATH_SCENERY_ID_MIN)
|
||||
else if (currentSceneryGlobal.SceneryType == SCENERY_TYPE_PATH_ITEM)
|
||||
{
|
||||
sceneryEntry = get_footpath_item_entry(currentSceneryGlobalId - SCENERY_PATH_SCENERY_ID_MIN);
|
||||
sceneryEntry = get_footpath_item_entry(currentSceneryGlobal.EntryIndex);
|
||||
uint32_t imageId = sceneryEntry->image;
|
||||
|
||||
gfx_draw_sprite(&clipdpi, imageId, 0x0B, 0x10, w->colours[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneryEntry = get_small_scenery_entry(currentSceneryGlobalId);
|
||||
sceneryEntry = get_small_scenery_entry(currentSceneryGlobal.EntryIndex);
|
||||
uint32_t imageId = sceneryEntry->image + gWindowSceneryRotation;
|
||||
|
||||
if (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
|
||||
|
@ -1363,33 +1354,33 @@ void window_scenery_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t s
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t window_scenery_find_tab_with_scenery_id(int32_t sceneryId)
|
||||
static int32_t window_scenery_find_tab_with_scenery(const ScenerySelection& scenery)
|
||||
{
|
||||
for (int32_t i = 0; i < SCENERY_WINDOW_TABS; i++)
|
||||
{
|
||||
for (int32_t j = 0; j < SCENERY_ENTRIES_BY_TAB; j++)
|
||||
for (int32_t j = 0; j < SCENERY_ENTRIES_PER_TAB; j++)
|
||||
{
|
||||
uint16_t entry = window_scenery_tab_entries[i][j];
|
||||
if (entry == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
ScenerySelection entry = window_scenery_tab_entries[i][j];
|
||||
if (entry.IsUndefined())
|
||||
break;
|
||||
if (entry == sceneryId)
|
||||
if (entry == scenery)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool window_scenery_set_selected_item(int32_t sceneryId)
|
||||
bool window_scenery_set_selected_item(const ScenerySelection& scenery)
|
||||
{
|
||||
bool result = false;
|
||||
rct_window* w = window_bring_to_front_by_class(WC_SCENERY);
|
||||
if (w != nullptr)
|
||||
{
|
||||
int32_t tabIndex = window_scenery_find_tab_with_scenery_id(sceneryId);
|
||||
int32_t tabIndex = window_scenery_find_tab_with_scenery(scenery);
|
||||
if (tabIndex != -1)
|
||||
{
|
||||
gWindowSceneryActiveTabIndex = tabIndex;
|
||||
gWindowSceneryTabSelections[tabIndex] = sceneryId;
|
||||
gWindowSceneryTabSelections[tabIndex] = scenery;
|
||||
|
||||
audio_play_sound(SoundId::Click1, 0, context_get_width() / 2);
|
||||
w->scenery.hover_counter = -16;
|
||||
|
@ -1406,6 +1397,6 @@ void window_scenery_reset_selected_scenery_items()
|
|||
{
|
||||
for (size_t i = 0; i < SCENERY_WINDOW_TABS; i++)
|
||||
{
|
||||
gWindowSceneryTabSelections[i] = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
gWindowSceneryTabSelections[i].SetUndefined();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1117,12 +1117,11 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
case VIEWPORT_INTERACTION_ITEM_SCENERY:
|
||||
{
|
||||
SmallSceneryElement* sceneryElement = tileElement->AsSmallScenery();
|
||||
int32_t entryIndex = sceneryElement->GetEntryIndex();
|
||||
auto entryIndex = sceneryElement->GetEntryIndex();
|
||||
rct_scenery_entry* sceneryEntry = get_small_scenery_entry(entryIndex);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_SMALL_SCENERY, entryIndex);
|
||||
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
|
||||
if (window_scenery_set_selected_item({ SCENERY_TYPE_SMALL, entryIndex }))
|
||||
{
|
||||
gWindowSceneryRotation = sceneryElement->GetDirectionWithOffset(get_current_rotation());
|
||||
gWindowSceneryPrimaryColour = sceneryElement->GetPrimaryColour();
|
||||
|
@ -1134,12 +1133,11 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
}
|
||||
case VIEWPORT_INTERACTION_ITEM_WALL:
|
||||
{
|
||||
int32_t entryIndex = tileElement->AsWall()->GetEntryIndex();
|
||||
auto entryIndex = tileElement->AsWall()->GetEntryIndex();
|
||||
rct_scenery_entry* sceneryEntry = get_wall_entry(entryIndex);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_WALLS, entryIndex);
|
||||
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
|
||||
if (window_scenery_set_selected_item({ SCENERY_TYPE_WALL, entryIndex }))
|
||||
{
|
||||
gWindowSceneryPrimaryColour = tileElement->AsWall()->GetPrimaryColour();
|
||||
gWindowScenerySecondaryColour = tileElement->AsWall()->GetSecondaryColour();
|
||||
|
@ -1151,12 +1149,11 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
}
|
||||
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
|
||||
{
|
||||
int32_t entryIndex = tileElement->AsLargeScenery()->GetEntryIndex();
|
||||
auto entryIndex = tileElement->AsLargeScenery()->GetEntryIndex();
|
||||
rct_scenery_entry* sceneryEntry = get_large_scenery_entry(entryIndex);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_LARGE_SCENERY, entryIndex);
|
||||
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
|
||||
if (window_scenery_set_selected_item({ SCENERY_TYPE_LARGE, entryIndex }))
|
||||
{
|
||||
gWindowSceneryRotation = (get_current_rotation() + tileElement->GetDirection()) & 3;
|
||||
gWindowSceneryPrimaryColour = tileElement->AsLargeScenery()->GetPrimaryColour();
|
||||
|
@ -1174,8 +1171,7 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
auto sceneryEntry = get_banner_entry(banner->type);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_BANNERS, banner->type);
|
||||
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
|
||||
if (window_scenery_set_selected_item({ SCENERY_TYPE_BANNER, banner->type }))
|
||||
{
|
||||
gWindowSceneryEyedropperEnabled = false;
|
||||
}
|
||||
|
@ -1185,12 +1181,11 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
}
|
||||
case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM:
|
||||
{
|
||||
int32_t entryIndex = tileElement->AsPath()->GetAdditionEntryIndex();
|
||||
auto entryIndex = tileElement->AsPath()->GetAdditionEntryIndex();
|
||||
rct_scenery_entry* sceneryEntry = get_footpath_item_entry(entryIndex);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_PATH_BITS, entryIndex);
|
||||
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
|
||||
if (window_scenery_set_selected_item({ SCENERY_TYPE_PATH_ITEM, entryIndex }))
|
||||
{
|
||||
gWindowSceneryEyedropperEnabled = false;
|
||||
}
|
||||
|
@ -1211,7 +1206,7 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
|
|||
* edi : parameter_3
|
||||
*/
|
||||
static void sub_6E1F34(
|
||||
int16_t x, int16_t y, uint16_t selected_scenery, CoordsXY& gridPos, uint32_t* parameter_1, uint32_t* parameter_2,
|
||||
int16_t x, int16_t y, ScenerySelection selection, CoordsXY& gridPos, uint32_t* parameter_1, uint32_t* parameter_2,
|
||||
uint32_t* parameter_3)
|
||||
{
|
||||
rct_window* w = window_find_by_class(WC_SCENERY);
|
||||
|
@ -1222,33 +1217,30 @@ static void sub_6E1F34(
|
|||
return;
|
||||
}
|
||||
|
||||
// The upper byte of selected_scenery contains the type, the lower byte the index.
|
||||
uint8_t scenery_type = selected_scenery >> 8;
|
||||
selected_scenery &= 0xFF;
|
||||
uint16_t maxPossibleHeight = (std::numeric_limits<decltype(TileElement::base_height)>::max() - 32) << MAX_ZOOM_LEVEL;
|
||||
bool can_raise_item = false;
|
||||
|
||||
if (scenery_type == SCENERY_TYPE_SMALL)
|
||||
if (selection.SceneryType == SCENERY_TYPE_SMALL)
|
||||
{
|
||||
rct_scenery_entry* scenery_entry = get_small_scenery_entry(selected_scenery);
|
||||
rct_scenery_entry* scenery_entry = get_small_scenery_entry(selection.EntryIndex);
|
||||
maxPossibleHeight -= scenery_entry->small_scenery.height;
|
||||
if (scenery_small_entry_has_flag(scenery_entry, SMALL_SCENERY_FLAG_STACKABLE))
|
||||
{
|
||||
can_raise_item = true;
|
||||
}
|
||||
}
|
||||
else if (scenery_type == SCENERY_TYPE_WALL)
|
||||
else if (selection.SceneryType == SCENERY_TYPE_WALL)
|
||||
{
|
||||
rct_scenery_entry* scenery_entry = get_wall_entry(selected_scenery);
|
||||
rct_scenery_entry* scenery_entry = get_wall_entry(selection.EntryIndex);
|
||||
if (scenery_entry)
|
||||
{
|
||||
maxPossibleHeight -= scenery_entry->wall.height;
|
||||
}
|
||||
can_raise_item = true;
|
||||
}
|
||||
else if (scenery_type == SCENERY_TYPE_LARGE)
|
||||
else if (selection.SceneryType == SCENERY_TYPE_LARGE)
|
||||
{
|
||||
rct_scenery_entry* scenery_entry = get_large_scenery_entry(selected_scenery);
|
||||
rct_scenery_entry* scenery_entry = get_large_scenery_entry(selection.EntryIndex);
|
||||
if (scenery_entry)
|
||||
{
|
||||
int16_t maxClearZ = 0;
|
||||
|
@ -1333,20 +1325,20 @@ static void sub_6E1F34(
|
|||
}
|
||||
}
|
||||
|
||||
switch (scenery_type)
|
||||
switch (selection.SceneryType)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
{
|
||||
// Small scenery
|
||||
rct_scenery_entry* scenery = get_small_scenery_entry(selected_scenery);
|
||||
rct_scenery_entry* scenery = get_small_scenery_entry(selection.EntryIndex);
|
||||
if (!scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_FULL_TILE))
|
||||
{
|
||||
uint8_t cl = 0;
|
||||
uint8_t quadrant = 0;
|
||||
|
||||
// If CTRL not pressed
|
||||
if (!gSceneryCtrlPressed)
|
||||
{
|
||||
auto gridCoords = screen_get_map_xy_quadrant({ x, y }, &cl);
|
||||
auto gridCoords = screen_get_map_xy_quadrant({ x, y }, &quadrant);
|
||||
if (!gridCoords)
|
||||
{
|
||||
gridPos.setNull();
|
||||
|
@ -1379,7 +1371,7 @@ static void sub_6E1F34(
|
|||
{
|
||||
int16_t z = gSceneryCtrlPressZ;
|
||||
|
||||
auto mapCoords = screen_get_map_xy_quadrant_with_z({ x, y }, z, &cl);
|
||||
auto mapCoords = screen_get_map_xy_quadrant_with_z({ x, y }, z, &quadrant);
|
||||
if (!mapCoords)
|
||||
{
|
||||
gridPos.setNull();
|
||||
|
@ -1412,8 +1404,8 @@ static void sub_6E1F34(
|
|||
rotation &= 0x3;
|
||||
|
||||
// Also places it in lower but think thats for clobbering
|
||||
*parameter_1 = selected_scenery << 8;
|
||||
*parameter_2 = (cl ^ (1 << 1)) | (gWindowSceneryPrimaryColour << 8);
|
||||
*parameter_1 = selection.EntryIndex << 8;
|
||||
*parameter_2 = (quadrant ^ (1 << 1)) | (gWindowSceneryPrimaryColour << 8);
|
||||
*parameter_3 = rotation | (gWindowScenerySecondaryColour << 16);
|
||||
|
||||
if (gConfigGeneral.virtual_floor_style != VIRTUAL_FLOOR_STYLE_OFF)
|
||||
|
@ -1501,7 +1493,7 @@ static void sub_6E1F34(
|
|||
rotation &= 0x3;
|
||||
|
||||
// Also places it in lower but think thats for clobbering
|
||||
*parameter_1 = selected_scenery << 8;
|
||||
*parameter_1 = selection.EntryIndex << 8;
|
||||
*parameter_2 = 0 | (gWindowSceneryPrimaryColour << 8);
|
||||
*parameter_3 = rotation | (gWindowScenerySecondaryColour << 16);
|
||||
break;
|
||||
|
@ -1532,7 +1524,7 @@ static void sub_6E1F34(
|
|||
{
|
||||
*parameter_2 |= LOCATION_NULL;
|
||||
}
|
||||
*parameter_3 = selected_scenery + 1;
|
||||
*parameter_3 = selection.EntryIndex + 1;
|
||||
break;
|
||||
}
|
||||
case SCENERY_TYPE_WALL:
|
||||
|
@ -1599,7 +1591,7 @@ static void sub_6E1F34(
|
|||
_secondaryColour = gWindowScenerySecondaryColour;
|
||||
_tertiaryColour = gWindowSceneryTertiaryColour;
|
||||
// Also places it in lower but think thats for clobbering
|
||||
*parameter_1 = selected_scenery << 8;
|
||||
*parameter_1 = selection.EntryIndex << 8;
|
||||
*parameter_2 = cl | (gWindowSceneryPrimaryColour << 8);
|
||||
*parameter_3 = 0;
|
||||
break;
|
||||
|
@ -1672,7 +1664,7 @@ static void sub_6E1F34(
|
|||
|
||||
*parameter_1 = (rotation << 8);
|
||||
*parameter_2 = gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8);
|
||||
*parameter_3 = selected_scenery;
|
||||
*parameter_3 = selection.EntryIndex;
|
||||
break;
|
||||
}
|
||||
case SCENERY_TYPE_BANNER:
|
||||
|
@ -1709,7 +1701,7 @@ static void sub_6E1F34(
|
|||
z /= 2;
|
||||
|
||||
// Also places it in lower but think thats for clobbering
|
||||
*parameter_1 = selected_scenery << 8;
|
||||
*parameter_1 = selection.EntryIndex << 8;
|
||||
*parameter_2 = z | (rotation << 8);
|
||||
*parameter_3 = gWindowSceneryPrimaryColour;
|
||||
break;
|
||||
|
@ -1722,6 +1714,64 @@ static void sub_6E1F34(
|
|||
}
|
||||
}
|
||||
|
||||
static void sub_6E1F34_small_scenery(
|
||||
const ScreenCoordsXY& screenCoords, uint16_t sceneryIndex, CoordsXY& gridPos, uint8_t* outQuadrant,
|
||||
colour_t* outPrimaryColour, colour_t* outSecondaryColour)
|
||||
{
|
||||
uint32_t parameter1 = 0, parameter2 = 0, parameter3 = 0;
|
||||
sub_6E1F34(
|
||||
screenCoords.x, screenCoords.y, { SCENERY_TYPE_SMALL, sceneryIndex }, gridPos, ¶meter1, ¶meter2, ¶meter3);
|
||||
|
||||
*outQuadrant = parameter2 & 0xFF;
|
||||
*outPrimaryColour = (parameter2 >> 8) & 0xFF;
|
||||
*outSecondaryColour = (parameter3 >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
static void sub_6E1F34_path_item(const ScreenCoordsXY& screenCoords, uint16_t sceneryIndex, CoordsXY& gridPos, int32_t* outZ)
|
||||
{
|
||||
uint32_t parameter1 = 0, parameter2 = 0, parameter3 = 0;
|
||||
sub_6E1F34(
|
||||
screenCoords.x, screenCoords.y, { SCENERY_TYPE_PATH_ITEM, sceneryIndex }, gridPos, ¶meter1, ¶meter2,
|
||||
¶meter3);
|
||||
|
||||
*outZ = (parameter2 & 0xFF) * COORDS_Z_STEP;
|
||||
}
|
||||
|
||||
static void sub_6E1F34_wall(
|
||||
const ScreenCoordsXY& screenCoords, uint16_t sceneryIndex, CoordsXY& gridPos, colour_t* outPrimaryColour, uint8_t* outEdges)
|
||||
{
|
||||
uint32_t parameter1 = 0, parameter2 = 0, parameter3 = 0;
|
||||
sub_6E1F34(
|
||||
screenCoords.x, screenCoords.y, { SCENERY_TYPE_WALL, sceneryIndex }, gridPos, ¶meter1, ¶meter2, ¶meter3);
|
||||
|
||||
*outPrimaryColour = (parameter2 >> 8) & 0xFF;
|
||||
*outEdges = parameter2 & 0xFF;
|
||||
}
|
||||
|
||||
static void sub_6E1F34_large_scenery(
|
||||
const ScreenCoordsXY& screenCoords, uint16_t sceneryIndex, CoordsXY& gridPos, colour_t* outPrimaryColour,
|
||||
colour_t* outSecondaryColour, Direction* outDirection)
|
||||
{
|
||||
uint32_t parameter1 = 0, parameter2 = 0, parameter3 = 0;
|
||||
sub_6E1F34(
|
||||
screenCoords.x, screenCoords.y, { SCENERY_TYPE_LARGE, sceneryIndex }, gridPos, ¶meter1, ¶meter2, ¶meter3);
|
||||
|
||||
*outPrimaryColour = parameter2 & 0xFF;
|
||||
*outSecondaryColour = (parameter2 >> 8) & 0xFF;
|
||||
*outDirection = (parameter1 & 0xFF00) >> 8;
|
||||
}
|
||||
|
||||
static void sub_6E1F34_banner(
|
||||
const ScreenCoordsXY& screenCoords, uint16_t sceneryIndex, CoordsXY& gridPos, int32_t* outZ, Direction* outDirection)
|
||||
{
|
||||
uint32_t parameter1 = 0, parameter2 = 0, parameter3 = 0;
|
||||
sub_6E1F34(
|
||||
screenCoords.x, screenCoords.y, { SCENERY_TYPE_BANNER, sceneryIndex }, gridPos, ¶meter1, ¶meter2, ¶meter3);
|
||||
|
||||
*outDirection = (parameter2 >> 8) & 0xFF;
|
||||
*outZ = (parameter2 & 0xFF) * COORDS_Z_PER_TINY_Z;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006E2CC6
|
||||
|
@ -1740,24 +1790,26 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
return;
|
||||
}
|
||||
|
||||
uint16_t selectedTab = gWindowSceneryTabSelections[gWindowSceneryActiveTabIndex];
|
||||
uint8_t sceneryType = (selectedTab & 0xFF00) >> 8;
|
||||
ScenerySelection selectedTab = gWindowSceneryTabSelections[gWindowSceneryActiveTabIndex];
|
||||
uint8_t sceneryType = selectedTab.SceneryType;
|
||||
uint16_t selectedScenery = selectedTab.EntryIndex;
|
||||
|
||||
if (selectedTab == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED)
|
||||
if (selectedTab.IsUndefined())
|
||||
return;
|
||||
|
||||
CoordsXY gridPos;
|
||||
uint32_t parameter_1, parameter_2, parameter_3;
|
||||
|
||||
sub_6E1F34(x, y, selectedTab, gridPos, ¶meter_1, ¶meter_2, ¶meter_3);
|
||||
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
switch (sceneryType)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
{
|
||||
uint8_t quadrant;
|
||||
colour_t primaryColour;
|
||||
colour_t secondaryColour;
|
||||
sub_6E1F34_small_scenery({ x, y }, selectedScenery, gridPos, &quadrant, &primaryColour, &secondaryColour);
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
int32_t quantity = 1;
|
||||
bool isCluster = gWindowSceneryScatterEnabled
|
||||
&& (network_get_mode() != NETWORK_MODE_CLIENT
|
||||
|
@ -1785,7 +1837,7 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
for (int32_t q = 0; q < quantity; q++)
|
||||
{
|
||||
int32_t zCoordinate = gSceneryPlaceZ;
|
||||
rct_scenery_entry* scenery = get_small_scenery_entry((parameter_1 >> 8) & 0xFF);
|
||||
rct_scenery_entry* scenery = get_small_scenery_entry(selectedScenery);
|
||||
|
||||
int16_t cur_grid_x = gridPos.x;
|
||||
int16_t cur_grid_y = gridPos.y;
|
||||
|
@ -1794,8 +1846,7 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
{
|
||||
if (!scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_FULL_TILE))
|
||||
{
|
||||
parameter_2 &= 0xFF00;
|
||||
parameter_2 |= util_rand() & 3;
|
||||
quadrant = util_rand() & 3;
|
||||
}
|
||||
|
||||
int16_t grid_x_offset = (util_rand() % gWindowSceneryScatterSize) - (gWindowSceneryScatterSize / 2);
|
||||
|
@ -1820,17 +1871,13 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
zAttemptRange = 20;
|
||||
}
|
||||
|
||||
uint8_t quadrant = parameter_2 & 0xFF;
|
||||
uint8_t primaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
uint8_t secondaryColour = (parameter_3 >> 16) & 0xFF;
|
||||
uint8_t type = (parameter_1 >> 8) & 0xFF;
|
||||
auto success = GA_ERROR::UNKNOWN;
|
||||
// Try find a valid z coordinate
|
||||
for (; zAttemptRange != 0; zAttemptRange--)
|
||||
{
|
||||
auto smallSceneryPlaceAction = SmallSceneryPlaceAction(
|
||||
{ cur_grid_x, cur_grid_y, gSceneryPlaceZ, gSceneryPlaceRotation }, quadrant, type, primaryColour,
|
||||
secondaryColour);
|
||||
{ cur_grid_x, cur_grid_y, gSceneryPlaceZ, gSceneryPlaceRotation }, quadrant, selectedScenery,
|
||||
primaryColour, secondaryColour);
|
||||
auto res = GameActions::Query(&smallSceneryPlaceAction);
|
||||
success = res->Error;
|
||||
if (res->Error == GA_ERROR::OK)
|
||||
|
@ -1852,8 +1899,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
if (success == GA_ERROR::OK || ((q + 1 == quantity) && forceError))
|
||||
{
|
||||
auto smallSceneryPlaceAction = SmallSceneryPlaceAction(
|
||||
{ cur_grid_x, cur_grid_y, gSceneryPlaceZ, gSceneryPlaceRotation }, quadrant, type, primaryColour,
|
||||
secondaryColour);
|
||||
{ cur_grid_x, cur_grid_y, gSceneryPlaceZ, gSceneryPlaceRotation }, quadrant, selectedScenery,
|
||||
primaryColour, secondaryColour);
|
||||
|
||||
smallSceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
|
@ -1878,9 +1925,12 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
}
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
{
|
||||
auto pathItemType = parameter_3 & 0xFF;
|
||||
int32_t z = (parameter_2 & 0xFF) * COORDS_Z_STEP;
|
||||
auto footpathSceneryPlaceAction = FootpathSceneryPlaceAction({ gridPos, z }, pathItemType);
|
||||
int32_t z;
|
||||
sub_6E1F34_path_item({ x, y }, selectedScenery, gridPos, &z);
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
auto footpathSceneryPlaceAction = FootpathSceneryPlaceAction({ gridPos, z }, selectedScenery + 1);
|
||||
|
||||
footpathSceneryPlaceAction.SetCallback([](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
|
@ -1894,6 +1944,12 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
}
|
||||
case SCENERY_TYPE_WALL:
|
||||
{
|
||||
colour_t primaryColour;
|
||||
uint8_t edges;
|
||||
sub_6E1F34_wall({ x, y }, selectedScenery, gridPos, &primaryColour, &edges);
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
uint8_t zAttemptRange = 1;
|
||||
if (gSceneryPlaceZ != 0 && gSceneryShiftPressed)
|
||||
{
|
||||
|
@ -1902,11 +1958,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
|
||||
for (; zAttemptRange != 0; zAttemptRange--)
|
||||
{
|
||||
auto primaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto edges = parameter_2 & 0xFF;
|
||||
auto type = (parameter_1 >> 8) & 0xFF;
|
||||
auto wallPlaceAction = WallPlaceAction(
|
||||
type, { gridPos, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour);
|
||||
selectedScenery, { gridPos, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour);
|
||||
|
||||
auto res = GameActions::Query(&wallPlaceAction);
|
||||
if (res->Error == GA_ERROR::OK)
|
||||
|
@ -1925,11 +1978,8 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
}
|
||||
}
|
||||
|
||||
auto primaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto edges = parameter_2 & 0xFF;
|
||||
auto type = (parameter_1 >> 8) & 0xFF;
|
||||
auto wallPlaceAction = WallPlaceAction(
|
||||
type, { gridPos, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour);
|
||||
selectedScenery, { gridPos, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour);
|
||||
|
||||
wallPlaceAction.SetCallback([](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
|
@ -1942,6 +1992,13 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
}
|
||||
case SCENERY_TYPE_LARGE:
|
||||
{
|
||||
colour_t primaryColour;
|
||||
colour_t secondaryColour;
|
||||
Direction direction;
|
||||
sub_6E1F34_large_scenery({ x, y }, selectedScenery, gridPos, &primaryColour, &secondaryColour, &direction);
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
uint8_t zAttemptRange = 1;
|
||||
if (gSceneryPlaceZ != 0 && gSceneryShiftPressed)
|
||||
{
|
||||
|
@ -1950,13 +2007,9 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
|
||||
for (; zAttemptRange != 0; zAttemptRange--)
|
||||
{
|
||||
auto primaryColour = parameter_2 & 0xFF;
|
||||
auto secondaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto largeSceneryType = parameter_3 & 0xFF;
|
||||
uint8_t direction = (parameter_1 & 0xFF00) >> 8;
|
||||
CoordsXYZD loc = { gridPos, gSceneryPlaceZ, direction };
|
||||
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour);
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, selectedScenery, primaryColour, secondaryColour);
|
||||
|
||||
auto res = GameActions::Query(&sceneryPlaceAction);
|
||||
if (res->Error == GA_ERROR::OK)
|
||||
|
@ -1974,13 +2027,10 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
gSceneryPlaceZ += 8;
|
||||
}
|
||||
}
|
||||
auto primaryColour = parameter_2 & 0xFF;
|
||||
auto secondaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto largeSceneryType = parameter_3 & 0xFF;
|
||||
uint8_t direction = (parameter_1 & 0xFF00) >> 8;
|
||||
|
||||
CoordsXYZD loc = { gridPos, gSceneryPlaceZ, direction };
|
||||
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, largeSceneryType, primaryColour, secondaryColour);
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, selectedScenery, primaryColour, secondaryColour);
|
||||
sceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
{
|
||||
|
@ -1996,18 +2046,21 @@ static void window_top_toolbar_scenery_tool_down(int16_t x, int16_t y, rct_windo
|
|||
}
|
||||
case SCENERY_TYPE_BANNER:
|
||||
{
|
||||
uint8_t direction = (parameter_2 >> 8) & 0xFF;
|
||||
int32_t z = (parameter_2 & 0xFF) * 16;
|
||||
int32_t z;
|
||||
Direction direction;
|
||||
sub_6E1F34_banner({ x, y }, selectedScenery, gridPos, &z, &direction);
|
||||
if (gridPos.isNull())
|
||||
return;
|
||||
|
||||
CoordsXYZD loc{ gridPos, z, direction };
|
||||
auto primaryColour = gWindowSceneryPrimaryColour;
|
||||
auto bannerType = (parameter_1 & 0xFF00) >> 8;
|
||||
auto bannerIndex = create_new_banner(0);
|
||||
if (bannerIndex == BANNER_INDEX_NULL)
|
||||
{
|
||||
context_show_error(STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME);
|
||||
break;
|
||||
}
|
||||
auto bannerPlaceAction = BannerPlaceAction(loc, bannerType, bannerIndex, primaryColour);
|
||||
auto bannerPlaceAction = BannerPlaceAction(loc, selectedScenery, bannerIndex, primaryColour);
|
||||
bannerPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
{
|
||||
|
@ -2483,34 +2536,34 @@ static void top_toolbar_tool_update_water(int16_t x, int16_t y)
|
|||
* On success places ghost scenery and returns cost to place proper
|
||||
*/
|
||||
static money32 try_place_ghost_scenery(
|
||||
CoordsXY map_tile, uint32_t parameter_1, uint32_t parameter_2, uint32_t parameter_3, uint16_t selected_tab)
|
||||
CoordsXY map_tile, uint32_t parameter_1, uint32_t parameter_2, uint32_t parameter_3, uint8_t scenery_type,
|
||||
uint16_t entryIndex)
|
||||
{
|
||||
scenery_remove_ghost_tool_placement();
|
||||
|
||||
uint8_t scenery_type = (selected_tab & 0xFF00) >> 8;
|
||||
money32 cost = 0;
|
||||
TileElement* tileElement;
|
||||
|
||||
switch (scenery_type)
|
||||
{
|
||||
case 0:
|
||||
case SCENERY_TYPE_SMALL:
|
||||
{
|
||||
// Small Scenery
|
||||
// 6e252b
|
||||
uint8_t quadrant = parameter_2 & 0xFF;
|
||||
uint8_t primaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
uint8_t secondaryColour = (parameter_3 >> 16) & 0xFF;
|
||||
uint8_t type = (parameter_1 >> 8) & 0xFF;
|
||||
uint8_t rotation = parameter_3 & 0xFF;
|
||||
auto smallSceneryPlaceAction = SmallSceneryPlaceAction(
|
||||
{ map_tile.x, map_tile.y, gSceneryPlaceZ, rotation }, quadrant, type, primaryColour, secondaryColour);
|
||||
{ map_tile.x, map_tile.y, gSceneryPlaceZ, rotation }, quadrant, entryIndex, primaryColour, secondaryColour);
|
||||
smallSceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED);
|
||||
auto res = GameActions::Execute(&smallSceneryPlaceAction);
|
||||
if (res->Error != GA_ERROR::OK)
|
||||
return MONEY32_UNDEFINED;
|
||||
|
||||
gSceneryPlaceRotation = (uint16_t)(parameter_3 & 0xFF);
|
||||
gSceneryPlaceObject = selected_tab;
|
||||
gSceneryPlaceObject.SceneryType = SCENERY_TYPE_SMALL;
|
||||
gSceneryPlaceObject.EntryIndex = entryIndex;
|
||||
|
||||
tileElement = dynamic_cast<SmallSceneryPlaceActionResult*>(res.get())->tileElement;
|
||||
gSceneryGhostPosition = { map_tile, tileElement->GetBaseZ() };
|
||||
|
@ -2530,13 +2583,12 @@ static money32 try_place_ghost_scenery(
|
|||
cost = res->Cost;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
{
|
||||
// Path Bits
|
||||
// 6e265b
|
||||
auto pathItemType = parameter_3 & 0xFF;
|
||||
int32_t z = (parameter_2 & 0xFF) * COORDS_Z_STEP;
|
||||
auto footpathSceneryPlaceAction = FootpathSceneryPlaceAction({ map_tile.x, map_tile.y, z }, pathItemType);
|
||||
auto footpathSceneryPlaceAction = FootpathSceneryPlaceAction({ map_tile.x, map_tile.y, z }, entryIndex + 1);
|
||||
footpathSceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED);
|
||||
footpathSceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) {
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
|
@ -2553,15 +2605,15 @@ static money32 try_place_ghost_scenery(
|
|||
cost = res->Cost;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case SCENERY_TYPE_WALL:
|
||||
{
|
||||
// Walls
|
||||
// 6e26b0
|
||||
auto primaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto edges = parameter_2 & 0xFF;
|
||||
auto type = (parameter_1 >> 8) & 0xFF;
|
||||
auto wallPlaceAction = WallPlaceAction(
|
||||
type, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour, _tertiaryColour);
|
||||
entryIndex, { map_tile.x, map_tile.y, gSceneryPlaceZ }, edges, primaryColour, _secondaryColour,
|
||||
_tertiaryColour);
|
||||
wallPlaceAction.SetFlags(
|
||||
GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
|
||||
wallPlaceAction.SetCallback([=](const GameAction* ga, const WallPlaceActionResult* result) {
|
||||
|
@ -2580,17 +2632,16 @@ static money32 try_place_ghost_scenery(
|
|||
cost = res->Cost;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case SCENERY_TYPE_LARGE:
|
||||
{
|
||||
// Large Scenery
|
||||
// 6e25a7
|
||||
auto primaryColour = parameter_2 & 0xFF;
|
||||
auto secondaryColour = (parameter_2 >> 8) & 0xFF;
|
||||
auto sceneryType = parameter_3 & 0xFF;
|
||||
uint8_t direction = (parameter_1 & 0xFF00) >> 8;
|
||||
CoordsXYZD loc = { map_tile.x, map_tile.y, gSceneryPlaceZ, direction };
|
||||
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, sceneryType, primaryColour, secondaryColour);
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, entryIndex, primaryColour, secondaryColour);
|
||||
sceneryPlaceAction.SetFlags(
|
||||
GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
|
||||
auto res = GameActions::Execute(&sceneryPlaceAction);
|
||||
|
@ -2617,22 +2668,21 @@ static money32 try_place_ghost_scenery(
|
|||
cost = res->Cost;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
case SCENERY_TYPE_BANNER:
|
||||
{
|
||||
// Banners
|
||||
// 6e2612
|
||||
uint8_t direction = (parameter_2 >> 8) & 0xFF;
|
||||
int32_t z = (parameter_2 & 0xFF) * 16;
|
||||
int32_t z = (parameter_2 & 0xFF) * COORDS_Z_PER_TINY_Z;
|
||||
CoordsXYZD loc{ map_tile.x, map_tile.y, z, direction };
|
||||
auto primaryColour = gWindowSceneryPrimaryColour;
|
||||
auto bannerType = (parameter_1 & 0xFF00) >> 8;
|
||||
auto bannerIndex = create_new_banner(0);
|
||||
if (bannerIndex == BANNER_INDEX_NULL)
|
||||
{
|
||||
// Silently fail as this is just for the ghost
|
||||
break;
|
||||
}
|
||||
auto bannerPlaceAction = BannerPlaceAction(loc, bannerType, bannerIndex, primaryColour);
|
||||
auto bannerPlaceAction = BannerPlaceAction(loc, entryIndex, bannerIndex, primaryColour);
|
||||
bannerPlaceAction.SetFlags(
|
||||
GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
|
||||
auto res = GameActions::Execute(&bannerPlaceAction);
|
||||
|
@ -2673,20 +2723,20 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
if (gWindowSceneryEyedropperEnabled)
|
||||
return;
|
||||
|
||||
int16_t selected_tab = gWindowSceneryTabSelections[gWindowSceneryActiveTabIndex];
|
||||
ScenerySelection selection = gWindowSceneryTabSelections[gWindowSceneryActiveTabIndex];
|
||||
|
||||
if (selected_tab == -1)
|
||||
if (selection.IsUndefined())
|
||||
{
|
||||
scenery_remove_ghost_tool_placement();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t scenery_type = (selected_tab & 0xFF00) >> 8;
|
||||
uint8_t selected_scenery = selected_tab & 0xFF;
|
||||
uint8_t sceneryType = selection.SceneryType;
|
||||
uint16_t selectedScenery = selection.EntryIndex;
|
||||
CoordsXY mapTile = {};
|
||||
uint32_t parameter1, parameter2, parameter3;
|
||||
|
||||
sub_6E1F34(x, y, selected_tab, mapTile, ¶meter1, ¶meter2, ¶meter3);
|
||||
sub_6E1F34(x, y, selection, mapTile, ¶meter1, ¶meter2, ¶meter3);
|
||||
|
||||
if (mapTile.isNull())
|
||||
{
|
||||
|
@ -2698,7 +2748,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
uint8_t bl;
|
||||
money32 cost = 0;
|
||||
|
||||
switch (scenery_type)
|
||||
switch (sceneryType)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
|
||||
|
@ -2723,7 +2773,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
gMapSelectPositionB.y = mapTile.y;
|
||||
}
|
||||
|
||||
scenery = get_small_scenery_entry(selected_scenery);
|
||||
scenery = get_small_scenery_entry(selectedScenery);
|
||||
|
||||
gMapSelectType = MAP_SELECT_TYPE_FULL;
|
||||
if (!scenery_small_entry_has_flag(scenery, SMALL_SCENERY_FLAG_FULL_TILE) && !gWindowSceneryScatterEnabled)
|
||||
|
@ -2735,7 +2785,8 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
|
||||
// If no change in ghost placement
|
||||
if ((gSceneryGhostType & SCENERY_GHOST_FLAG_0) && mapTile == gSceneryGhostPosition
|
||||
&& (parameter2 & 0xFF) == _unkF64F0E && gSceneryPlaceZ == _unkF64F0A && gSceneryPlaceObject == selected_tab)
|
||||
&& (parameter2 & 0xFF) == _unkF64F0E && gSceneryPlaceZ == _unkF64F0A
|
||||
&& gSceneryPlaceObject.SceneryType == SCENERY_TYPE_SMALL && gSceneryPlaceObject.EntryIndex == selectedScenery)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2753,7 +2804,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
|
||||
for (; bl != 0; bl--)
|
||||
{
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, selected_tab);
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, sceneryType, selectedScenery);
|
||||
|
||||
if (cost != MONEY32_UNDEFINED)
|
||||
break;
|
||||
|
@ -2781,7 +2832,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
|
||||
scenery_remove_ghost_tool_placement();
|
||||
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, selected_tab);
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, sceneryType, selectedScenery);
|
||||
|
||||
gSceneryPlaceCost = cost;
|
||||
break;
|
||||
|
@ -2816,7 +2867,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
cost = 0;
|
||||
for (; bl != 0; bl--)
|
||||
{
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, selected_tab);
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, sceneryType, selectedScenery);
|
||||
|
||||
if (cost != MONEY32_UNDEFINED)
|
||||
break;
|
||||
|
@ -2827,7 +2878,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
break;
|
||||
case SCENERY_TYPE_LARGE:
|
||||
{
|
||||
scenery = get_large_scenery_entry(selected_scenery);
|
||||
scenery = get_large_scenery_entry(selectedScenery);
|
||||
gMapSelectionTiles.clear();
|
||||
|
||||
for (rct_large_scenery_tile* tile = scenery->large_scenery.tiles; tile->x_offset != (int16_t)(uint16_t)0xFFFF;
|
||||
|
@ -2847,14 +2898,15 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
|
||||
// If no change in ghost placement
|
||||
if ((gSceneryGhostType & SCENERY_GHOST_FLAG_3) && mapTile == gSceneryGhostPosition && gSceneryPlaceZ == _unkF64F0A
|
||||
&& (int16_t)(parameter3 & 0xFFFF) == gSceneryPlaceObject)
|
||||
&& gSceneryPlaceObject.SceneryType == SCENERY_TYPE_LARGE && gSceneryPlaceObject.EntryIndex == selectedScenery)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scenery_remove_ghost_tool_placement();
|
||||
|
||||
gSceneryPlaceObject = (parameter3 & 0xFFFF);
|
||||
gSceneryPlaceObject.SceneryType = SCENERY_TYPE_LARGE;
|
||||
gSceneryPlaceObject.EntryIndex = selectedScenery;
|
||||
_unkF64F0A = gSceneryPlaceZ;
|
||||
|
||||
bl = 1;
|
||||
|
@ -2866,7 +2918,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
cost = 0;
|
||||
for (; bl != 0; bl--)
|
||||
{
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, selected_tab);
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, sceneryType, selectedScenery);
|
||||
|
||||
if (cost != MONEY32_UNDEFINED)
|
||||
break;
|
||||
|
@ -2896,7 +2948,7 @@ static void top_toolbar_tool_update_scenery(int16_t x, int16_t y)
|
|||
|
||||
scenery_remove_ghost_tool_placement();
|
||||
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, selected_tab);
|
||||
cost = try_place_ghost_scenery(mapTile, parameter1, parameter2, parameter3, sceneryType, selectedScenery);
|
||||
|
||||
gSceneryPlaceCost = cost;
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,7 @@ struct TileElement;
|
|||
struct Vehicle;
|
||||
enum class ScatterToolDensity : uint8_t;
|
||||
|
||||
extern uint16_t gWindowSceneryTabSelections[];
|
||||
extern ScenerySelection gWindowSceneryTabSelections[];
|
||||
extern uint8_t gWindowSceneryActiveTabIndex;
|
||||
extern bool gWindowSceneryScatterEnabled;
|
||||
extern uint16_t gWindowSceneryScatterSize;
|
||||
|
@ -164,7 +164,7 @@ bool clear_scenery_tool_is_active();
|
|||
bool water_tool_is_active();
|
||||
|
||||
rct_window* window_scenery_open();
|
||||
bool window_scenery_set_selected_item(int32_t sceneryId);
|
||||
bool window_scenery_set_selected_item(const ScenerySelection& scenery);
|
||||
void window_scenery_set_default_placement_configuration();
|
||||
void window_scenery_init();
|
||||
void window_scenery_reset_selected_scenery_items();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../common.h"
|
||||
#include "../ride/RideTypes.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "../world/ScenerySelection.h"
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
@ -243,7 +244,7 @@ struct ride_variables
|
|||
|
||||
struct scenery_variables
|
||||
{
|
||||
uint16_t selected_scenery_id;
|
||||
ScenerySelection SelectedScenery;
|
||||
int16_t hover_counter;
|
||||
};
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ uint8_t gResearchUncompletedCategories;
|
|||
|
||||
static bool _researchedRideTypes[RIDE_TYPE_COUNT];
|
||||
static bool _researchedRideEntries[MAX_RIDE_OBJECTS];
|
||||
static bool _researchedSceneryItems[MAX_RESEARCHED_SCENERY_ITEMS];
|
||||
static bool _researchedSceneryItems[SCENERY_TYPE_COUNT][UINT16_MAX];
|
||||
|
||||
bool gSilentResearch = false;
|
||||
|
||||
|
@ -599,19 +599,21 @@ void ride_entry_set_invented(int32_t rideEntryIndex)
|
|||
_researchedRideEntries[rideEntryIndex] = true;
|
||||
}
|
||||
|
||||
bool scenery_is_invented(uint16_t sceneryItem)
|
||||
bool scenery_is_invented(const ScenerySelection& sceneryItem)
|
||||
{
|
||||
return _researchedSceneryItems[sceneryItem];
|
||||
return _researchedSceneryItems[sceneryItem.SceneryType][sceneryItem.EntryIndex];
|
||||
}
|
||||
|
||||
void scenery_set_invented(uint16_t sceneryItem)
|
||||
void scenery_set_invented(const ScenerySelection& sceneryItem)
|
||||
{
|
||||
_researchedSceneryItems[sceneryItem] = true;
|
||||
assert(sceneryItem.SceneryType < SCENERY_TYPE_COUNT);
|
||||
_researchedSceneryItems[sceneryItem.SceneryType][sceneryItem.EntryIndex] = true;
|
||||
}
|
||||
|
||||
void scenery_set_not_invented(uint16_t sceneryItem)
|
||||
void scenery_set_not_invented(const ScenerySelection& sceneryItem)
|
||||
{
|
||||
_researchedSceneryItems[sceneryItem] = false;
|
||||
assert(sceneryItem.SceneryType < SCENERY_TYPE_COUNT);
|
||||
_researchedSceneryItems[sceneryItem.SceneryType][sceneryItem.EntryIndex] = false;
|
||||
}
|
||||
|
||||
bool scenery_group_is_invented(int32_t sgIndex)
|
||||
|
@ -628,8 +630,8 @@ bool scenery_group_is_invented(int32_t sgIndex)
|
|||
{
|
||||
for (auto i = 0; i < sgEntry->entry_count; i++)
|
||||
{
|
||||
auto sceneryEntryIndex = sgEntry->scenery_entries[i];
|
||||
if (scenery_is_invented(sceneryEntryIndex))
|
||||
auto sceneryEntry = sgEntry->scenery_entries[i];
|
||||
if (scenery_is_invented(sceneryEntry))
|
||||
{
|
||||
invented = true;
|
||||
break;
|
||||
|
@ -672,12 +674,18 @@ void set_all_scenery_groups_not_invented()
|
|||
|
||||
void set_all_scenery_items_invented()
|
||||
{
|
||||
std::fill(std::begin(_researchedSceneryItems), std::end(_researchedSceneryItems), true);
|
||||
for (auto sceneryType = 0; sceneryType < SCENERY_TYPE_COUNT; sceneryType++)
|
||||
{
|
||||
std::fill(std::begin(_researchedSceneryItems[sceneryType]), std::end(_researchedSceneryItems[sceneryType]), true);
|
||||
}
|
||||
}
|
||||
|
||||
void set_all_scenery_items_not_invented()
|
||||
{
|
||||
std::fill(std::begin(_researchedSceneryItems), std::end(_researchedSceneryItems), false);
|
||||
for (auto sceneryType = 0; sceneryType < SCENERY_TYPE_COUNT; sceneryType++)
|
||||
{
|
||||
std::fill(std::begin(_researchedSceneryItems[sceneryType]), std::end(_researchedSceneryItems[sceneryType]), true);
|
||||
}
|
||||
}
|
||||
|
||||
void set_every_ride_type_invented()
|
||||
|
|
|
@ -63,8 +63,6 @@ enum
|
|||
#define RESEARCH_ITEM_NULL 0xFFFFFFFF
|
||||
|
||||
#define MAX_RESEARCH_ITEMS 500
|
||||
#define MAX_RESEARCHED_TRACK_TYPES 128
|
||||
#define MAX_RESEARCHED_SCENERY_ITEMS 1792
|
||||
|
||||
#define RESEARCH_ENTRY_RIDE_MASK 0x10000
|
||||
|
||||
|
@ -129,15 +127,15 @@ void research_insert_scenery_group_entry(uint8_t entryIndex, bool researched);
|
|||
|
||||
void ride_type_set_invented(uint32_t rideType);
|
||||
void ride_entry_set_invented(int32_t rideEntryIndex);
|
||||
void scenery_set_invented(uint16_t sceneryItem);
|
||||
void scenery_set_not_invented(uint16_t sceneryItem);
|
||||
void scenery_set_invented(const ScenerySelection& sceneryItem);
|
||||
void scenery_set_not_invented(const ScenerySelection& sceneryItem);
|
||||
bool ride_type_is_invented(uint32_t rideType);
|
||||
bool ride_entry_is_invented(int32_t rideEntryIndex);
|
||||
uint64_t get_available_track_pieces_for_ride_type(uint8_t rideType);
|
||||
bool track_piece_is_available_for_ride_type(uint8_t rideType, int32_t trackType);
|
||||
bool scenery_group_is_invented(int32_t sgIndex);
|
||||
void scenery_group_set_invented(int32_t sgIndex);
|
||||
bool scenery_is_invented(uint16_t sceneryItem);
|
||||
bool scenery_is_invented(const ScenerySelection& sceneryItem);
|
||||
void set_all_scenery_items_invented();
|
||||
void set_all_scenery_items_not_invented();
|
||||
void set_all_scenery_groups_not_invented();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../core/String.hpp"
|
||||
#include "../localisation/Language.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../world/Scenery.h"
|
||||
#include "ObjectLimits.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -168,6 +169,25 @@ std::string Object::GetName(int32_t language) const
|
|||
return GetString(language, OBJ_STRING_ID_NAME);
|
||||
}
|
||||
|
||||
std::optional<uint8_t> rct_object_entry::GetSceneryType() const
|
||||
{
|
||||
switch (GetType())
|
||||
{
|
||||
case OBJECT_TYPE_SMALL_SCENERY:
|
||||
return SCENERY_TYPE_SMALL;
|
||||
case OBJECT_TYPE_LARGE_SCENERY:
|
||||
return SCENERY_TYPE_LARGE;
|
||||
case OBJECT_TYPE_WALLS:
|
||||
return SCENERY_TYPE_WALL;
|
||||
case OBJECT_TYPE_BANNERS:
|
||||
return SCENERY_TYPE_BANNER;
|
||||
case OBJECT_TYPE_PATH_BITS:
|
||||
return SCENERY_TYPE_PATH_ITEM;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WARN_SUGGEST_FINAL_METHODS__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "ImageTable.h"
|
||||
#include "StringTable.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
|
@ -110,6 +111,8 @@ struct rct_object_entry
|
|||
{
|
||||
return flags & 0x0F;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> GetSceneryType() const;
|
||||
};
|
||||
assert_struct_size(rct_object_entry, 0x10);
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ void SceneryGroupObject::ReadLegacy(IReadObjectContext* context, IStream* stream
|
|||
stream->Seek(6, STREAM_SEEK_CURRENT);
|
||||
stream->Seek(0x80 * 2, STREAM_SEEK_CURRENT);
|
||||
_legacyType.entry_count = stream->ReadValue<uint8_t>();
|
||||
_legacyType.pad_107 = stream->ReadValue<uint8_t>();
|
||||
stream->Seek(1, STREAM_SEEK_CURRENT); // pad_107;
|
||||
_legacyType.priority = stream->ReadValue<uint8_t>();
|
||||
_legacyType.pad_109 = stream->ReadValue<uint8_t>();
|
||||
stream->Seek(1, STREAM_SEEK_CURRENT); // pad_109;
|
||||
_legacyType.entertainer_costumes = stream->ReadValue<uint32_t>();
|
||||
|
||||
GetStringTable().Read(context, stream, OBJ_STRING_ID_NAME);
|
||||
|
@ -82,33 +82,13 @@ void SceneryGroupObject::UpdateEntryIndexes()
|
|||
if (ori->LoadedObject == nullptr)
|
||||
continue;
|
||||
|
||||
uint16_t sceneryEntry = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject);
|
||||
Guard::Assert(sceneryEntry != UINT8_MAX, GUARD_LINE);
|
||||
uint16_t entryIndex = objectManager.GetLoadedObjectEntryIndex(ori->LoadedObject);
|
||||
Guard::Assert(entryIndex != UINT8_MAX, GUARD_LINE);
|
||||
|
||||
auto objectType = ori->ObjectEntry.GetType();
|
||||
switch (objectType)
|
||||
auto sceneryType = ori->ObjectEntry.GetSceneryType();
|
||||
if (sceneryType != std::nullopt)
|
||||
{
|
||||
case OBJECT_TYPE_SMALL_SCENERY:
|
||||
break;
|
||||
case OBJECT_TYPE_PATH_BITS:
|
||||
sceneryEntry += SCENERY_PATH_SCENERY_ID_MIN;
|
||||
break;
|
||||
case OBJECT_TYPE_WALLS:
|
||||
sceneryEntry += SCENERY_WALLS_ID_MIN;
|
||||
break;
|
||||
case OBJECT_TYPE_LARGE_SCENERY:
|
||||
sceneryEntry += SCENERY_LARGE_SCENERY_ID_MIN;
|
||||
break;
|
||||
case OBJECT_TYPE_BANNERS:
|
||||
sceneryEntry += SCENERY_BANNERS_ID_MIN;
|
||||
break;
|
||||
default:
|
||||
sceneryEntry = UINT16_MAX;
|
||||
break;
|
||||
}
|
||||
if (sceneryEntry != UINT16_MAX)
|
||||
{
|
||||
_legacyType.scenery_entries[_legacyType.entry_count] = sceneryEntry;
|
||||
_legacyType.scenery_entries[_legacyType.entry_count] = { *sceneryType, entryIndex };
|
||||
_legacyType.entry_count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -880,7 +880,9 @@ void S6Exporter::ExportResearchedSceneryItems()
|
|||
|
||||
for (uint16_t sceneryEntryIndex = 0; sceneryEntryIndex < RCT2_MAX_RESEARCHED_SCENERY_ITEMS; sceneryEntryIndex++)
|
||||
{
|
||||
if (scenery_is_invented(sceneryEntryIndex))
|
||||
ScenerySelection scenerySelection = { static_cast<uint8_t>((sceneryEntryIndex >> 8) & 0xFF),
|
||||
static_cast<uint16_t>(sceneryEntryIndex & 0xFF) };
|
||||
if (scenery_is_invented(scenerySelection))
|
||||
{
|
||||
int32_t quadIndex = sceneryEntryIndex >> 5;
|
||||
int32_t bitIndex = sceneryEntryIndex & 0x1F;
|
||||
|
|
|
@ -874,7 +874,17 @@ public:
|
|||
bool invented = (_s6.researched_scenery_items[quadIndex] & ((uint32_t)1 << bitIndex));
|
||||
|
||||
if (invented)
|
||||
scenery_set_invented(sceneryEntryIndex);
|
||||
{
|
||||
ScenerySelection scenerySelection = { static_cast<uint8_t>((sceneryEntryIndex >> 8) & 0xFF),
|
||||
static_cast<uint16_t>(sceneryEntryIndex & 0xFF) };
|
||||
|
||||
// SV6 has room for 8 types of scenery, and sometimes scenery of non-existing types 5 and 6 is marked as
|
||||
// "invented".
|
||||
if (scenerySelection.SceneryType < SCENERY_TYPE_COUNT)
|
||||
{
|
||||
scenery_set_invented(scenerySelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
uint8_t gSceneryQuadrant;
|
||||
|
||||
money32 gSceneryPlaceCost;
|
||||
int16_t gSceneryPlaceObject;
|
||||
ScenerySelection gSceneryPlaceObject;
|
||||
int16_t gSceneryPlaceZ;
|
||||
uint8_t gSceneryPlaceRotation;
|
||||
|
||||
|
@ -167,7 +167,8 @@ void scenery_remove_ghost_tool_placement()
|
|||
{
|
||||
gSceneryGhostType &= ~SCENERY_GHOST_FLAG_0;
|
||||
|
||||
auto removeSceneryAction = SmallSceneryRemoveAction(gSceneryGhostPosition, gSceneryQuadrant, gSceneryPlaceObject);
|
||||
auto removeSceneryAction = SmallSceneryRemoveAction(
|
||||
gSceneryGhostPosition, gSceneryQuadrant, gSceneryPlaceObject.EntryIndex);
|
||||
removeSceneryAction.SetFlags(
|
||||
GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST);
|
||||
removeSceneryAction.Execute();
|
||||
|
@ -276,25 +277,6 @@ rct_scenery_group_entry* get_scenery_group_entry(int32_t entryIndex)
|
|||
return result;
|
||||
}
|
||||
|
||||
int32_t get_scenery_id_from_entry_index(uint8_t objectType, int32_t entryIndex)
|
||||
{
|
||||
switch (objectType)
|
||||
{
|
||||
case OBJECT_TYPE_SMALL_SCENERY:
|
||||
return entryIndex + SCENERY_SMALL_SCENERY_ID_MIN;
|
||||
case OBJECT_TYPE_PATH_BITS:
|
||||
return entryIndex + SCENERY_PATH_SCENERY_ID_MIN;
|
||||
case OBJECT_TYPE_WALLS:
|
||||
return entryIndex + SCENERY_WALLS_ID_MIN;
|
||||
case OBJECT_TYPE_LARGE_SCENERY:
|
||||
return entryIndex + SCENERY_LARGE_SCENERY_ID_MIN;
|
||||
case OBJECT_TYPE_BANNERS:
|
||||
return entryIndex + SCENERY_BANNERS_ID_MIN;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t wall_entry_get_door_sound(const rct_scenery_entry* wallEntry)
|
||||
{
|
||||
return (wallEntry->wall.flags2 & WALL_SCENERY_2_DOOR_SOUND_MASK) >> WALL_SCENERY_2_DOOR_SOUND_SHIFT;
|
||||
|
|
|
@ -11,24 +11,12 @@
|
|||
#define _SCENERY_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "../object/Object.h"
|
||||
#include "../object/ObjectLimits.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "../world/ScenerySelection.h"
|
||||
#include "TileElement.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
constexpr const uint16_t SCENERY_SMALL_SCENERY_ID_MIN = 0;
|
||||
constexpr const uint16_t SCENERY_SMALL_SCENERY_ID_MAX = MAX_SMALL_SCENERY_OBJECTS - 1;
|
||||
constexpr const uint16_t SCENERY_PATH_SCENERY_ID_MIN = 0x100;
|
||||
constexpr const uint16_t SCENERY_PATH_SCENERY_ID_MAX = SCENERY_PATH_SCENERY_ID_MIN + MAX_PATH_ADDITION_OBJECTS - 1;
|
||||
constexpr const uint16_t SCENERY_WALLS_ID_MIN = 0x200;
|
||||
constexpr const uint16_t SCENERY_WALLS_ID_MAX = SCENERY_WALLS_ID_MIN + MAX_WALL_SCENERY_OBJECTS - 1;
|
||||
constexpr const uint16_t SCENERY_LARGE_SCENERY_ID_MIN = 0x300;
|
||||
constexpr const uint16_t SCENERY_LARGE_SCENERY_ID_MAX = SCENERY_LARGE_SCENERY_ID_MIN + MAX_LARGE_SCENERY_OBJECTS - 1;
|
||||
constexpr const uint16_t SCENERY_BANNERS_ID_MIN = 0x400;
|
||||
constexpr const uint16_t SCENERY_BANNERS_ID_MAX = SCENERY_BANNERS_ID_MIN + MAX_BANNER_OBJECTS - 1;
|
||||
|
||||
#define SCENERY_WITHER_AGE_THRESHOLD_1 0x28
|
||||
#define SCENERY_WITHER_AGE_THRESHOLD_2 0x37
|
||||
|
||||
|
@ -187,19 +175,17 @@ struct rct_scenery_entry
|
|||
assert_struct_size(rct_scenery_entry, 6 + 21);
|
||||
#endif
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct rct_scenery_group_entry
|
||||
{
|
||||
rct_string_id name; // 0x00
|
||||
uint32_t image; // 0x02
|
||||
uint16_t scenery_entries[0x80]; // 0x06
|
||||
uint8_t entry_count; // 0x106
|
||||
uint8_t pad_107;
|
||||
uint8_t priority; // 0x108
|
||||
uint8_t pad_109;
|
||||
uint32_t entertainer_costumes; // 0x10A
|
||||
rct_string_id name;
|
||||
uint32_t image;
|
||||
ScenerySelection scenery_entries[0x80];
|
||||
uint8_t entry_count;
|
||||
uint8_t priority;
|
||||
uint32_t entertainer_costumes;
|
||||
};
|
||||
assert_struct_size(rct_scenery_group_entry, 14 + 2 * 0x80);
|
||||
#pragma pack(pop)
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -228,7 +214,9 @@ enum
|
|||
SCENERY_TYPE_PATH_ITEM,
|
||||
SCENERY_TYPE_WALL,
|
||||
SCENERY_TYPE_LARGE,
|
||||
SCENERY_TYPE_BANNER
|
||||
SCENERY_TYPE_BANNER,
|
||||
|
||||
SCENERY_TYPE_COUNT,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -252,13 +240,11 @@ enum class ScatterToolDensity : uint8_t
|
|||
HighDensity
|
||||
};
|
||||
|
||||
#define SCENERY_ENTRIES_BY_TAB 1024
|
||||
constexpr auto WINDOW_SCENERY_TAB_SELECTION_UNDEFINED = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
extern uint8_t gSceneryQuadrant;
|
||||
|
||||
extern money32 gSceneryPlaceCost;
|
||||
extern int16_t gSceneryPlaceObject;
|
||||
extern ScenerySelection gSceneryPlaceObject;
|
||||
extern uint16_t gSceneryPlaceObjectEntryIndex;
|
||||
extern int16_t gSceneryPlaceZ;
|
||||
extern uint8_t gSceneryPlaceRotation;
|
||||
|
||||
|
@ -288,7 +274,6 @@ rct_scenery_entry* get_banner_entry(int32_t entryIndex);
|
|||
rct_scenery_entry* get_footpath_item_entry(int32_t entryIndex);
|
||||
rct_scenery_group_entry* get_scenery_group_entry(int32_t entryIndex);
|
||||
|
||||
int32_t get_scenery_id_from_entry_index(uint8_t objectType, int32_t entryIndex);
|
||||
int32_t wall_entry_get_door_sound(const rct_scenery_entry* wallEntry);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2020 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 <cstdint>
|
||||
#include <limits>
|
||||
|
||||
constexpr auto WINDOW_SCENERY_TAB_SELECTION_UNDEFINED = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
struct ScenerySelection
|
||||
{
|
||||
uint8_t SceneryType;
|
||||
uint16_t EntryIndex;
|
||||
|
||||
inline bool operator==(const ScenerySelection& rhs)
|
||||
{
|
||||
return SceneryType == rhs.SceneryType && EntryIndex == rhs.EntryIndex;
|
||||
}
|
||||
|
||||
bool IsUndefined() const
|
||||
{
|
||||
return EntryIndex == WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
}
|
||||
|
||||
void SetUndefined()
|
||||
{
|
||||
EntryIndex = WINDOW_SCENERY_TAB_SELECTION_UNDEFINED;
|
||||
}
|
||||
|
||||
static ScenerySelection CreateUndefined()
|
||||
{
|
||||
return ScenerySelection{ 0, WINDOW_SCENERY_TAB_SELECTION_UNDEFINED };
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue