refactor map element iteration

This commit is contained in:
IntelOrca 2015-01-22 00:19:05 +00:00
parent 658d949733
commit 8774731f03
16 changed files with 347 additions and 319 deletions

View File

@ -1431,7 +1431,7 @@ int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z)
sint16 y2 = y & 0xFFE0;
if (x2 < 0x1FFF && y2 < 0x1FFF) {
rct_map_element* mapelement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[((y2 * 256 + x2) & 0xFFFF) / 8];
while (mapelement->type & MAP_ELEMENT_TYPE_MASK) {
while (map_element_get_type(mapelement) != MAP_ELEMENT_TYPE_SURFACE) {
mapelement++;
}
if ((mapelement->base_height * 8) - 5 > z) {

View File

@ -339,15 +339,15 @@ static void sub_666DFD()
x /= 32;
y /= 32;
mapElement = TILE_MAP_ELEMENT_POINTER(x + y * 256);
mapElement = map_get_first_element_at(x, y);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE) {
mapElement->properties.entrance.path_type = 0;
break;
}
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
}
/**
@ -397,10 +397,10 @@ static void sub_69F06A()
*/
static void sub_6A2B62()
{
int i, x, y;
int i;
rct_sprite *sprite;
rct_ride *ride;
rct_map_element *mapElement;
map_element_iterator it;
RCT2_CALLPROC_EBPSAFE(0x0069F007);
@ -429,37 +429,33 @@ static void sub_6A2B62()
RCT2_CALLPROC_EBPSAFE(0x0069F3AB);
// Fix paths and remove all ride track / entrance / exit
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
resetElementLoop:
mapElement = TILE_MAP_ELEMENT_POINTER(x + y * 256);
do {
switch (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
case MAP_ELEMENT_TYPE_PATH:
if (mapElement->type & 1) {
mapElement->properties.path.type &= 0xF7;
mapElement->properties.path.addition_status = 255;
}
break;
map_element_iterator_begin(&it);
do {
switch (map_element_get_type(it.element)) {
case MAP_ELEMENT_TYPE_PATH:
if (it.element->type & 1) {
it.element->properties.path.type &= 0xF7;
it.element->properties.path.addition_status = 255;
}
break;
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(x * 32, y * 32, mapElement);
map_element_remove(mapElement);
goto resetElementLoop;
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(it.x * 32, it.y * 32, it.element);
map_element_remove(it.element);
map_element_iterator_restart_for_tile(&it);
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
if (mapElement->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) {
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(x * 32, y * 32, mapElement);
map_element_remove(mapElement);
goto resetElementLoop;
}
break;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
case MAP_ELEMENT_TYPE_ENTRANCE:
if (it.element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) {
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(it.x * 32, it.y * 32, it.element);
map_element_remove(it.element);
map_element_iterator_restart_for_tile(&it);
}
break;
}
}
} while (map_element_iterator_next(&it));
object_unload_all();

View File

@ -190,7 +190,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
case VIEWPORT_INTERACTION_ITEM_RIDE:
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR)
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH)
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH)
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
ride = GET_RIDE(mapElement->properties.track.ride_index);
@ -199,7 +199,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 1163;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) =
mapElement->properties.track.type == ENTRANCE_TYPE_RIDE_ENTRANCE ? 1335 : 1337;
} else if (mapElement->properties.track.type == 1 || mapElement->properties.track.type == 2 || mapElement->properties.track.type == 3) {
@ -288,7 +288,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
if (!(RCT2_ADDRESS_SCREEN_FLAGS & SCREEN_FLAGS_SCENARIO_EDITOR))
break;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_ENTRANCE)
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_ENTRANCE)
break;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 1164;
@ -397,13 +397,14 @@ static void viewport_interaction_remove_footpath(rct_map_element *mapElement, in
if (w != NULL)
sub_6A7831();
mapElement2 = TILE_MAP_ELEMENT_POINTER((y / 32) * 256 + (x / 32));
mapElement2 = map_get_first_element_at(x / 32, y / 32);
do {
if ((mapElement2->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH && mapElement2->base_height == z) {
if (map_element_get_type(mapElement2) == MAP_ELEMENT_TYPE_PATH && mapElement2->base_height == z) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_REMOVE_FOOTPATH_FROM_HERE;
footpath_remove(x, y, z, 1);
break;
}
} while (!((mapElement2++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement2++));
}
/**

View File

@ -111,8 +111,7 @@ int sub_68F3AE(rct_peep* peep){
peep->var_C4++;
if ((peep->var_C4 & 0xF) != (peep->sprite_index & 0xF))return 1;
uint16 ebx = (peep->next_x | (peep->next_y << 8)) >> 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(ebx);
rct_map_element* map_element = map_get_first_element_at(peep->next_x / 32, peep->next_y / 32);
uint8 map_type = MAP_ELEMENT_TYPE_PATH;
if ((peep->next_z >> 8) & ((1 << 4) | (1 << 3))){
@ -121,12 +120,11 @@ int sub_68F3AE(rct_peep* peep){
int z = peep->next_z & 0xFF;
for (;; map_element++){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == map_type){
do {
if (map_element_get_type(map_element) == map_type){
if (z == map_element->base_height)return 1;
}
if (map_element->flags & MAP_ELEMENT_FLAG_LAST_TILE)break;
}
} while (!map_element_is_last_for_tile(map_element++));
peep_decrement_num_riders(peep);
peep->state = PEEP_STATE_FALLING;
@ -348,15 +346,13 @@ void peep_update_falling(rct_peep* peep){
// If not drowning then falling. Note: peeps 'fall' after leaving a ride/enter the park.
rct_map_element *map_element = TILE_MAP_ELEMENT_POINTER((peep->y / 32) * 256 + (peep->x /32));
rct_map_element *map_element = map_get_first_element_at(peep->x / 32, peep->y / 32);
rct_map_element *saved_map = NULL;
int saved_height = 0;
for (int final_element = 0; !final_element; map_element++){
final_element = map_element->flags & MAP_ELEMENT_FLAG_LAST_TILE;
do {
// If a path check if we are on it
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_PATH){
int height = map_height_from_slope(peep->x, peep->y, map_element->properties.surface.slope)
+ map_element->base_height * 8;
@ -366,7 +362,7 @@ void peep_update_falling(rct_peep* peep){
saved_map = map_element;
break;
} // If a surface get the height and see if we are on it
else if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SURFACE){
else if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SURFACE){
// If the surface is water check to see if we could be drowning
if (map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK){
int height = (map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) * 16;
@ -404,7 +400,7 @@ void peep_update_falling(rct_peep* peep){
saved_map = map_element;
} // If not a path or surface go see next element
else continue;
}
} while (!map_element_is_last_for_tile(map_element++));
// This will be null if peep is falling
if (saved_map == NULL){
@ -699,9 +695,9 @@ static void peep_update_mowing(rct_peep* peep){
if (peep->var_37 != 7)continue;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER((peep->next_x | (peep->next_y << 8)) >> 5);
rct_map_element *map_element = map_get_first_element_at(peep->next_x / 32, peep->next_y / 32);
for (; ((map_element->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_SURFACE); map_element++);
for (; (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SURFACE); map_element++);
if ((map_element->properties.surface.terrain & MAP_ELEMENT_SURFACE_TERRAIN_MASK) == (TERRAIN_GRASS << 5)){
map_element->properties.surface.grass_length = 0;
@ -740,10 +736,10 @@ static void peep_update_watering(rct_peep* peep){
int x = peep->next_x + RCT2_ADDRESS(0x993CCC, sint16)[peep->var_37 * 2];
int y = peep->next_y + RCT2_ADDRESS(0x993CCE, sint16)[peep->var_37 * 2];
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER((x | (y << 8)) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
for (;; map_element++){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SCENERY){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY){
if (abs((peep->next_z & 0xFF) - map_element->base_height) <= 4){
rct_scenery_entry* scenery_entry = g_smallSceneryEntries[map_element->properties.scenery.type];
@ -755,7 +751,7 @@ static void peep_update_watering(rct_peep* peep){
}
}
}
if (map_element->flags&MAP_ELEMENT_FLAG_LAST_TILE){
if (map_element_is_last_for_tile(map_element)) {
peep_state_reset(peep);
return;
}
@ -794,27 +790,30 @@ static void peep_update_emptying_bin(rct_peep* peep){
if (peep->action_frame != 11)return;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER((peep->next_x | (peep->next_y << 8)) >> 5);
rct_map_element* map_element = map_get_first_element_at(peep->next_x / 32, peep->next_y / 32);
for (;; map_element++){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH){
if ((peep->next_z & 0xFF) == map_element->base_height)break;
for (;; map_element++) {
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_PATH) {
if ((peep->next_z & 0xFF) == map_element->base_height)
break;
}
if (map_element->flags&MAP_ELEMENT_FLAG_LAST_TILE){
if (map_element_is_last_for_tile(map_element)) {
peep_state_reset(peep);
return;
}
}
if ((map_element->properties.path.additions & 0xF) == 0){
if ((map_element->properties.path.additions & 0x0F) == 0) {
peep_state_reset(peep);
return;
}
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[(map_element->properties.path.additions & 0xF) - 1];
if (!(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG1)
|| map_element->flags&(1 << 5)
|| map_element->properties.path.additions & (1 << 7)){
if (
!(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG1)
|| map_element->flags & (1 << 5)
|| map_element->properties.path.additions & (1 << 7)
) {
peep_state_reset(peep);
return;
}

View File

@ -266,47 +266,42 @@ money32 ride_calculate_income_per_hour(rct_ride *ride)
*/
rct_map_element *sub_6CAF80(int rideIndex, int *outX, int *outY)
{
rct_map_element *resultMapElement, *mapElement;
map_element_iterator it;
rct_map_element *resultMapElement;
int foundSpecialTrackPiece;
resultMapElement = (rct_map_element*)-1;
foundSpecialTrackPiece = 0;
uint16 x, y;
for (x = 0; x < 256; x++) {
for (y = 0; y < 256; y++) {
// Iterate through map elements on tile
int tileIndex = (y << 8) | x;
mapElement = TILE_MAP_ELEMENT_POINTER(tileIndex);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_TRACK)
continue;
if (rideIndex != mapElement->properties.track.ride_index)
continue;
map_element_iterator_begin(&it);
do {
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_TRACK)
continue;
if (rideIndex != it.element->properties.track.ride_index)
continue;
// Found a track piece for target ride
// Found a track piece for target ride
// Check if its a ???
int specialTrackPiece = (
(mapElement->properties.track.type != 2 && mapElement->properties.track.type != 3) &&
(RCT2_ADDRESS(0x0099BA64, uint8)[mapElement->properties.track.type * 16] & 0x10)
);
// Check if its a ???
int specialTrackPiece = (
(it.element->properties.track.type != 2 && it.element->properties.track.type != 3) &&
(RCT2_ADDRESS(0x0099BA64, uint8)[it.element->properties.track.type * 16] & 0x10)
);
// Set result tile to this track piece if first found track or a ???
if (resultMapElement == (rct_map_element*)-1 || specialTrackPiece) {
resultMapElement = mapElement;
// Set result tile to this track piece if first found track or a ???
if (resultMapElement == (rct_map_element*)-1 || specialTrackPiece) {
resultMapElement = it.element;
if (outX != NULL) *outX = x * 32;
if (outY != NULL) *outY = y * 32;
}
if (specialTrackPiece) {
foundSpecialTrackPiece = 1;
return resultMapElement;
}
} while (!(mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE) && mapElement++);
if (outX != NULL) *outX = it.x * 32;
if (outY != NULL) *outY = it.y * 32;
}
}
if (specialTrackPiece) {
foundSpecialTrackPiece = 1;
return resultMapElement;
}
} while (map_element_iterator_next(&it));
return resultMapElement;
}
@ -881,7 +876,7 @@ int ride_modify(rct_map_element *mapElement, int x, int y)
ride_remove_peeps(rideIndex);
// Check if element is a station entrance or exit
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE)
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE)
return ride_modify_entrance_or_exit(mapElement, x, y);
constructionWindow = ride_create_or_find_construction_window(rideIndex);
@ -2031,29 +2026,35 @@ void ride_check_all_reachable()
* rct2: 0x006B7C59
* @return 1 if the coordinate is reachable or has no entrance, 0 otherwise
*/
static int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) {
int x = ((coordinate >> 8) & 0xFF) << 5, // cx
y = (coordinate & 0xFF) << 5; // ax
uint8 station_height = ride->station_heights[index];
int tile_idx = ((x << 8) | y) >> 5;
rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx];
static int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index)
{
int x, y, z;
rct_map_element *mapElement;
while(1) {
uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK;
if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) {
break;
} else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) {
return 1;
}
tile++;
x = coordinate & 0xFF;
y = (coordinate >> 8) & 0xFF;
z = ride->station_heights[index];
mapElement = map_get_first_element_at(x, y);
for (;;) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE && z == mapElement->base_height) {
break;
} else if (map_element_is_last_for_tile(mapElement)) {
return 1;
}
mapElement++;
}
uint8 face_direction = tile->type & 3;
y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2];
x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2];
tile_idx = ((x << 8) | y) >> 5;
uint8 face_direction = mapElement->type & 3;
return map_coord_is_connected(tile_idx, station_height, face_direction);
x *= 32;
y *= 32;
x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2];
y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2];
x /= 32;
y /= 32;
return map_coord_is_connected(x, y, z, face_direction);
}
static void ride_entrance_exit_connected(rct_ride* ride, int ride_idx)
@ -2086,64 +2087,66 @@ static void ride_entrance_exit_connected(rct_ride* ride, int ride_idx)
static void ride_shop_connected(rct_ride* ride, int ride_idx)
{
rct_ride* ride_back = ride;
int x, y, count;
rct_map_element *mapElement;
uint16 coordinate = ride->station_starts[0];
if (coordinate == 0xFFFF)
return;
int x = ((coordinate >> 8) & 0xFF) << 5, // cx
y = (coordinate & 0xFF) << 5; // ax
x = (coordinate & 0xFF);
y = (coordinate >> 8) & 0xFF;
rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate];
for (; ; tile++){
uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK;
if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx)
break;
if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE)
return;
}
mapElement = map_get_first_element_at(x, y);
do {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK && mapElement->properties.track.ride_index == ride_idx)
break;
} while (!map_element_is_last_for_tile(mapElement++));
uint16 entrance_directions = 0;
uint8 track_type = tile->properties.track.type;
ride = &g_ride_list[tile->properties.track.ride_index];
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) {
uint8 track_type = mapElement->properties.track.type;
ride = &g_ride_list[mapElement->properties.track.ride_index];
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) {
entrance_directions = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16];
} else {
} else {
entrance_directions = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16];
}
}
uint8 tile_direction = tile->type & MAP_ELEMENT_DIRECTION_MASK;
uint8 tile_direction = mapElement->type & MAP_ELEMENT_DIRECTION_MASK;
entrance_directions <<= tile_direction;
entrance_directions = ((entrance_directions >> 12) | entrance_directions) & 0xF;
// now each bit in entrance_directions stands for an entrance direction to check
// Now each bit in entrance_directions stands for an entrance direction to check
if (entrance_directions == 0)
return;
for (int count = 0; entrance_directions != 0; ++count) {
// Turn x, y from tiles into units
x *= 32;
y *= 32;
for (count = 0; entrance_directions != 0; count++) {
if (!(entrance_directions & 1)) {
entrance_directions >>= 1;
continue;
}
continue;
}
entrance_directions >>= 1;
uint8 face_direction = count ^ 2; // flip direction north<->south, east<->west
// Flip direction north<->south, east<->west
uint8 face_direction = count ^ 2;
int y2 = y - RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2];
int x2 = x - RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2];
int tile_idx = ((x2 << 8) | y2) >> 5;
if (map_coord_is_connected(tile_idx, tile->base_height, face_direction))
return;
}
// name of ride is parameter of the format string
RCT2_GLOBAL(0x013CE952, uint16) = ride->name;
if (map_coord_is_connected(x2 / 32, y2 / 32, mapElement->base_height, face_direction))
return;
}
// Name of ride is parameter of the format string
RCT2_GLOBAL(0x013CE952, uint16) = ride->name;
RCT2_GLOBAL(0x013CE954, uint32) = ride->name_arguments;
news_item_add_to_queue(1, STR_ENTRANCE_NOT_CONNECTED, ride_idx);
ride->connected_message_throttle = 3;
ride->connected_message_throttle = 3;
}
#pragma endregion
@ -2242,7 +2245,7 @@ static void ride_entrance_set_map_tooltip(rct_map_element *mapElement)
void ride_set_map_tooltip(rct_map_element *mapElement)
{
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
ride_entrance_set_map_tooltip(mapElement);
} else {
if (

View File

@ -236,11 +236,11 @@ static void ride_ratings_update_state_2()
y = RCT2_GLOBAL(0x0138B586, uint16) / 32;
z = RCT2_GLOBAL(0x0138B588, uint16) / 8;
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
mapElement = map_get_first_element_at(x, y);
trackType = RCT2_GLOBAL(0x0138B592, uint8);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_TRACK)
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
continue;
if (mapElement->base_height != z)
continue;
@ -271,7 +271,7 @@ static void ride_ratings_update_state_2()
RCT2_GLOBAL(0x0138B588, uint16) = z;
RCT2_GLOBAL(0x0138B592, uint8) = mapElement->properties.track.type;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
_rideRatingsState = RIDE_RATINGS_STATE_FIND_NEXT_RIDE;
}
@ -333,11 +333,11 @@ static void ride_ratings_update_state_5()
y = RCT2_GLOBAL(0x0138B586, uint16) / 32;
z = RCT2_GLOBAL(0x0138B588, uint16) / 8;
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
mapElement = map_get_first_element_at(x, y);
trackType = RCT2_GLOBAL(0x0138B592, uint8);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_TRACK)
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
continue;
if (mapElement->base_height != z)
continue;
@ -363,7 +363,7 @@ static void ride_ratings_update_state_5()
RCT2_GLOBAL(0x0138B588, uint16) = z;
RCT2_GLOBAL(0x0138B592, uint8) = mapElement->properties.track.type;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
_rideRatingsState = RIDE_RATINGS_STATE_FIND_NEXT_RIDE;
}
@ -736,15 +736,15 @@ static int ride_ratings_get_scenery_score(rct_ride *ride)
for (yy = y - 5; yy <= y + 5; yy++) {
for (xx = x - 5; xx <= x + 5; xx++) {
// Count scenery items on this tile
mapElement = TILE_MAP_ELEMENT_POINTER(yy * 256 + xx);
mapElement = map_get_first_element_at(xx, yy);
do {
if (mapElement->flags & 0x10)
if (mapElement->flags & (1 << 4))
continue;
type = mapElement->type & MAP_ELEMENT_TYPE_MASK;
type = map_element_get_type(mapElement);
if (type == MAP_ELEMENT_TYPE_SCENERY || type == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE)
numSceneryItems++;
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
}
}

View File

@ -294,16 +294,13 @@ rct_map_element *ride_get_station_start_track_element(rct_ride *ride, int statio
y = ride->station_starts[stationIndex] >> 8;
z = ride->station_heights[stationIndex];
// Get first element of the tile
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
// Find the station track element
mapElement = map_get_first_element_at(x, y);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_TRACK && z == mapElement->base_height)
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK && z == mapElement->base_height)
return mapElement;
mapElement++;
} while (!((mapElement - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
return NULL;
}
@ -312,16 +309,12 @@ rct_map_element *ride_get_station_exit_element(rct_ride *ride, int x, int y, int
{
rct_map_element *mapElement;
// Get first element of the tile
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
// Find the station track element
mapElement = map_get_first_element_at(x, y);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE && z == mapElement->base_height)
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE && z == mapElement->base_height)
return mapElement;
mapElement++;
} while (!((mapElement - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
return NULL;
}

View File

@ -676,26 +676,22 @@ unsigned int scenario_rand()
*/
void scenario_prepare_rides_for_save()
{
int i, x, y;
rct_map_element *mapElement;
int i;
rct_ride *ride;
map_element_iterator it;
int isFiveCoasterObjective = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_FINISH_5_ROLLERCOASTERS;
// Set all existing track to be indestructible
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_TRACK) {
if (isFiveCoasterObjective)
mapElement->flags |= 0x40;
else
mapElement->flags &= ~0x40;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
map_element_iterator_begin(&it);
do {
if (map_element_get_type(it.element) == MAP_ELEMENT_TYPE_TRACK) {
if (isFiveCoasterObjective)
it.element->flags |= 0x40;
else
it.element->flags &= ~0x40;
}
}
} while (map_element_iterator_next(&it));
// Set all existing rides to have indestructible track
FOR_ALL_RIDES(i, ride) {

View File

@ -136,13 +136,15 @@ void window_banner_open(rct_windownumber number)
int view_x = gBanners[w->number].x << 5;
int view_y = gBanners[w->number].y << 5;
int ebp = ((view_y << 8) | view_x) >> 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(ebp);
while(1){
if (((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_BANNER) &&
(map_element->properties.banner.index == w->number)) break;
rct_map_element* map_element = map_get_first_element_at(view_x / 32, view_y / 32);
while(1) {
if (
(map_element_get_type(map_element) == MAP_ELEMENT_TYPE_BANNER) &&
(map_element->properties.banner.index == w->number)
) {
break;
}
map_element++;
}
@ -186,10 +188,10 @@ static void window_banner_mouseup()
int x = banner->x << 5;
int y = banner->y << 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(((y << 8) | x) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if (((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_BANNER) &&
if ((map_element_get_type(map_element) == MAP_ELEMENT_TYPE_BANNER) &&
(map_element->properties.banner.index == w->number)) break;
map_element++;
}

View File

@ -288,42 +288,32 @@ static void cheat_set_grass_length(int length)
static void cheat_water_plants()
{
int x, y;
rct_map_element *mapElement;
map_element_iterator it;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SCENERY) {
mapElement->properties.scenery.age = 0;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
map_element_iterator_begin(&it);
do {
if (map_element_get_type(it.element) == MAP_ELEMENT_TYPE_SCENERY) {
it.element->properties.scenery.age = 0;
}
}
} while (map_element_iterator_next(&it));
gfx_invalidate_screen();
}
static void cheat_fix_vandalism()
{
int x, y;
rct_map_element *mapElement;
map_element_iterator it;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_PATH)
continue;
map_element_iterator_begin(&it);
do {
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_PATH)
continue;
if ((mapElement->properties.path.additions & 0x0F) == 0)
continue;
if ((it.element->properties.path.additions & 0x0F) == 0)
continue;
mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
}
}
it.element->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
} while (map_element_iterator_next(&it));
gfx_invalidate_screen();
}
@ -685,20 +675,15 @@ void window_cheats_misc_tool_down(){
// in the middle of a tile.
dest_x += 16;
dest_y += 16;
// Set the tile coordinate to top left of tile
int tile_y = dest_y & 0xFFE0;
int tile_x = dest_x & 0xFFE0;
int tile_x = (dest_x & 0xFFE0) >> 5;
int tile_y = (dest_y & 0xFFE0) >> 5;
ebp = ((tile_y << 8) | tile_x) >> 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(ebp);
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_SURFACE){
map_element->clearance_height = 0;
rct_map_element *mapElement = map_get_first_element_at(tile_x, tile_y);
do {
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SURFACE) {
mapElement->clearance_height = 0;
}
if (map_element->flags & MAP_ELEMENT_FLAG_LAST_TILE)
break;
map_element++;
}
} while (!map_element_is_last_for_tile(mapElement++));
}

View File

@ -728,7 +728,7 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY)
if (x == 0x8000)
return;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SURFACE) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) {
// ?
uint8 dl = ((mapElement->properties.surface.slope & 0x0F) << direction) & 0xFF;
uint8 dh = dl;
@ -739,7 +739,7 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY)
z += 2;
} else {
z = mapElement->base_height;
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH) {
if (mapElement->properties.path.type & 4) {
if (direction == (mapElement->properties.path.type & 3))
z += 2;
@ -837,9 +837,9 @@ static rct_map_element *footpath_get_map_element_to_remove()
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];
mapElement = map_get_first_element_at(x, y);
do {
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) {
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 & 3) ^ 2) != RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8))
@ -854,7 +854,7 @@ static rct_map_element *footpath_get_map_element_to_remove()
return mapElement;
}
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
return NULL;
}

