mirror of https://github.com/OpenRCT2/OpenRCT2.git
Implement #6292: Allow building queue lines in the the Scenario Editor
Also format the file properly and do a bit of clean up. It's now also possible to build queue lines for editor-only paths.
This commit is contained in:
parent
4e3a38b25d
commit
18db4a5274
|
@ -4,6 +4,7 @@
|
||||||
- Feature: [#6078] Game now converts mp.dat to SC21.SC4 (Mega Park) automatically.
|
- Feature: [#6078] Game now converts mp.dat to SC21.SC4 (Mega Park) automatically.
|
||||||
- Feature: [#6181] Map generator now allows adjusting random terrain and tree placement in Simplex Noise tab.
|
- Feature: [#6181] Map generator now allows adjusting random terrain and tree placement in Simplex Noise tab.
|
||||||
- Feature: [#6235] Add drawing debug option for showing visuals when and where blocks of the screen are painted.
|
- Feature: [#6235] Add drawing debug option for showing visuals when and where blocks of the screen are painted.
|
||||||
|
- Feature: [#6292] Allow building queue lines in the Scenario Editor.
|
||||||
- Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug).
|
- Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug).
|
||||||
- Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug).
|
- Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug).
|
||||||
- Fix: [#4991] Inverted helices can be built on the Lay Down RC, but are not drawn
|
- Fix: [#4991] Inverted helices can be built on the Lay Down RC, but are not drawn
|
||||||
|
|
|
@ -24,22 +24,26 @@
|
||||||
#include <openrct2/interface/viewport.h>
|
#include <openrct2/interface/viewport.h>
|
||||||
#include <openrct2/interface/widget.h>
|
#include <openrct2/interface/widget.h>
|
||||||
#include <openrct2/localisation/localisation.h>
|
#include <openrct2/localisation/localisation.h>
|
||||||
|
#include <openrct2/object_list.h>
|
||||||
#include <openrct2/sprites.h>
|
#include <openrct2/sprites.h>
|
||||||
#include <openrct2/world/footpath.h>
|
#include <openrct2/world/footpath.h>
|
||||||
#include <openrct2/windows/dropdown.h>
|
#include <openrct2/windows/dropdown.h>
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
PATH_CONSTRUCTION_MODE_LAND,
|
PATH_CONSTRUCTION_MODE_LAND,
|
||||||
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL,
|
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL,
|
||||||
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL
|
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
SELECTED_PATH_TYPE_NORMAL,
|
SELECTED_PATH_TYPE_NORMAL,
|
||||||
SELECTED_PATH_TYPE_QUEUE
|
SELECTED_PATH_TYPE_QUEUE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WINDOW_FOOTPATH_WIDGET_IDX {
|
enum WINDOW_FOOTPATH_WIDGET_IDX
|
||||||
|
{
|
||||||
WIDX_BACKGROUND,
|
WIDX_BACKGROUND,
|
||||||
WIDX_TITLE,
|
WIDX_TITLE,
|
||||||
WIDX_CLOSE,
|
WIDX_CLOSE,
|
||||||
|
@ -98,15 +102,25 @@ static rct_widget window_footpath_widgets[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void window_footpath_close(rct_window * w);
|
static void window_footpath_close(rct_window * w);
|
||||||
|
|
||||||
static void window_footpath_mouseup(rct_window * w, rct_widgetindex widgetIndex);
|
static void window_footpath_mouseup(rct_window * w, rct_widgetindex widgetIndex);
|
||||||
|
|
||||||
static void window_footpath_mousedown(rct_window * w, rct_widgetindex widgetIndex, rct_widget * widget);
|
static void window_footpath_mousedown(rct_window * w, rct_widgetindex widgetIndex, rct_widget * widget);
|
||||||
|
|
||||||
static void window_footpath_dropdown(rct_window * w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
static void window_footpath_dropdown(rct_window * w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
||||||
|
|
||||||
static void window_footpath_update(rct_window * w);
|
static void window_footpath_update(rct_window * w);
|
||||||
|
|
||||||
static void window_footpath_toolupdate(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
static void window_footpath_toolupdate(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_tooldown(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
static void window_footpath_tooldown(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_tooldrag(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
static void window_footpath_tooldrag(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_toolup(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
static void window_footpath_toolup(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_invalidate(rct_window * w);
|
static void window_footpath_invalidate(rct_window * w);
|
||||||
|
|
||||||
static void window_footpath_paint(rct_window * w, rct_drawpixelinfo * dpi);
|
static void window_footpath_paint(rct_window * w, rct_drawpixelinfo * dpi);
|
||||||
|
|
||||||
static rct_window_event_list window_footpath_events = {
|
static rct_window_event_list window_footpath_events = {
|
||||||
|
@ -196,16 +210,27 @@ static uint8 footpath_construction_preview_images[][4] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void window_footpath_mousedown_direction(sint32 direction);
|
static void window_footpath_mousedown_direction(sint32 direction);
|
||||||
|
|
||||||
static void window_footpath_mousedown_slope(sint32 slope);
|
static void window_footpath_mousedown_slope(sint32 slope);
|
||||||
static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, sint32 showQueues);
|
|
||||||
|
static void window_footpath_show_footpath_types_dialog(rct_window * w, rct_widget * widget, bool showQueues);
|
||||||
|
|
||||||
static void window_footpath_set_provisional_path_at_point(sint32 x, sint32 y);
|
static void window_footpath_set_provisional_path_at_point(sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_set_selection_start_bridge_at_point(sint32 screenX, sint32 screenY);
|
static void window_footpath_set_selection_start_bridge_at_point(sint32 screenX, sint32 screenY);
|
||||||
|
|
||||||
static void window_footpath_place_path_at_point(sint32 x, sint32 y);
|
static void window_footpath_place_path_at_point(sint32 x, sint32 y);
|
||||||
|
|
||||||
static void window_footpath_start_bridge_at_point(sint32 screenX, sint32 screenY);
|
static void window_footpath_start_bridge_at_point(sint32 screenX, sint32 screenY);
|
||||||
|
|
||||||
static void window_footpath_construct();
|
static void window_footpath_construct();
|
||||||
|
|
||||||
static void window_footpath_remove();
|
static void window_footpath_remove();
|
||||||
|
|
||||||
static void window_footpath_set_enabled_and_pressed_widgets();
|
static void window_footpath_set_enabled_and_pressed_widgets();
|
||||||
|
|
||||||
static void footpath_get_next_path_info(sint32 * type, sint32 * x, sint32 * y, sint32 * z, sint32 * slope);
|
static void footpath_get_next_path_info(sint32 * type, sint32 * x, sint32 * y, sint32 * z, sint32 * slope);
|
||||||
|
|
||||||
static bool footpath_select_default();
|
static bool footpath_select_default();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -216,13 +241,17 @@ rct_window * window_footpath_open()
|
||||||
{
|
{
|
||||||
// If a restricted path was selected when the game is no longer in Sandbox mode, reset it
|
// If a restricted path was selected when the game is no longer in Sandbox mode, reset it
|
||||||
rct_footpath_entry * pathEntry = get_footpath_entry(gFootpathSelectedId);
|
rct_footpath_entry * pathEntry = get_footpath_entry(gFootpathSelectedId);
|
||||||
if (pathEntry != (rct_footpath_entry*)-1 && (pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !gCheatsSandboxMode) {
|
if (pathEntry != (rct_footpath_entry *) -1 &&
|
||||||
|
(pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !gCheatsSandboxMode)
|
||||||
|
{
|
||||||
pathEntry = (rct_footpath_entry *) -1;
|
pathEntry = (rct_footpath_entry *) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select the default path if we don't have one
|
// Select the default path if we don't have one
|
||||||
if (pathEntry == (rct_footpath_entry*)-1) {
|
if (pathEntry == (rct_footpath_entry *) -1)
|
||||||
if (!footpath_select_default()) {
|
{
|
||||||
|
if (!footpath_select_default())
|
||||||
|
{
|
||||||
// No path objects to select from, don't open window
|
// No path objects to select from, don't open window
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +260,9 @@ rct_window * window_footpath_open()
|
||||||
// Check if window is already open
|
// Check if window is already open
|
||||||
rct_window * window = window_bring_to_front_by_class(WC_FOOTPATH);
|
rct_window * window = window_bring_to_front_by_class(WC_FOOTPATH);
|
||||||
if (window != nullptr)
|
if (window != nullptr)
|
||||||
|
{
|
||||||
return window;
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
window = window_create(
|
window = window_create(
|
||||||
0,
|
0,
|
||||||
|
@ -293,7 +324,8 @@ static void window_footpath_close(rct_window *w)
|
||||||
*/
|
*/
|
||||||
static void window_footpath_mouseup(rct_window * w, rct_widgetindex widgetIndex)
|
static void window_footpath_mouseup(rct_window * w, rct_widgetindex widgetIndex)
|
||||||
{
|
{
|
||||||
switch (widgetIndex) {
|
switch (widgetIndex)
|
||||||
|
{
|
||||||
case WIDX_CLOSE:
|
case WIDX_CLOSE:
|
||||||
window_close(w);
|
window_close(w);
|
||||||
break;
|
break;
|
||||||
|
@ -305,7 +337,9 @@ static void window_footpath_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||||
break;
|
break;
|
||||||
case WIDX_CONSTRUCT_ON_LAND:
|
case WIDX_CONSTRUCT_ON_LAND:
|
||||||
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND)
|
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
_window_footpath_cost = MONEY32_UNDEFINED;
|
_window_footpath_cost = MONEY32_UNDEFINED;
|
||||||
tool_cancel();
|
tool_cancel();
|
||||||
|
@ -320,7 +354,9 @@ static void window_footpath_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||||
break;
|
break;
|
||||||
case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL:
|
case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL:
|
||||||
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL)
|
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
_window_footpath_cost = MONEY32_UNDEFINED;
|
_window_footpath_cost = MONEY32_UNDEFINED;
|
||||||
tool_cancel();
|
tool_cancel();
|
||||||
|
@ -342,12 +378,13 @@ static void window_footpath_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||||
*/
|
*/
|
||||||
static void window_footpath_mousedown(rct_window * w, rct_widgetindex widgetIndex, rct_widget * widget)
|
static void window_footpath_mousedown(rct_window * w, rct_widgetindex widgetIndex, rct_widget * widget)
|
||||||
{
|
{
|
||||||
switch (widgetIndex) {
|
switch (widgetIndex)
|
||||||
|
{
|
||||||
case WIDX_FOOTPATH_TYPE:
|
case WIDX_FOOTPATH_TYPE:
|
||||||
window_footpath_show_footpath_types_dialog(w, widget, 0);
|
window_footpath_show_footpath_types_dialog(w, widget, false);
|
||||||
break;
|
break;
|
||||||
case WIDX_QUEUELINE_TYPE:
|
case WIDX_QUEUELINE_TYPE:
|
||||||
window_footpath_show_footpath_types_dialog(w, widget, 1);
|
window_footpath_show_footpath_types_dialog(w, widget, true);
|
||||||
break;
|
break;
|
||||||
case WIDX_DIRECTION_NW:
|
case WIDX_DIRECTION_NW:
|
||||||
window_footpath_mousedown_direction(0);
|
window_footpath_mousedown_direction(0);
|
||||||
|
@ -380,34 +417,45 @@ static void window_footpath_mousedown(rct_window *w, rct_widgetindex widgetIndex
|
||||||
static void window_footpath_dropdown(rct_window * w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
static void window_footpath_dropdown(rct_window * w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
||||||
{
|
{
|
||||||
if (widgetIndex == WIDX_FOOTPATH_TYPE)
|
if (widgetIndex == WIDX_FOOTPATH_TYPE)
|
||||||
|
{
|
||||||
gFootpathSelectedType = SELECTED_PATH_TYPE_NORMAL;
|
gFootpathSelectedType = SELECTED_PATH_TYPE_NORMAL;
|
||||||
|
}
|
||||||
else if (widgetIndex == WIDX_QUEUELINE_TYPE)
|
else if (widgetIndex == WIDX_QUEUELINE_TYPE)
|
||||||
|
{
|
||||||
gFootpathSelectedType = SELECTED_PATH_TYPE_QUEUE;
|
gFootpathSelectedType = SELECTED_PATH_TYPE_QUEUE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get path id
|
// Get path id
|
||||||
sint32 pathId = dropdownIndex;
|
sint32 pathId = dropdownIndex;
|
||||||
if (pathId == -1) {
|
if (pathId == -1)
|
||||||
|
{
|
||||||
pathId = gFootpathSelectedId;
|
pathId = gFootpathSelectedId;
|
||||||
} else {
|
}
|
||||||
sint32 flags = 4;
|
else
|
||||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode)
|
{
|
||||||
flags = 0;
|
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
|
||||||
|
|
||||||
sint32 i = 0, j = 0;
|
sint32 i = 0, j = 0;
|
||||||
for (; i < 16; i++) {
|
for (; i < MAX_PATH_OBJECTS; i++)
|
||||||
|
{
|
||||||
rct_footpath_entry * pathType = get_footpath_entry(i);
|
rct_footpath_entry * pathType = get_footpath_entry(i);
|
||||||
if (pathType == (rct_footpath_entry *) -1)
|
if (pathType == (rct_footpath_entry *) -1)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
if (pathType->flags & flags)
|
}
|
||||||
continue;
|
if ((pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !showEditorPaths)
|
||||||
// Skip queue lines of scenario editor-only paths (only applicable when the game is in sandbox mode)
|
{
|
||||||
if(widgetIndex == WIDX_QUEUELINE_TYPE && (pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (j == pathId)
|
if (j == pathId)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
pathId = i;
|
pathId = i;
|
||||||
|
@ -426,9 +474,12 @@ static void window_footpath_dropdown(rct_window *w, rct_widgetindex widgetIndex,
|
||||||
*/
|
*/
|
||||||
static void window_footpath_toolupdate(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
static void window_footpath_toolupdate(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||||
{
|
{
|
||||||
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
|
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
|
||||||
|
{
|
||||||
window_footpath_set_provisional_path_at_point(x, y);
|
window_footpath_set_provisional_path_at_point(x, y);
|
||||||
} else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) {
|
}
|
||||||
|
else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
window_footpath_set_selection_start_bridge_at_point(x, y);
|
window_footpath_set_selection_start_bridge_at_point(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,10 +491,14 @@ static void window_footpath_toolupdate(rct_window* w, rct_widgetindex widgetInde
|
||||||
static void window_footpath_tooldown(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
static void window_footpath_tooldown(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||||
{
|
{
|
||||||
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
|
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
|
||||||
|
{
|
||||||
window_footpath_place_path_at_point(x, y);
|
window_footpath_place_path_at_point(x, y);
|
||||||
|
}
|
||||||
else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
|
else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
window_footpath_start_bridge_at_point(x, y);
|
window_footpath_start_bridge_at_point(x, y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -451,7 +506,8 @@ static void window_footpath_tooldown(rct_window* w, rct_widgetindex widgetIndex,
|
||||||
*/
|
*/
|
||||||
static void window_footpath_tooldrag(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
static void window_footpath_tooldrag(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||||
{
|
{
|
||||||
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
|
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
|
||||||
|
{
|
||||||
window_footpath_place_path_at_point(x, y);
|
window_footpath_place_path_at_point(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -462,7 +518,8 @@ static void window_footpath_tooldrag(rct_window* w, rct_widgetindex widgetIndex,
|
||||||
*/
|
*/
|
||||||
static void window_footpath_toolup(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
static void window_footpath_toolup(rct_window * w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||||
{
|
{
|
||||||
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
|
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
|
||||||
|
{
|
||||||
_footpathErrorOccured = false;
|
_footpathErrorOccured = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,23 +533,28 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window *
|
||||||
sint32 type, x, y, z, slope;
|
sint32 type, x, y, z, slope;
|
||||||
|
|
||||||
if (gFootpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
|
if (gFootpathConstructionMode != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Recheck area for construction. Set by ride_construction window
|
// Recheck area for construction. Set by ride_construction window
|
||||||
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_2) {
|
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_2)
|
||||||
|
{
|
||||||
footpath_provisional_remove();
|
footpath_provisional_remove();
|
||||||
gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_2;
|
gFootpathProvisionalFlags &= ~PROVISIONAL_PATH_FLAG_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update provisional bridge mode path
|
// Update provisional bridge mode path
|
||||||
if (!(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1)) {
|
if (!(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1))
|
||||||
|
{
|
||||||
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
||||||
_window_footpath_cost = footpath_provisional_set(type, x, y, z, slope);
|
_window_footpath_cost = footpath_provisional_set(type, x, y, z, slope);
|
||||||
widget_invalidate(w, WIDX_CONSTRUCT);
|
widget_invalidate(w, WIDX_CONSTRUCT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update little directional arrow on provisional bridge mode path
|
// Update little directional arrow on provisional bridge mode path
|
||||||
if (--_window_footpath_provisional_path_arrow_timer < 0) {
|
if (--_window_footpath_provisional_path_arrow_timer < 0)
|
||||||
|
{
|
||||||
_window_footpath_provisional_path_arrow_timer = 5;
|
_window_footpath_provisional_path_arrow_timer = 5;
|
||||||
gFootpathProvisionalFlags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW;
|
gFootpathProvisionalFlags ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW;
|
||||||
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
||||||
|
@ -501,9 +563,13 @@ static void window_footpath_update_provisional_path_for_bridge_mode(rct_window *
|
||||||
gMapSelectArrowPosition.z = z * 8;
|
gMapSelectArrowPosition.z = z * 8;
|
||||||
gMapSelectArrowDirection = gFootpathConstructDirection;
|
gMapSelectArrowDirection = gFootpathConstructDirection;
|
||||||
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW)
|
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_SHOW_ARROW)
|
||||||
|
{
|
||||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW;
|
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
|
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
|
||||||
|
}
|
||||||
map_invalidate_tile_full(x, y);
|
map_invalidate_tile_full(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,28 +585,44 @@ static void window_footpath_update(rct_window *w)
|
||||||
|
|
||||||
// #2502: The camera might have changed rotation, so we need to update which directional buttons are pressed
|
// #2502: The camera might have changed rotation, so we need to update which directional buttons are pressed
|
||||||
uint8 currentRotation = get_current_rotation();
|
uint8 currentRotation = get_current_rotation();
|
||||||
if (_lastUpdatedCameraRotation != currentRotation) {
|
if (_lastUpdatedCameraRotation != currentRotation)
|
||||||
|
{
|
||||||
_lastUpdatedCameraRotation = currentRotation;
|
_lastUpdatedCameraRotation = currentRotation;
|
||||||
window_footpath_set_enabled_and_pressed_widgets();
|
window_footpath_set_enabled_and_pressed_widgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check tool
|
// Check tool
|
||||||
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND) {
|
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_LAND)
|
||||||
|
{
|
||||||
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
|
}
|
||||||
else if (gCurrentToolWidget.window_classification != WC_FOOTPATH)
|
else if (gCurrentToolWidget.window_classification != WC_FOOTPATH)
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
|
}
|
||||||
else if (gCurrentToolWidget.widget_index != WIDX_CONSTRUCT_ON_LAND)
|
else if (gCurrentToolWidget.widget_index != WIDX_CONSTRUCT_ON_LAND)
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
} else if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) {
|
}
|
||||||
|
}
|
||||||
|
else if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL)
|
||||||
|
{
|
||||||
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
|
}
|
||||||
else if (gCurrentToolWidget.window_classification != WC_FOOTPATH)
|
else if (gCurrentToolWidget.window_classification != WC_FOOTPATH)
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
|
}
|
||||||
else if (gCurrentToolWidget.widget_index != WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
|
else if (gCurrentToolWidget.widget_index != WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
window_close(w);
|
window_close(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -569,19 +651,10 @@ static void window_footpath_invalidate(rct_window *w)
|
||||||
|
|
||||||
// TODO: Should probably add constants for object sprites
|
// TODO: Should probably add constants for object sprites
|
||||||
sint32 pathImage = 71 + pathType->image;
|
sint32 pathImage = 71 + pathType->image;
|
||||||
|
// Editor-only paths might lack a queue image
|
||||||
|
sint32 queueImage = (pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) ? pathImage : pathImage + 1;
|
||||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||||
|
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
|
||||||
// Disable queue line button when the path is scenario editor-only (and therefore usually shouldn't have one)
|
|
||||||
if(!(pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) {
|
|
||||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = pathImage + 1;
|
|
||||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_FLATBTN;
|
|
||||||
} else {
|
|
||||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable queue line button if in Scenario Editor
|
|
||||||
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
|
|
||||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_EMPTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -592,24 +665,32 @@ static void window_footpath_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||||
{
|
{
|
||||||
window_draw_widgets(w, dpi);
|
window_draw_widgets(w, dpi);
|
||||||
|
|
||||||
if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT))) {
|
if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT)))
|
||||||
|
{
|
||||||
// Get construction image
|
// Get construction image
|
||||||
uint8 direction = (gFootpathConstructDirection + get_current_rotation()) % 4;
|
uint8 direction = (gFootpathConstructDirection + get_current_rotation()) % 4;
|
||||||
uint8 slope = 0;
|
uint8 slope = 0;
|
||||||
if (gFootpathConstructSlope == 2)
|
if (gFootpathConstructSlope == 2)
|
||||||
|
{
|
||||||
slope = 1;
|
slope = 1;
|
||||||
|
}
|
||||||
else if (gFootpathConstructSlope == 6)
|
else if (gFootpathConstructSlope == 6)
|
||||||
|
{
|
||||||
slope = 2;
|
slope = 2;
|
||||||
|
}
|
||||||
sint32 image = footpath_construction_preview_images[slope][direction];
|
sint32 image = footpath_construction_preview_images[slope][direction];
|
||||||
|
|
||||||
sint32 selectedPath = gFootpathSelectedId;
|
sint32 selectedPath = gFootpathSelectedId;
|
||||||
rct_footpath_entry * pathType = get_footpath_entry(selectedPath);
|
rct_footpath_entry * pathType = get_footpath_entry(selectedPath);
|
||||||
image += pathType->image;
|
image += pathType->image;
|
||||||
if (gFootpathSelectedType != SELECTED_PATH_TYPE_NORMAL)
|
if (gFootpathSelectedType != SELECTED_PATH_TYPE_NORMAL)
|
||||||
|
{
|
||||||
image += 51;
|
image += 51;
|
||||||
|
}
|
||||||
|
|
||||||
// Draw construction image
|
// Draw construction image
|
||||||
sint32 x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
|
sint32 x = w->x +
|
||||||
|
(window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
|
||||||
sint32 y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 60;
|
sint32 y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 60;
|
||||||
gfx_draw_sprite(dpi, image, x, y, 0);
|
gfx_draw_sprite(dpi, image, x, y, 0);
|
||||||
|
|
||||||
|
@ -620,38 +701,49 @@ static void window_footpath_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw cost
|
// Draw cost
|
||||||
sint32 x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
|
sint32 x = w->x +
|
||||||
|
(window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2;
|
||||||
sint32 y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12;
|
sint32 y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12;
|
||||||
if (_window_footpath_cost != MONEY32_UNDEFINED)
|
if (_window_footpath_cost != MONEY32_UNDEFINED)
|
||||||
|
{
|
||||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
||||||
|
{
|
||||||
gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, COLOUR_BLACK, &_window_footpath_cost);
|
gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, COLOUR_BLACK, &_window_footpath_cost);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x006A7F88
|
* rct2: 0x006A7F88
|
||||||
*/
|
*/
|
||||||
static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, sint32 showQueues)
|
static void window_footpath_show_footpath_types_dialog(rct_window * w, rct_widget * widget, bool showQueues)
|
||||||
{
|
{
|
||||||
sint32 i, flags, numPathTypes, image;
|
sint32 i, numPathTypes, image;
|
||||||
rct_footpath_entry * pathType;
|
rct_footpath_entry * pathType;
|
||||||
|
|
||||||
numPathTypes = 0;
|
numPathTypes = 0;
|
||||||
flags = FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR;
|
// If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor
|
||||||
// If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor, but not their queues (since these usually shouldn't have one)
|
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
|
||||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || (gCheatsSandboxMode && !showQueues))
|
|
||||||
flags = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < MAX_PATH_OBJECTS; i++)
|
||||||
|
{
|
||||||
pathType = get_footpath_entry(i);
|
pathType = get_footpath_entry(i);
|
||||||
if (pathType == (rct_footpath_entry *) -1)
|
if (pathType == (rct_footpath_entry *) -1)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
if (pathType->flags & flags)
|
}
|
||||||
|
if ((pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !showEditorPaths)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
image = pathType->image + 71;
|
image = pathType->image + 71;
|
||||||
if (showQueues)
|
// Editor-only paths usually lack queue images. In this case, use the main path image
|
||||||
|
if (showQueues && !(pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
|
||||||
|
{
|
||||||
image++;
|
image++;
|
||||||
|
}
|
||||||
|
|
||||||
gDropdownItemsFormat[numPathTypes] = -1;
|
gDropdownItemsFormat[numPathTypes] = -1;
|
||||||
gDropdownItemsArgs[numPathTypes] = image;
|
gDropdownItemsArgs[numPathTypes] = image;
|
||||||
|
@ -705,21 +797,26 @@ static void window_footpath_set_provisional_path_at_point(sint32 x, sint32 y)
|
||||||
sint32 interactionType;
|
sint32 interactionType;
|
||||||
rct_map_element * mapElement;
|
rct_map_element * mapElement;
|
||||||
rct_xy16 mapCoord = {0};
|
rct_xy16 mapCoord = {0};
|
||||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr);
|
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN,
|
||||||
|
&mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr);
|
||||||
x = mapCoord.x;
|
x = mapCoord.x;
|
||||||
y = mapCoord.y;
|
y = mapCoord.y;
|
||||||
|
|
||||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
|
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||||
|
{
|
||||||
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
|
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
|
||||||
footpath_provisional_update();
|
footpath_provisional_update();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Check for change
|
// Check for change
|
||||||
if (
|
if (
|
||||||
(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) &&
|
(gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1) &&
|
||||||
gFootpathProvisionalPosition.x == x &&
|
gFootpathProvisionalPosition.x == x &&
|
||||||
gFootpathProvisionalPosition.y == y &&
|
gFootpathProvisionalPosition.y == y &&
|
||||||
gFootpathProvisionalPosition.z == mapElement->base_height
|
gFootpathProvisionalPosition.z == mapElement->base_height
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +833,9 @@ static void window_footpath_set_provisional_path_at_point(sint32 x, sint32 y)
|
||||||
// Set provisional path
|
// Set provisional path
|
||||||
sint32 slope = default_path_slope[mapElement->properties.surface.slope & 0x1F];
|
sint32 slope = default_path_slope[mapElement->properties.surface.slope & 0x1F];
|
||||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
||||||
|
{
|
||||||
slope = mapElement->properties.surface.slope & 7;
|
slope = mapElement->properties.surface.slope & 7;
|
||||||
|
}
|
||||||
sint32 pathType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
sint32 pathType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
||||||
|
|
||||||
_window_footpath_cost = footpath_provisional_set(pathType, x, y, mapElement->base_height, slope);
|
_window_footpath_cost = footpath_provisional_set(pathType, x, y, mapElement->base_height, slope);
|
||||||
|
@ -759,7 +858,9 @@ static void window_footpath_set_selection_start_bridge_at_point(sint32 screenX,
|
||||||
|
|
||||||
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
|
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
|
||||||
if (x == MAP_LOCATION_NULL)
|
if (x == MAP_LOCATION_NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
|
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
|
||||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW;
|
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW;
|
||||||
|
@ -775,10 +876,13 @@ static void window_footpath_set_selection_start_bridge_at_point(sint32 screenX,
|
||||||
|
|
||||||
sint32 z = mapElement->base_height;
|
sint32 z = mapElement->base_height;
|
||||||
|
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) {
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE)
|
||||||
|
{
|
||||||
uint8 slope = mapElement->properties.surface.slope;
|
uint8 slope = mapElement->properties.surface.slope;
|
||||||
if (slope & 0xf)
|
if (slope & 0xf)
|
||||||
z += 2; // Add 2 for a slope
|
{
|
||||||
|
z += 2;
|
||||||
|
} // Add 2 for a slope
|
||||||
if (slope & 0x10)
|
if (slope & 0x10)
|
||||||
z += 2; // Add another 2 for a steep slope
|
z += 2; // Add another 2 for a steep slope
|
||||||
}
|
}
|
||||||
|
@ -798,22 +902,29 @@ static void window_footpath_place_path_at_point(sint32 x, sint32 y)
|
||||||
rct_map_element * mapElement;
|
rct_map_element * mapElement;
|
||||||
|
|
||||||
if (_footpathErrorOccured)
|
if (_footpathErrorOccured)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
footpath_provisional_update();
|
footpath_provisional_update();
|
||||||
|
|
||||||
rct_xy16 mapCoord = {0};
|
rct_xy16 mapCoord = {0};
|
||||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr);
|
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN,
|
||||||
|
&mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr);
|
||||||
x = mapCoord.x;
|
x = mapCoord.x;
|
||||||
y = mapCoord.y;
|
y = mapCoord.y;
|
||||||
|
|
||||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set path
|
// Set path
|
||||||
presentType = default_path_slope[mapElement->properties.path.type & 0x1F];
|
presentType = default_path_slope[mapElement->properties.path.type & 0x1F];
|
||||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
||||||
|
{
|
||||||
presentType = mapElement->properties.path.type & 7;
|
presentType = mapElement->properties.path.type & 7;
|
||||||
|
}
|
||||||
z = mapElement->base_height;
|
z = mapElement->base_height;
|
||||||
selectedType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
selectedType = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
||||||
|
|
||||||
|
@ -821,9 +932,12 @@ static void window_footpath_place_path_at_point(sint32 x, sint32 y)
|
||||||
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
||||||
cost = footpath_place(selectedType, x, y, z, presentType, GAME_COMMAND_FLAG_APPLY);
|
cost = footpath_place(selectedType, x, y, z, presentType, GAME_COMMAND_FLAG_APPLY);
|
||||||
|
|
||||||
if (cost == MONEY32_UNDEFINED) {
|
if (cost == MONEY32_UNDEFINED)
|
||||||
|
{
|
||||||
_footpathErrorOccured = true;
|
_footpathErrorOccured = true;
|
||||||
} else if (gFootpathPrice != 0) {
|
}
|
||||||
|
else if (gFootpathPrice != 0)
|
||||||
|
{
|
||||||
// bp = RCT2_ADDRESS_COMMAND_MAP_Z
|
// bp = RCT2_ADDRESS_COMMAND_MAP_Z
|
||||||
// dx = RCT2_ADDRESS_COMMAND_MAP_Y
|
// dx = RCT2_ADDRESS_COMMAND_MAP_Y
|
||||||
// cx = RCT2_ADDRESS_COMMAND_MAP_X
|
// cx = RCT2_ADDRESS_COMMAND_MAP_X
|
||||||
|
@ -842,29 +956,41 @@ static void window_footpath_start_bridge_at_point(sint32 screenX, sint32 screenY
|
||||||
|
|
||||||
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
|
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
|
||||||
if (x == MAP_LOCATION_NULL)
|
if (x == MAP_LOCATION_NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) {
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE)
|
||||||
|
{
|
||||||
// If we start the path on a slope, the arrow is slightly raised, so we
|
// If we start the path on a slope, the arrow is slightly raised, so we
|
||||||
// expect the path to be slightly raised as well.
|
// expect the path to be slightly raised as well.
|
||||||
uint8 slope = mapElement->properties.surface.slope;
|
uint8 slope = mapElement->properties.surface.slope;
|
||||||
z = mapElement->base_height;
|
z = mapElement->base_height;
|
||||||
if (slope & 0x10) {
|
if (slope & 0x10)
|
||||||
|
{
|
||||||
// Steep diagonal slope
|
// Steep diagonal slope
|
||||||
z += 4;
|
z += 4;
|
||||||
} else if (slope & 0x0f) {
|
}
|
||||||
|
else if (slope & 0x0f)
|
||||||
|
{
|
||||||
// Normal slope
|
// Normal slope
|
||||||
z += 2;
|
z += 2;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
z = mapElement->base_height;
|
z = mapElement->base_height;
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH) {
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH)
|
||||||
if (mapElement->properties.path.type & 4) {
|
{
|
||||||
|
if (mapElement->properties.path.type & 4)
|
||||||
|
{
|
||||||
if (direction == (mapElement->properties.path.type & 3))
|
if (direction == (mapElement->properties.path.type & 3))
|
||||||
|
{
|
||||||
z += 2;
|
z += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tool_cancel();
|
tool_cancel();
|
||||||
gFootpathConstructFromPosition.x = x;
|
gFootpathConstructFromPosition.x = x;
|
||||||
|
@ -892,9 +1018,11 @@ static void window_footpath_construct()
|
||||||
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
|
||||||
|
|
||||||
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE;
|
||||||
money32 cost = footpath_place_remove_intersecting(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY, gFootpathConstructDirection);
|
money32 cost = footpath_place_remove_intersecting(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY,
|
||||||
|
gFootpathConstructDirection);
|
||||||
|
|
||||||
if (cost != MONEY32_UNDEFINED) {
|
if (cost != MONEY32_UNDEFINED)
|
||||||
|
{
|
||||||
audio_play_sound_at_location(
|
audio_play_sound_at_location(
|
||||||
SOUND_PLACE_ITEM,
|
SOUND_PLACE_ITEM,
|
||||||
gFootpathConstructFromPosition.x,
|
gFootpathConstructFromPosition.x,
|
||||||
|
@ -902,20 +1030,27 @@ static void window_footpath_construct()
|
||||||
gFootpathConstructFromPosition.z
|
gFootpathConstructFromPosition.z
|
||||||
);
|
);
|
||||||
|
|
||||||
if (gFootpathConstructSlope == 0) {
|
if (gFootpathConstructSlope == 0)
|
||||||
|
{
|
||||||
gFootpathConstructValidDirections = 0xFF;
|
gFootpathConstructValidDirections = 0xFF;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gFootpathConstructValidDirections = gFootpathConstructDirection;
|
gFootpathConstructValidDirections = gFootpathConstructDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND)
|
if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND)
|
||||||
|
{
|
||||||
viewport_set_visibility(1);
|
viewport_set_visibility(1);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have just built an upwards slope, the next path to construct is
|
// If we have just built an upwards slope, the next path to construct is
|
||||||
// a bit higher. Note that the z returned by footpath_get_next_path_info
|
// a bit higher. Note that the z returned by footpath_get_next_path_info
|
||||||
// already is lowered if we are building a downwards slope.
|
// already is lowered if we are building a downwards slope.
|
||||||
if (gFootpathConstructSlope == 2)
|
if (gFootpathConstructSlope == 2)
|
||||||
|
{
|
||||||
z += 2;
|
z += 2;
|
||||||
|
}
|
||||||
|
|
||||||
gFootpathConstructFromPosition.x = x;
|
gFootpathConstructFromPosition.x = x;
|
||||||
gFootpathConstructFromPosition.y = y;
|
gFootpathConstructFromPosition.y = y;
|
||||||
|
@ -935,26 +1070,34 @@ static void footpath_remove_map_element(rct_map_element *mapElement)
|
||||||
|
|
||||||
z = mapElement->base_height;
|
z = mapElement->base_height;
|
||||||
sint32 pathType = mapElement->properties.path.type;
|
sint32 pathType = mapElement->properties.path.type;
|
||||||
if (pathType & 4) {
|
if (pathType & 4)
|
||||||
|
{
|
||||||
pathType &= 3;
|
pathType &= 3;
|
||||||
pathType ^= 2;
|
pathType ^= 2;
|
||||||
if (pathType == gFootpathConstructDirection)
|
if (pathType == gFootpathConstructDirection)
|
||||||
|
{
|
||||||
z += 2;
|
z += 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find a connected edge
|
// Find a connected edge
|
||||||
sint32 edge = gFootpathConstructDirection ^2;
|
sint32 edge = gFootpathConstructDirection ^2;
|
||||||
if (!(mapElement->properties.path.edges & (1 << edge))) {
|
if (!(mapElement->properties.path.edges & (1 << edge)))
|
||||||
|
{
|
||||||
edge = (edge + 1) & 3;
|
edge = (edge + 1) & 3;
|
||||||
if (!(mapElement->properties.path.edges & (1 << edge))) {
|
if (!(mapElement->properties.path.edges & (1 << edge)))
|
||||||
|
{
|
||||||
edge = (edge + 2) & 3;
|
edge = (edge + 2) & 3;
|
||||||
if (!(mapElement->properties.path.edges & (1 << edge))) {
|
if (!(mapElement->properties.path.edges & (1 << edge)))
|
||||||
|
{
|
||||||
edge = (edge - 1) & 3;
|
edge = (edge - 1) & 3;
|
||||||
if (!(mapElement->properties.path.edges & (1 << edge)))
|
if (!(mapElement->properties.path.edges & (1 << edge)))
|
||||||
|
{
|
||||||
edge ^= 2;
|
edge ^= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove path
|
// Remove path
|
||||||
gGameCommandErrorTitle = STR_CANT_REMOVE_FOOTPATH_FROM_HERE;
|
gGameCommandErrorTitle = STR_CANT_REMOVE_FOOTPATH_FROM_HERE;
|
||||||
|
@ -988,29 +1131,45 @@ static rct_map_element *footpath_get_map_element_to_remove()
|
||||||
x = gFootpathConstructFromPosition.x / 32;
|
x = gFootpathConstructFromPosition.x / 32;
|
||||||
y = gFootpathConstructFromPosition.y / 32;
|
y = gFootpathConstructFromPosition.y / 32;
|
||||||
if (x >= 256 || y >= 256)
|
if (x >= 256 || y >= 256)
|
||||||
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
z = (gFootpathConstructFromPosition.z >> 3) & 0xFF;
|
z = (gFootpathConstructFromPosition.z >> 3) & 0xFF;
|
||||||
zLow = z - 2;
|
zLow = z - 2;
|
||||||
|
|
||||||
mapElement = map_get_first_element_at(x, y);
|
mapElement = map_get_first_element_at(x, y);
|
||||||
do {
|
do
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH) {
|
{
|
||||||
if (mapElement->base_height == z) {
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH)
|
||||||
|
{
|
||||||
|
if (mapElement->base_height == z)
|
||||||
|
{
|
||||||
if (mapElement->properties.path.type & 4)
|
if (mapElement->properties.path.type & 4)
|
||||||
|
{
|
||||||
if (((mapElement->properties.path.type & 3) ^ 2) != gFootpathConstructDirection)
|
if (((mapElement->properties.path.type & 3) ^ 2) != gFootpathConstructDirection)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mapElement;
|
return mapElement;
|
||||||
} else if (mapElement->base_height == zLow) {
|
}
|
||||||
|
else if (mapElement->base_height == zLow)
|
||||||
|
{
|
||||||
if (!(mapElement->properties.path.type & 4))
|
if (!(mapElement->properties.path.type & 4))
|
||||||
|
{
|
||||||
if ((mapElement->properties.path.type & 3) == gFootpathConstructDirection)
|
if ((mapElement->properties.path.type & 3) == gFootpathConstructDirection)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mapElement;
|
return mapElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!map_element_is_last_for_tile(mapElement++));
|
}
|
||||||
|
while (!map_element_is_last_for_tile(mapElement++));
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1187,9 @@ static void window_footpath_remove()
|
||||||
|
|
||||||
mapElement = footpath_get_map_element_to_remove();
|
mapElement = footpath_get_map_element_to_remove();
|
||||||
if (mapElement != nullptr)
|
if (mapElement != nullptr)
|
||||||
|
{
|
||||||
footpath_remove_map_element(mapElement);
|
footpath_remove_map_element(mapElement);
|
||||||
|
}
|
||||||
|
|
||||||
window_footpath_set_enabled_and_pressed_widgets();
|
window_footpath_set_enabled_and_pressed_widgets();
|
||||||
}
|
}
|
||||||
|
@ -1041,9 +1202,12 @@ static void window_footpath_set_enabled_and_pressed_widgets()
|
||||||
{
|
{
|
||||||
rct_window * w = window_find_by_class(WC_FOOTPATH);
|
rct_window * w = window_find_by_class(WC_FOOTPATH);
|
||||||
if (w == nullptr)
|
if (w == nullptr)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
|
if (gFootpathConstructionMode == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
map_invalidate_map_selection_tiles();
|
map_invalidate_map_selection_tiles();
|
||||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_CONSTRUCT;
|
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_CONSTRUCT;
|
||||||
gMapSelectFlags |= MAP_SELECT_FLAG_GREEN;
|
gMapSelectFlags |= MAP_SELECT_FLAG_GREEN;
|
||||||
|
@ -1066,7 +1230,8 @@ static void window_footpath_set_enabled_and_pressed_widgets()
|
||||||
);
|
);
|
||||||
uint64 disabledWidgets = 0;
|
uint64 disabledWidgets = 0;
|
||||||
sint32 currentRotation = get_current_rotation();
|
sint32 currentRotation = get_current_rotation();
|
||||||
if (gFootpathConstructionMode >= PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
|
if (gFootpathConstructionMode >= PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
|
||||||
|
{
|
||||||
// Set pressed directional widget
|
// Set pressed directional widget
|
||||||
sint32 direction = (gFootpathConstructDirection + currentRotation) & 3;
|
sint32 direction = (gFootpathConstructDirection + currentRotation) & 3;
|
||||||
pressedWidgets |= (1LL << (WIDX_DIRECTION_NW + direction));
|
pressedWidgets |= (1LL << (WIDX_DIRECTION_NW + direction));
|
||||||
|
@ -1074,15 +1239,22 @@ static void window_footpath_set_enabled_and_pressed_widgets()
|
||||||
// Set pressed slope widget
|
// Set pressed slope widget
|
||||||
sint32 slope = gFootpathConstructSlope;
|
sint32 slope = gFootpathConstructSlope;
|
||||||
if (slope == 6)
|
if (slope == 6)
|
||||||
|
{
|
||||||
pressedWidgets |= (1 << WIDX_SLOPEDOWN);
|
pressedWidgets |= (1 << WIDX_SLOPEDOWN);
|
||||||
|
}
|
||||||
else if (slope == 0)
|
else if (slope == 0)
|
||||||
|
{
|
||||||
pressedWidgets |= (1 << WIDX_LEVEL);
|
pressedWidgets |= (1 << WIDX_LEVEL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pressedWidgets |= (1 << WIDX_SLOPEUP);
|
pressedWidgets |= (1 << WIDX_SLOPEUP);
|
||||||
|
}
|
||||||
|
|
||||||
// Enable / disable directional widgets
|
// Enable / disable directional widgets
|
||||||
direction = gFootpathConstructValidDirections;
|
direction = gFootpathConstructValidDirections;
|
||||||
if (direction != 255) {
|
if (direction != 255)
|
||||||
|
{
|
||||||
disabledWidgets |=
|
disabledWidgets |=
|
||||||
(1 << WIDX_DIRECTION_NW) |
|
(1 << WIDX_DIRECTION_NW) |
|
||||||
(1 << WIDX_DIRECTION_NE) |
|
(1 << WIDX_DIRECTION_NE) |
|
||||||
|
@ -1092,7 +1264,9 @@ static void window_footpath_set_enabled_and_pressed_widgets()
|
||||||
direction = (direction + currentRotation) & 3;
|
direction = (direction + currentRotation) & 3;
|
||||||
disabledWidgets &= ~(1 << (WIDX_DIRECTION_NW + direction));
|
disabledWidgets &= ~(1 << (WIDX_DIRECTION_NW + direction));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Disable all bridge mode widgets
|
// Disable all bridge mode widgets
|
||||||
disabledWidgets |=
|
disabledWidgets |=
|
||||||
(1 << WIDX_DIRECTION_GROUP) |
|
(1 << WIDX_DIRECTION_GROUP) |
|
||||||
|
@ -1127,9 +1301,11 @@ static void footpath_get_next_path_info(sint32 *type, sint32 *x, sint32 *y, sint
|
||||||
*z = gFootpathConstructFromPosition.z / 8;
|
*z = gFootpathConstructFromPosition.z / 8;
|
||||||
*type = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
*type = (gFootpathSelectedType << 7) + (gFootpathSelectedId & 0xFF);
|
||||||
*slope = 0;
|
*slope = 0;
|
||||||
if (gFootpathConstructSlope != 0) {
|
if (gFootpathConstructSlope != 0)
|
||||||
|
{
|
||||||
*slope = gFootpathConstructDirection | 4;
|
*slope = gFootpathConstructDirection | 4;
|
||||||
if (gFootpathConstructSlope != 2) {
|
if (gFootpathConstructSlope != 2)
|
||||||
|
{
|
||||||
*z -= 2;
|
*z -= 2;
|
||||||
*slope ^= 2;
|
*slope ^= 2;
|
||||||
}
|
}
|
||||||
|
@ -1140,20 +1316,26 @@ static bool footpath_select_default()
|
||||||
{
|
{
|
||||||
// Select first available footpath
|
// Select first available footpath
|
||||||
sint32 footpathId = -1;
|
sint32 footpathId = -1;
|
||||||
for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; i++) {
|
for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; i++)
|
||||||
|
{
|
||||||
rct_footpath_entry * pathEntry = get_footpath_entry(i);
|
rct_footpath_entry * pathEntry = get_footpath_entry(i);
|
||||||
if (pathEntry != (rct_footpath_entry*)-1) {
|
if (pathEntry != (rct_footpath_entry *) -1)
|
||||||
|
{
|
||||||
footpathId = i;
|
footpathId = i;
|
||||||
|
|
||||||
// Prioritise non-restricted path
|
// Prioritise non-restricted path
|
||||||
if (!(pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) {
|
if (!(pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (footpathId == -1) {
|
if (footpathId == -1)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
gFootpathSelectedId = footpathId;
|
gFootpathSelectedId = footpathId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue