1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 07:14:31 +01:00

implement more footpath construction and window

This commit is contained in:
IntelOrca
2014-12-17 20:45:27 +00:00
parent 0209ad080c
commit 44efbd95ac
12 changed files with 371 additions and 92 deletions

View File

@@ -236,6 +236,9 @@
#define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y 0x00F3EF8C
#define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z 0x00F3EF8E
#define RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION 0x00F3EF90
#define RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE 0x00F3EF91
#define RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS 0x00F3EF9E
#define RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS 0x00F42B6C

View File

@@ -1534,9 +1534,8 @@ void tool_cancel()
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) {
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_TOOL_ACTIVE;
//
RCT2_CALLPROC_EBPSAFE(0x0068AAE1);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_selection_rect();
map_invalidate_map_selection_tiles();
// Reset map selection
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) = 0;

View File

@@ -646,7 +646,7 @@ void window_cheats_misc_tool_update(){
if (widgetIndex != WIDX_ZERO_CLEARANCE) return;
RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
int temp_y = y + 16;
@@ -660,7 +660,7 @@ void window_cheats_misc_tool_update(){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = temp_y;
RCT2_CALLPROC_X(0x0068AAE1, eax, temp_y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
}
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;

View File

@@ -33,8 +33,8 @@
enum {
PATH_CONSTRUCTION_MODE_LAND,
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL,
PATH_CONSTRUCTION_MODE_2
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL,
PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL
};
enum {
@@ -146,12 +146,16 @@ static void* window_footpath_events[] = {
};
money32 _window_footpath_cost;
sint8 _window_footpath_provisional_path_arrow_timer;
static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues);
static void window_footpath_set_provisional_path_at_point(int x, int y);
static void window_footpath_place_path_at_point(int x, int y);
static void window_footpath_start_bridge_at_point(int screenX, int screenY);
static void window_footpath_construct();
static void window_footpath_remove();
static void window_footpath_set_enabled_and_pressed_widgets();
static void footpath_get_next_path_info(int *type, int *x, int *y, int *z, int *slope);
/**
*
@@ -204,7 +208,7 @@ void window_footpath_open()
tool_set(window, WIDX_CONSTRUCT_ON_LAND, 17);
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
window_footpath_set_enabled_and_pressed_widgets();
}
/**
@@ -219,7 +223,7 @@ static void window_footpath_close()
sub_6A7831();
viewport_set_visibility(0);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
window_invalidate_by_class(WC_TOP_TOOLBAR);
hide_gridlines();
@@ -253,28 +257,28 @@ static void window_footpath_mouseup()
_window_footpath_cost = MONEY32_UNDEFINED;
tool_cancel();
sub_6A7831();
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_LAND;
tool_set(w, WIDX_CONSTRUCT_ON_LAND, 17);
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
window_footpath_set_enabled_and_pressed_widgets();
break;
case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL:
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL)
break;
_window_footpath_cost = MONEY32_UNDEFINED;
tool_cancel();
sub_6A7831();
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL;
tool_set(w, WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, 12);
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x006A855C);
window_footpath_set_enabled_and_pressed_widgets();
break;
}
}
@@ -399,11 +403,10 @@ static void window_footpath_tooldown()
window_tool_get_registers(w, widgetIndex, x, y);
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) {
if (widgetIndex == WIDX_CONSTRUCT_ON_LAND)
window_footpath_place_path_at_point(x, y);
} else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) {
RCT2_CALLPROC_X(0x006A840F, x, y, 0, 0, (int)w, 0, 0);
}
else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL)
window_footpath_start_bridge_at_point(x, y);
}
/**
@@ -440,16 +443,49 @@ static void window_footpath_toolup()
}
}
/**
*
* rct2: 0x006A7760
*/
static void window_footpath_update_provisional_path_for_bridge_mode(rct_window *w)
{
int type, x, y, z, slope;
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) != PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL)
return;
// Update provisional bridge mode path
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & (1 << 1))) {
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
_window_footpath_cost = footpath_provisional_set(type, x, y, z, slope);
widget_invalidate(w, WIDX_CONSTRUCT);
}
// Update little directional arrow on provisional bridge mode path
if (--_window_footpath_provisional_path_arrow_timer < 0) {
_window_footpath_provisional_path_arrow_timer = 5;
RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) ^= PROVISIONAL_PATH_FLAG_SHOW_ARROW;
footpath_get_next_path_info(&type, &x, &y, &z, &slope);
RCT2_GLOBAL(0x009DEA48, uint16) = x;
RCT2_GLOBAL(0x009DEA4A, uint16) = y;
RCT2_GLOBAL(0x009DEA4C, uint16) = z * 8;
RCT2_GLOBAL(0x009DEA4E, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8);
if (RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & PROVISIONAL_PATH_FLAG_SHOW_ARROW)
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 2);
else
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 2);
map_invalidate_tile_full(x, y);
}
}
/**
*
* rct2: 0x006A84BB
*/
static void window_footpath_update(rct_window *w)
{
// Invalidate construct button
widget_invalidate(w, WIDX_CONSTRUCT);
RCT2_CALLPROC_EBPSAFE(0x006A7760);
window_footpath_update_provisional_path_for_bridge_mode(w);
// Check tool
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_LAND) {
@@ -459,7 +495,7 @@ static void window_footpath_update(rct_window *w)
window_close(w);
else if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_ON_LAND)
window_close(w);
} else if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
} else if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL) {
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE))
window_close(w);
else if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH)
@@ -489,7 +525,9 @@ static void window_footpath_invalidate()
(1 << WIDX_QUEUELINE_TYPE);
// Enable / disable construct button
window_footpath_widgets[WIDX_CONSTRUCT].type = RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_LAND ? WWT_EMPTY : WWT_IMGBTN;
window_footpath_widgets[WIDX_CONSTRUCT].type =
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL ?
WWT_IMGBTN : WWT_EMPTY;
// Set footpath and queue type button images
selectedPath = RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint16);
@@ -523,9 +561,9 @@ static void window_footpath_paint()
if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT))) {
// Get construction image
image = (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) % 4;
if (RCT2_GLOBAL(0x00F3EF91, uint8) == 2)
if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) == 2)
image += 4;
else if (RCT2_GLOBAL(0x00F3EF91, uint8) == 6)
else if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) == 6)
image += 8;
image = RCT2_ADDRESS(0x0098D7E0, uint8)[image];
@@ -604,21 +642,21 @@ static void window_footpath_set_provisional_path_at_point(int x, int y)
int z, slope, pathType;
rct_map_element *mapElement;
RCT2_CALLPROC_EBPSAFE(0x0068AAE1);
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~4;
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 2);
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement);
if (z == 0) {
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
sub_6A7831();
} else {
// Check for change
if ((RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & 2) && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_X, uint16) == x && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Y, uint16) == y && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Z, uint8) == mapElement->base_height)
if ((RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & (1 << 1)) && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_X, uint16) == x && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Y, uint16) == y && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Z, uint8) == mapElement->base_height)
return;
// Set map selection
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0);
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y;
@@ -638,8 +676,6 @@ static void window_footpath_set_provisional_path_at_point(int x, int y)
}
}
/**
*
* rct2: 0x006A82C5
@@ -679,6 +715,51 @@ static void window_footpath_place_path_at_point(int x, int y)
}
}
/**
*
* rct2: 0x006A840F
*/
static void window_footpath_start_bridge_at_point(int screenX, int screenY)
{
int x, y, z, direction;
rct_map_element *mapElement;
sub_68A0C9(screenX, screenY, &x, &y, &direction, &mapElement);
if (x == 0x8000)
return;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SURFACE) {
// ?
uint8 dl = ((mapElement->properties.surface.slope & 0x0F) << direction) & 0xFF;
uint8 dh = dl;
dl = (dl >> 4) & 0x0F;
dh = (dh & 0x0F) | dl;
z = mapElement->base_height;
if ((dh & 0x0C) == 0x0C)
z += 2;
} else {
z = mapElement->base_height;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
if (mapElement->properties.path.type & 4) {
if (direction == (mapElement->properties.path.type & 3))
z += 2;
}
}
}
tool_cancel();
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) = y;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) = z * 8;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) = direction;
RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) = 0;
_window_footpath_provisional_path_arrow_timer = 0;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) = 255;
window_footpath_set_enabled_and_pressed_widgets();
}
/**
*
* rct2: 0x006A79B7
@@ -690,56 +771,21 @@ static void window_footpath_construct()
/**
*
* rct2: 0x006A7863
* rct2: 0x006A78EF
*/
static void window_footpath_remove()
static rct_map_element *footpath_remove_map_element(rct_map_element *mapElement)
{
int x, y, lastTile;
rct_map_element *mapElement;
int x, y, z;
// RCT2_CALLPROC_EBPSAFE(0x006A7863);
_window_footpath_cost = MONEY32_UNDEFINED;
sub_6A7831();
x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) / 32;
y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) / 32;
int dl = (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) >> 3) & 0xFF;
int dh = dl - 2;
if (x >= 256 || y >= 256)
goto loc_6A79B0;
mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
if (mapElement->base_height == dl) {
if (mapElement->properties.path.type & 4)
if (((mapElement->properties.path.type & 3) ^ 2) != RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
continue;
goto loc_6A78EF;
} else if (mapElement->base_height == dh) {
if (!(mapElement->properties.path.type & 4))
if ((mapElement->properties.path.type & 3) == RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
continue;
goto loc_6A78EF;
}
}
lastTile = (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE) != 0;
mapElement++;
} while (!lastTile);
goto loc_6A79B0;
loc_6A78EF:
dl = mapElement->base_height;
z = mapElement->base_height;
int pathType = mapElement->properties.path.type;
if (pathType & 4) {
pathType &= 3;
pathType ^= 2;
if (pathType == RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
dl += 2;
z += 2;
}
// Find a connected edge
int edge = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) ^ 2;
if (!(mapElement->properties.path.edges & (1 << edge))) {
@@ -753,7 +799,7 @@ loc_6A78EF:
}
}
}
// Remove path
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_REMOVE_FOOTPATH_FROM_HERE;
footpath_remove(
@@ -765,14 +811,166 @@ loc_6A78EF:
// Move selection
edge ^= 2;
x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) - RCT2_GLOBAL(0x00993CCC + (edge * 4), sint16);
y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) - RCT2_GLOBAL(0x00993CCE + (edge * 4), sint16);
x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) - TileDirectionDelta[edge].x;
y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) - TileDirectionDelta[edge].y;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) = y;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) = dl << 3;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) = z << 3;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) = edge;
RCT2_GLOBAL(0x00F3EF9E, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) = 255;
}
loc_6A79B0:
RCT2_CALLPROC_EBPSAFE(0x006A855C);
/**
*
* rct2: 0x006A7873
*/
static rct_map_element *footpath_get_map_element_to_remove()
{
rct_map_element *mapElement;
int x, y, z, zLow;
x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) / 32;
y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) / 32;
if (x >= 256 || y >= 256)
return NULL;
z = (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) >> 3) & 0xFF;
zLow = z - 2;
mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
if (mapElement->base_height == z) {
if (mapElement->properties.path.type & 4)
if (((mapElement->properties.path.type & 3) ^ 2) != RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
continue;
return mapElement;
} else if (mapElement->base_height == zLow) {
if (!(mapElement->properties.path.type & 4))
if ((mapElement->properties.path.type & 3) == RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
continue;
return mapElement;
}
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
return NULL;
}
/**
*
* rct2: 0x006A7863
*/
static void window_footpath_remove()
{
rct_map_element *mapElement;
_window_footpath_cost = MONEY32_UNDEFINED;
sub_6A7831();
mapElement = footpath_get_map_element_to_remove();
if (mapElement != NULL)
footpath_remove_map_element(mapElement);
window_footpath_set_enabled_and_pressed_widgets();
}
/**
*
* rct2: 0x006A855C
*/
static void window_footpath_set_enabled_and_pressed_widgets()
{
rct_window *w;
uint64 pressedWidgets, disabledWidgets;
int currentRotation, direction, slope;
w = window_find_by_class(WC_FOOTPATH);
if (w == NULL)
return;
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 1) | (1 << 3);
direction = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8);
gMapSelectionTiles[0].x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) + TileDirectionDelta[direction].x;
gMapSelectionTiles[0].y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) + TileDirectionDelta[direction].y;
gMapSelectionTiles[1].x = -1;
map_invalidate_map_selection_tiles();
}
pressedWidgets = w->pressed_widgets & 0xFFFF887F;
disabledWidgets = 0;
currentRotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) >= PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) {
// Set pressed directional widget
direction = (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) + currentRotation) & 3;
pressedWidgets |= (1LL << (WIDX_DIRECTION_NW + direction));
// Set pressed slope widget
slope = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8);
if (slope == 6)
pressedWidgets |= (1 << WIDX_SLOPEDOWN);
else if (slope == 0)
pressedWidgets |= (1 << WIDX_LEVEL);
else
pressedWidgets |= (1 << WIDX_SLOPEUP);
// Enable / disable directional widgets
direction = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8);
if (direction != 255) {
disabledWidgets |=
(1 << WIDX_DIRECTION_NW) |
(1 << WIDX_DIRECTION_NE) |
(1 << WIDX_DIRECTION_SW) |
(1 << WIDX_DIRECTION_SE);
direction = (direction + currentRotation) & 3;
disabledWidgets &= ~(1 << (WIDX_DIRECTION_NW + direction));
}
} else {
// Disable all bridge mode widgets
disabledWidgets |=
(1 << WIDX_DIRECTION_GROUP) |
(1 << WIDX_DIRECTION_NW) |
(1 << WIDX_DIRECTION_NE) |
(1 << WIDX_DIRECTION_SW) |
(1 << WIDX_DIRECTION_SE) |
(1 << WIDX_SLOPE_GROUP) |
(1 << WIDX_SLOPEDOWN) |
(1 << WIDX_LEVEL) |
(1 << WIDX_SLOPEUP) |
(1 << WIDX_CONSTRUCT) |
(1 << WIDX_REMOVE);
}
w->pressed_widgets = pressedWidgets;
w->disabled_widgets = disabledWidgets;
window_invalidate(w);
}
/**
*
* rct2: 0x006A7B20
*/
static void footpath_get_next_path_info(int *type, int *x, int *y, int *z, int *slope)
{
int direction;
direction = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8);
*x = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) + TileDirectionDelta[direction].x;
*y = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) + TileDirectionDelta[direction].y;
*z = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) / 8;
*type = (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) << 7) + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint8);
*slope = 0;
if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 0) {
*slope = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) | 4;
if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 2) {
*z -= 2;
*slope ^= 2;
}
}
}