View File

@ -1225,7 +1225,7 @@ rct_window *window_ride_open_track(rct_map_element *mapElement)
{
int rideIndex = mapElement->properties.track.ride_index;
if (
((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE) ||
(map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) ||
(RCT2_ADDRESS(0x0099BA64, uint8)[mapElement->properties.track.type * 16] & 0x10)
) {
// Open ride window in station view

View File

@ -169,12 +169,11 @@ void window_sign_open(rct_windownumber number)
int view_x = gBanners[w->number].x << 5;
int view_y = gBanners[w->number].y << 5;
int ebp = ((view_y << 8) | view_x) >> 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(ebp);
rct_map_element* map_element = map_get_first_element_at(view_x / 32, view_y / 32);
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
int ebx = map_element->properties.scenerymultiple.type;
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
@ -213,7 +212,7 @@ void window_sign_open(rct_windownumber number)
view_z,
0,
-1
);
);
w->viewport->flags = (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES) ? VIEWPORT_FLAG_GRIDLINES : 0;
w->flags |= WF_2;
@ -234,7 +233,7 @@ static void window_sign_mouseup()
rct_string_id string_id;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(((y << 8) | x) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
switch (widgetIndex) {
case WIDX_CLOSE:
@ -242,7 +241,7 @@ static void window_sign_mouseup()
break;
case WIDX_SIGN_DEMOLISH:
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
int ebx = map_element->properties.scenerymultiple.type;
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
@ -320,10 +319,10 @@ static void window_sign_dropdown()
int x = banner->x << 5;
int y = banner->y << 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(((y << 8) | x) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
int ebx = map_element->properties.scenerymultiple.type;
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
@ -499,12 +498,11 @@ void window_sign_small_open(rct_windownumber number){
int view_x = gBanners[w->number].x << 5;
int view_y = gBanners[w->number].y << 5;
int ebp = ((view_y << 8) | view_x) >> 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(ebp);
rct_map_element* map_element = map_get_first_element_at(view_x / 32, view_y / 32);
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_FENCE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
if (scenery_entry->wall.var_0D != 0xFF){
if (map_element->properties.fence.item[0] == w->number)
@ -538,7 +536,7 @@ void window_sign_small_open(rct_windownumber number){
view_z,
0,
-1
);
);
w->viewport->flags = (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES) ? VIEWPORT_FLAG_GRIDLINES : 0;
w->flags |= WF_2;
@ -559,7 +557,7 @@ static void window_sign_small_mouseup()
rct_string_id string_id;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(((y << 8) | x) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
switch (widgetIndex) {
case WIDX_CLOSE:
@ -567,7 +565,7 @@ static void window_sign_small_mouseup()
break;
case WIDX_SIGN_DEMOLISH:
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_FENCE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
if (scenery_entry->wall.var_0D != 0xFF){
if (map_element->properties.fence.item[0] == w->number)
@ -626,10 +624,10 @@ static void window_sign_small_dropdown()
int x = banner->x << 5;
int y = banner->y << 5;
rct_map_element* map_element = TILE_MAP_ELEMENT_POINTER(((y << 8) | x) >> 5);
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
while (1){
if ((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_FENCE){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
if (scenery_entry->wall.var_0D != 0xFF){
if (map_element->properties.fence.item[0] == w->number)

View File

@ -45,6 +45,61 @@ int _sub_6A876D_save_y;
static void tiles_init();
static void sub_6A87BB(int x, int y);
void map_element_iterator_begin(map_element_iterator *it)
{
it->x = 0;
it->y = 0;
it->element = map_get_first_element_at(0, 0);
}
int map_element_iterator_next(map_element_iterator *it)
{
if (it->element == NULL) {
it->element = map_get_first_element_at(it->x, it->y);
return 1;
}
if (!map_element_is_last_for_tile(it->element)) {
it->element++;
return 1;
}
if (it->x < 255) {
it->x++;
it->element = map_get_first_element_at(it->x, it->y);
return 1;
}
if (it->y < 255) {
it->x = 0;
it->y++;
it->element = map_get_first_element_at(it->x, it->y);
return 1;
}
return 0;
}
void map_element_iterator_restart_for_tile(map_element_iterator *it)
{
it->element = NULL;
}
rct_map_element *map_get_first_element_at(int x, int y)
{
return TILE_MAP_ELEMENT_POINTER(x + y * 256);
}
int map_element_is_last_for_tile(rct_map_element *element)
{
return element->flags & MAP_ELEMENT_FLAG_LAST_TILE;
}
int map_element_get_type(rct_map_element *element)
{
return element->type & MAP_ELEMENT_TYPE_MASK;
}
int map_element_get_terrain(rct_map_element *element)
{
int terrain = (element->properties.surface.terrain >> 5) & 7;
@ -89,13 +144,11 @@ void map_element_set_terrain_edge(rct_map_element *element, int terrain)
rct_map_element *map_get_surface_element_at(int x, int y)
{
// Get first element of the tile
rct_map_element *mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
rct_map_element *mapElement = map_get_first_element_at(x, y);
// Find the first surface element
while ((mapElement->type & MAP_ELEMENT_TYPE_MASK) != MAP_ELEMENT_TYPE_SURFACE) {
// Check if last element on tile
if (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE)
while (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SURFACE) {
if (map_element_is_last_for_tile(mapElement))
return NULL;
mapElement++;
@ -151,7 +204,7 @@ void map_init()
*/
void map_update_tile_pointers()
{
int i, x, y, lastTile;
int i, x, y;
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++)
TILE_MAP_ELEMENT_POINTER(i) = TILE_UNDEFINED_MAP_ELEMENT;
@ -161,10 +214,7 @@ void map_update_tile_pointers()
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
*tile++ = mapElement;
do {
lastTile = (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE);
mapElement++;
} while (!lastTile);
do { } while (!map_element_is_last_for_tile(mapElement++));
}
}
@ -354,7 +404,7 @@ void sub_68B089()
mapElement++;
mapElementFirst++;
} while (!((mapElement - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement - 1));
// Update next free element?
mapElement = RCT2_GLOBAL(0x0140E9A4, rct_map_element*);
@ -370,34 +420,32 @@ void sub_68B089()
* Checks if the tile at coordinate at height counts as connected.
* @return 1 if connected, 0 otherwise
*/
int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction)
int map_coord_is_connected(int x, int y, int z, uint8 faceDirection)
{
rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx];
rct_map_element *mapElement = map_get_first_element_at(x, y);
do {
rct_map_element_path_properties props = tile->properties.path;
uint8 path_type = props.type >> 2, path_dir = props.type & 3;
uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK;
do {
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH)
continue;
if (element_type != PATH_ROAD)
continue;
rct_map_element_path_properties props = mapElement->properties.path;
uint8 pathType = props.type >> 2;
uint8 pathDirection = props.type & 3;
if (path_type & 1) {
if (path_dir == face_direction) {
if (height == tile->base_height + 2)
if (pathType & 1) {
if (pathDirection == faceDirection) {
if (z == mapElement->base_height + 2)
return 1;
}
else if ((path_dir ^ 2) == face_direction && height == tile->base_height) {
} else if ((pathDirection ^ 2) == faceDirection && z == mapElement->base_height) {
return 1;
}
} else {
if (height == tile->base_height)
} else {
if (z == mapElement->base_height)
return 1;
}
} while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++);
}
} while (!map_element_is_last_for_tile(mapElement++));
return 0;
return 0;
}
/**
@ -618,9 +666,9 @@ money32 map_clear_scenery_from_tile(int x, int y, int flags)
totalCost = 0;
restart_from_beginning:
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
mapElement = map_get_first_element_at(x, y);
do {
type = mapElement->type & MAP_ELEMENT_TYPE_MASK;
type = map_element_get_type(mapElement);
switch (type) {
case MAP_ELEMENT_TYPE_PATH:
#ifdef CLEAR_SCENERY_REMOVES_PATHS
@ -654,7 +702,7 @@ restart_from_beginning:
break;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
} while (!map_element_is_last_for_tile(mapElement++));
return totalCost;
}
@ -878,36 +926,30 @@ void sub_6A6AA7(int x, int y, rct_map_element *mapElement)
*/
void map_remove_all_rides()
{
int x, y;
rct_map_element *mapElement;
map_element_iterator it;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
repeat_tile:
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
map_element_iterator_begin(&it);
do {
switch (map_element_get_type(it.element)) {
case MAP_ELEMENT_TYPE_PATH:
if (it.element->type & 1) {
it.element->properties.path.type &= ~8;
it.element->properties.path.addition_status = 255;
}
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
if (it.element->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE)
break;
do {
switch (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
case MAP_ELEMENT_TYPE_PATH:
if (mapElement->type & 1) {
mapElement->properties.path.type &= ~8;
mapElement->properties.path.addition_status = 255;
}
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE)
break;
// fall-through
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(x * 32, y * 32, mapElement);
map_element_remove(mapElement);
goto repeat_tile;
}
} while (!((mapElement++)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
// fall-through
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(it.x * 32, it.y * 32, it.element);
map_element_remove(it.element);
map_element_iterator_restart_for_tile(&it);
break;
}
}
} while (map_element_iterator_next(&it));
}
/**

View File

@ -223,6 +223,9 @@ extern rct_xy16 *gMapSelectionTiles;
void map_init();
void map_update_tile_pointers();
rct_map_element *map_get_first_element_at(int x, int y);
int map_element_is_last_for_tile(rct_map_element *element);
int map_element_get_type(rct_map_element *element);
int map_element_get_terrain(rct_map_element *element);
int map_element_get_terrain_edge(rct_map_element *element);
void map_element_set_terrain(rct_map_element *element, int terrain);
@ -231,7 +234,7 @@ int map_height_from_slope(int x, int y, int slope);
rct_map_element *map_get_surface_element_at(int x, int y);
int map_element_height(int x, int y);
void sub_68B089();
int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction);
int map_coord_is_connected(int x, int y, int z, uint8 faceDirection);
void map_invalidate_animations();
void sub_6A876D();
int map_is_location_owned(int x, int y, int z);
@ -258,4 +261,14 @@ void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, i
#define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x]))
#define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])
typedef struct {
int x;
int y;
rct_map_element *element;
} map_element_iterator;
void map_element_iterator_begin(map_element_iterator *it);
int map_element_iterator_next(map_element_iterator *it);
void map_element_iterator_restart_for_tile(map_element_iterator *it);
#endif

View File

@ -137,7 +137,7 @@ int park_calculate_size()
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
while (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
while (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SURFACE) {
mapElement++;
}