mirror of https://github.com/OpenRCT2/OpenRCT2.git
refactor map element iteration
This commit is contained in:
parent
658d949733
commit
8774731f03
|
@ -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) {
|
||||
|
|
62
src/editor.c
62
src/editor.c
|
@ -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();
|
||||
|
||||
|
|
|
@ -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++));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
171
src/ride/ride.c
171
src/ride/ride.c
|
@ -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 (
|
||||
|
|
|
@ -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++));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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++));
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
162
src/world/map.c
162
src/world/map.c
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue