Split scenery place into multiple functions

This commit is contained in:
duncanspumpkin 2019-03-27 20:01:57 +00:00
parent 9f80a16353
commit f7c84fff60
1 changed files with 455 additions and 415 deletions

View File

@ -702,53 +702,7 @@ static void track_design_update_max_min_coordinates(int16_t x, int16_t y, int16_
gTrackPreviewMax.z = std::max(gTrackPreviewMax.z, z);
}
/**
*
* rct2: 0x006D0964
*/
static int32_t track_design_place_scenery(
rct_td6_scenery_element* scenery_start, int32_t originX, int32_t originY, int32_t originZ)
{
for (uint8_t mode = 0; mode <= 1; mode++)
{
if (scenery_start->scenery_object.end_flag != 0xFF)
{
_trackDesignPlaceStateHasScenery = true;
}
if (!_trackDesignPlaceStatePlaceScenery)
{
continue;
}
for (rct_td6_scenery_element* scenery = scenery_start; scenery->scenery_object.end_flag != 0xFF; scenery++)
{
uint8_t rotation = _currentTrackPieceDirection;
LocationXY8 tile = { (uint8_t)(originX / 32), (uint8_t)(originY / 32) };
switch (rotation & 3)
{
case TILE_ELEMENT_DIRECTION_WEST:
tile.x += scenery->x;
tile.y += scenery->y;
break;
case TILE_ELEMENT_DIRECTION_NORTH:
tile.x += scenery->y;
tile.y -= scenery->x;
break;
case TILE_ELEMENT_DIRECTION_EAST:
tile.x -= scenery->x;
tile.y -= scenery->y;
break;
case TILE_ELEMENT_DIRECTION_SOUTH:
tile.x -= scenery->y;
tile.y += scenery->x;
break;
}
LocationXY16 mapCoord = { (int16_t)(tile.x * 32), (int16_t)(tile.y * 32) };
track_design_update_max_min_coordinates(mapCoord.x, mapCoord.y, originZ);
if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0)
static bool TrackDesignPlaceSceneryTileDrawOutline(LocationXY8 tile)
{
uint8_t new_tile = 1;
LocationXY16* selectionTile = gMapSelectionTiles;
@ -773,9 +727,11 @@ static int32_t track_design_place_scenery(
selectionTile++;
selectionTile->x = -1;
}
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0)
static bool TrackDesignPlaceSceneryTileRemoveGhost(
CoordsXY mapCoord, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ)
{
uint8_t entry_type, entry_index;
if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index))
@ -791,17 +747,16 @@ static int32_t track_design_place_scenery(
}
entry_index = 0;
for (PathSurfaceEntry* path = get_path_surface_entry(0);
entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS];
for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS];
path = get_path_surface_entry(entry_index), entry_index++)
{
if (path == nullptr)
{
continue;
return true;
}
if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
{
continue;
return true;
}
}
@ -831,8 +786,7 @@ static int32_t track_design_place_scenery(
&& scenery_small_entry_has_flag(small_scenery, SMALL_SCENERY_FLAG_DIAGONAL))
&& scenery_small_entry_has_flag(
small_scenery,
SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE
| SMALL_SCENERY_FLAG_THREE_QUARTERS))
SMALL_SCENERY_FLAG_DIAGONAL | SMALL_SCENERY_FLAG_HALF_SPACE | SMALL_SCENERY_FLAG_THREE_QUARTERS))
{
quadrant = 0;
}
@ -862,7 +816,7 @@ static int32_t track_design_place_scenery(
uint8_t direction = (rotation + scenery->flags) & TILE_ELEMENT_DIRECTION_MASK;
TileCoordsXYZD wallLocation = { tile.x, tile.y, z, direction };
TileCoordsXYZD wallLocation = { mapCoord.x / 32, mapCoord.y / 32, z, direction };
auto wallRemoveAction = WallRemoveAction(wallLocation);
wallRemoveAction.SetFlags(flags);
@ -875,20 +829,10 @@ static int32_t track_design_place_scenery(
footpath_remove(mapCoord.x, mapCoord.y, z, flags);
break;
}
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
int32_t z = scenery->z * 8 + _trackDesignPlaceZ;
if (z < _trackDesignPlaceSceneryZ)
{
_trackDesignPlaceSceneryZ = z;
}
}
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE
|| _trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
static bool TrackDesignPlaceSceneryTileGetEntry(uint8_t& entry_type, uint8_t& entry_index, rct_td6_scenery_element* scenery)
{
uint8_t entry_type, entry_index;
if (!find_object_in_entry_group(&scenery->scenery_object, &entry_type, &entry_index))
@ -897,36 +841,79 @@ static int32_t track_design_place_scenery(
if (entry_type != OBJECT_TYPE_PATHS)
{
_trackDesignPlaceStateSceneryUnavailable = true;
continue;
return true;
}
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
{
_trackDesignPlaceStateSceneryUnavailable = true;
continue;
return true;
}
entry_index = 0;
for (PathSurfaceEntry* path = get_path_surface_entry(0);
entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS];
for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS];
path = get_path_surface_entry(entry_index), entry_index++)
{
if (path == nullptr)
{
continue;
return true;
}
if (path->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
{
continue;
return true;
}
}
if (entry_index == object_entry_group_counts[OBJECT_TYPE_PATHS])
{
_trackDesignPlaceStateSceneryUnavailable = true;
continue;
return true;
}
}
return false;
}
static bool TrackDesignPlaceSceneryTileGetPlaceZ(rct_td6_scenery_element* scenery)
{
int32_t z = scenery->z * 8 + _trackDesignPlaceZ;
if (z < _trackDesignPlaceSceneryZ)
{
_trackDesignPlaceSceneryZ = z;
}
uint8_t entry_type, entry_index;
TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery);
return true;
}
static bool TrackDesignPlaceSceneryTile(
CoordsXY mapCoord, LocationXY8 tile, uint8_t mode, rct_td6_scenery_element* scenery, uint8_t rotation, int32_t originZ)
{
if (_trackDesignPlaceOperation == PTD_OPERATION_DRAW_OUTLINES && mode == 0)
{
return TrackDesignPlaceSceneryTileDrawOutline(tile);
}
if (_trackDesignPlaceOperation == PTD_OPERATION_REMOVE_GHOST && mode == 0)
{
return TrackDesignPlaceSceneryTileRemoveGhost(mapCoord, scenery, rotation, originZ);
}
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
return TrackDesignPlaceSceneryTileGetPlaceZ(scenery);
}
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
uint8_t entry_type, entry_index;
if (TrackDesignPlaceSceneryTileGetEntry(entry_type, entry_index, scenery))
{
return true;
}
money32 cost;
int16_t z;
@ -939,11 +926,11 @@ static int32_t track_design_place_scenery(
{
if (mode != 0)
{
continue;
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
continue;
return true;
}
rotation += scenery->flags;
@ -954,13 +941,13 @@ static int32_t track_design_place_scenery(
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY;
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY
| GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5;
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED
| GAME_COMMAND_FLAG_5;
}
else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST)
{
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY
| GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5;
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED
| GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5;
}
else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY)
{
@ -983,11 +970,11 @@ static int32_t track_design_place_scenery(
case OBJECT_TYPE_LARGE_SCENERY:
if (mode != 0)
{
continue;
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
continue;
return true;
}
rotation += scenery->flags;
@ -998,13 +985,13 @@ static int32_t track_design_place_scenery(
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY;
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY
| GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5;
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED
| GAME_COMMAND_FLAG_5;
}
else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST)
{
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY
| GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5;
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED
| GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_5;
}
else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY)
{
@ -1012,9 +999,8 @@ static int32_t track_design_place_scenery(
}
cost = game_do_command(
mapCoord.x, flags | (rotation << 8), mapCoord.y,
scenery->primary_colour | (scenery->secondary_colour << 8), GAME_COMMAND_PLACE_LARGE_SCENERY,
entry_index, z);
mapCoord.x, flags | (rotation << 8), mapCoord.y, scenery->primary_colour | (scenery->secondary_colour << 8),
GAME_COMMAND_PLACE_LARGE_SCENERY, entry_index, z);
if (cost == MONEY32_UNDEFINED)
{
@ -1025,11 +1011,11 @@ static int32_t track_design_place_scenery(
{
if (mode != 0)
{
continue;
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
continue;
return true;
}
z = scenery->z * 8 + originZ;
@ -1039,8 +1025,8 @@ static int32_t track_design_place_scenery(
flags = GAME_COMMAND_FLAG_APPLY;
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY
| GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5;
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_PATH_SCENERY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED
| GAME_COMMAND_FLAG_5;
}
else if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST)
{
@ -1053,8 +1039,8 @@ static int32_t track_design_place_scenery(
}
auto wallPlaceAction = WallPlaceAction(
entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour,
scenery->secondary_colour, scenery->flags & 0xFC);
entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery->primary_colour, scenery->secondary_colour,
scenery->flags & 0xFC);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&wallPlaceAction)
: GameActions::Query(&wallPlaceAction);
@ -1064,7 +1050,7 @@ static int32_t track_design_place_scenery(
case OBJECT_TYPE_PATHS:
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
continue;
return true;
}
z = (scenery->z * 8 + originZ) / 8;
@ -1113,14 +1099,14 @@ static int32_t track_design_place_scenery(
{
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY)
{
continue;
return true;
}
TileElement* tile_element = map_get_path_element_at(mapCoord.x / 32, mapCoord.y / 32, z);
if (tile_element == nullptr)
{
continue;
return true;
}
footpath_queue_chain_reset();
@ -1139,12 +1125,12 @@ static int32_t track_design_place_scenery(
footpath_connect_edges(mapCoord.x, mapCoord.y, tile_element, flags);
footpath_update_queue_chains();
continue;
return true;
}
break;
default:
_trackDesignPlaceStateSceneryUnavailable = true;
continue;
return true;
}
_trackDesignPlaceCost = add_clamp_money32(_trackDesignPlaceCost, cost);
if (_trackDesignPlaceOperation != PTD_OPERATION_PLACE)
@ -1156,12 +1142,65 @@ static int32_t track_design_place_scenery(
}
if (_trackDesignPlaceCost != MONEY32_UNDEFINED)
{
continue;
return true;
}
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE)
{
return true;
}
return false;
}
return true;
}
/**
*
* rct2: 0x006D0964
*/
static int32_t track_design_place_scenery(
rct_td6_scenery_element* scenery_start, int32_t originX, int32_t originY, int32_t originZ)
{
for (uint8_t mode = 0; mode <= 1; mode++)
{
if (scenery_start->scenery_object.end_flag != 0xFF)
{
_trackDesignPlaceStateHasScenery = true;
}
if (!_trackDesignPlaceStatePlaceScenery)
{
continue;
}
for (rct_td6_scenery_element* scenery = scenery_start; scenery->scenery_object.end_flag != 0xFF; scenery++)
{
uint8_t rotation = _currentTrackPieceDirection;
LocationXY8 tile = { (uint8_t)(originX / 32), (uint8_t)(originY / 32) };
switch (rotation & 3)
{
case TILE_ELEMENT_DIRECTION_WEST:
tile.x += scenery->x;
tile.y += scenery->y;
break;
case TILE_ELEMENT_DIRECTION_NORTH:
tile.x += scenery->y;
tile.y -= scenery->x;
break;
case TILE_ELEMENT_DIRECTION_EAST:
tile.x -= scenery->x;
tile.y -= scenery->y;
break;
case TILE_ELEMENT_DIRECTION_SOUTH:
tile.x -= scenery->y;
tile.y += scenery->x;
break;
}
CoordsXY mapCoord = { tile.x * 32, tile.y * 32 };
track_design_update_max_min_coordinates(mapCoord.x, mapCoord.y, originZ);
if (!TrackDesignPlaceSceneryTile(mapCoord, tile, mode, scenery, rotation, originZ))
{
return 0;
}
}
@ -1202,7 +1241,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y,
}
if (_trackDesignPlaceOperation == PTD_OPERATION_PLACE_QUERY || _trackDesignPlaceOperation == PTD_OPERATION_PLACE
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST || _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_GHOST
|| _trackDesignPlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
uint8_t flags;
money32 cost = 0;