View File

@@ -1136,7 +1136,7 @@ void window_guest_overview_tool_update(){
if (widgetIndex != WIDX_PICKUP) return;
RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
int temp_y = y + 16;
@@ -1150,7 +1150,7 @@ void window_guest_overview_tool_update(){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = temp_y;
RCT2_CALLPROC_X(0x0068AAE1, eax, temp_y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
}
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;

View File

@@ -793,7 +793,7 @@ static void window_park_entrance_toolupdate()
window_tool_get_registers(w, widgetIndex, x, y);
if (widgetIndex == WIDX_BUY_LAND_RIGHTS) {
RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= 0xFFFE;
screen_pos_to_map_pos(&x, &y);
if (x != SPRITE_LOCATION_NULL) {
@@ -803,7 +803,7 @@ static void window_park_entrance_toolupdate()
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y;
RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, (int)w, 0, 0);
map_invalidate_selection_rect();
}
}
}

View File

@@ -197,7 +197,7 @@ void window_construction_close(){
RCT2_CALLPROC_X(0x006C9627, 0, 0, 0, 0, 0, 0, 0);
viewport_set_visibility(0);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(0x9DE58A, uint16) &= 0xFFFD;
hide_gridlines();
@@ -228,7 +228,7 @@ void window_construction_maze_close(){
RCT2_CALLPROC_X(0x006C9627, 0, 0, 0, 0, 0, 0, 0);
viewport_set_visibility(0);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(0x9DE58A, uint16) &= 0xFFFD;
hide_gridlines();

View File

@@ -453,7 +453,7 @@ static void window_track_place_close()
{
window_track_place_clear_provisional();
viewport_set_visibility(0);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~6;
hide_gridlines();
free(_window_track_place_mini_preview);
@@ -520,7 +520,7 @@ static void window_track_place_toolupdate()
window_tool_get_registers(w, widgetIndex, x, y);
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7;
// Get the tool map position
@@ -583,7 +583,7 @@ static void window_track_place_tooldown()
window_tool_get_registers(w, widgetIndex, x, y);
window_track_place_clear_provisional();
RCT2_CALLPROC_EBPSAFE(0x0068AB1B);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7;
sub_68A15E(x, y, &x, &y);

View File

@@ -80,8 +80,8 @@ void footpath_provisional_remove()
*/
void sub_6A7831()
{
if (RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & (1 << 0)) {
RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) &= ~(1 << 0);
if (RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & PROVISIONAL_PATH_FLAG_SHOW_ARROW) {
RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) &= ~PROVISIONAL_PATH_FLAG_SHOW_ARROW;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint8) &= ~(1 << 2);
map_invalidate_tile_full(
@@ -90,4 +90,20 @@ void sub_6A7831()
);
}
footpath_provisional_remove();
}
/**
*
* rct2: 0x0068A0C9
*/
void sub_68A0C9(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = screenX;
ebx = screenY;
RCT2_CALLFUNC_X(0x0068A0C9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (x != NULL) *x = *((uint16*)&eax);
if (y != NULL) *y = *((uint16*)&ebx);
if (direction != NULL) *direction = *((uint8*)&ecx);
if (mapElement != NULL) *mapElement = (rct_map_element*)edx;
}

View File

@@ -24,6 +24,10 @@
#include "../common.h"
#include "../interface/viewport.h"
enum {
PROVISIONAL_PATH_FLAG_SHOW_ARROW = (1 << 0)
};
typedef struct {
uint16 pad_00;
uint32 image; // 0x02
@@ -37,5 +41,6 @@ void footpath_remove(int x, int y, int z, int flags);
money32 footpath_provisional_set(int type, int x, int y, int z, int slope);
void footpath_provisional_remove();
void sub_6A7831();
void sub_68A0C9(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
#endif

View File

@@ -26,6 +26,19 @@
#include "park.h"
#include "scenery.h"
const rct_xy16 TileDirectionDelta[] = {
{ -32, 0 },
{ 0, +32 },
{ +32, 0 },
{ 0, -32 },
{ -32, +32 },
{ +32, +32 },
{ +32, -32 },
{ -32, -32 }
};
rct_xy16 *gMapSelectionTiles = (rct_xy16*)0x009DE596;
int _sub_6A876D_save_x;
int _sub_6A876D_save_y;
@@ -764,4 +777,40 @@ void map_remove_all_rides()
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
}
}
}
/**
*
* rct2: 0x0068AB1B
*/
void map_invalidate_map_selection_tiles()
{
rct_xy16 *position;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 1)))
return;
for (position = gMapSelectionTiles; position->x != -1; position++)
map_invalidate_tile_full(position->x, position->y);
}
/**
*
* rct2: 0x0068AAE1
*/
void map_invalidate_selection_rect()
{
int x, y, x0, y0, x1, y1;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)))
return;
x0 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16);
y0 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16);
x1 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16);
y1 = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16);
for (x = x0; x <= x1; x++)
for (y = y0; y <= y1; y++)
map_invalidate_tile_full(x, y);
}

View File

@@ -210,6 +210,13 @@ typedef struct {
uint8 direction;
} rct2_peep_spawn;
typedef struct {
sint16 x;
sint16 y;
} rct_xy16;
extern const rct_xy16 TileDirectionDelta[];
extern rct_xy16 *gMapSelectionTiles;
void map_init();
void map_update_tile_pointers();
@@ -232,6 +239,8 @@ int map_get_station(rct_map_element *mapElement);
void map_element_remove(rct_map_element *mapElement);
void sub_6A6AA7(int x, int y, rct_map_element *mapElement);
void map_remove_all_rides();
void map_invalidate_map_selection_tiles();
void map_invalidate_selection_rect();
void fountain_update_all();