Implement game command footpath from track.

Fixes #1954
This commit is contained in:
duncanspumpkin 2015-09-29 23:07:07 +01:00
parent 6318d468b5
commit ecc2f74b63
5 changed files with 111 additions and 4 deletions

View File

@ -1127,7 +1127,7 @@ static uint32 game_do_command_table[58] = {
0,
0,
0,
0x006A68AE,
0,
0,
0, // use new_game_command_table, original: 0x00663CCD, // 20
0,//0x006B53E9,
@ -1190,7 +1190,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
game_command_place_scenery,
game_command_set_water_height,
game_command_place_footpath,
game_command_emptysub,
game_command_place_footpath_from_track,
game_command_remove_footpath,
game_command_change_surface_style, // 20
game_command_set_ride_price,

View File

@ -44,7 +44,7 @@ enum GAME_COMMAND {
GAME_COMMAND_PLACE_SCENERY,
GAME_COMMAND_SET_WATER_HEIGHT,
GAME_COMMAND_PLACE_PATH,
GAME_COMMAND_18,
GAME_COMMAND_PLACE_PATH_FROM_TRACK,
GAME_COMMAND_REMOVE_PATH,
GAME_COMMAND_CHANGE_SURFACE_STYLE,
GAME_COMMAND_SET_RIDE_PRICE,

View File

@ -1297,7 +1297,7 @@ int track_place_scenery(rct_track_scenery* scenery_start, uint8 rideIndex, int o
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1)bl = 0;
RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 927;
cost = game_do_command(mapCoord.x, bl | (bh << 8), mapCoord.y, z | (entry_index << 8), GAME_COMMAND_18, 0, 0);
cost = game_do_command(mapCoord.x, bl | (bh << 8), mapCoord.y, z | (entry_index << 8), GAME_COMMAND_PLACE_PATH_FROM_TRACK, 0, 0);
}
else{
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1)

View File

@ -416,6 +416,112 @@ void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *es
);
}
static money32 footpath_place_from_track(int type, int x, int y, int z, int slope, int edges, int flags)
{
rct_map_element *mapElement;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LANDSCAPING * 4;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_X, uint16) = x + 16;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Y, uint16) = y + 16;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Z, uint16) = z * 8;
if (!(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0 && !gConfigCheat.build_in_pause_mode) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY)
footpath_interrupt_peeps(x, y, z * 8);
RCT2_GLOBAL(0x00F3EFD9, money32) = 0;
RCT2_GLOBAL(0x00F3EFA4, uint8) = 0;
if (!map_is_location_owned(x, y, z * 8) && !gCheatsSandboxMode) {
return MONEY32_UNDEFINED;
}
if (!((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode) && !map_is_location_owned(x, y, z * 8))
return MONEY32_UNDEFINED;
if (z < 2) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_LOW;
return MONEY32_UNDEFINED;
}
if (z > 248) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_HIGH;
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
if (!(flags & (GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST))) {
footpath_remove_litter(x, y, z * 8);
}
}
RCT2_GLOBAL(0x00F3EFD9, money32) += 120;
uint8 bl = 15;
int zHigh = z + 4;
if (slope & 4) {
bl = RCT2_ADDRESS(0x0098D7EC, uint8)[slope & 3];
zHigh += 2;
}
RCT2_GLOBAL(0x00F3EF84, uint16) = x;
RCT2_GLOBAL(0x00F3EF86, uint16) = y;
// Ugh, hack until 0x006A6733 is written
// 0x006A6733 expects the flags to be at (*0xF3EF7C) + 8
RCT2_GLOBAL(0x00F3EF7C, uint32) = (uint32)(&flags - 2);
if (!gCheatsDisableClearanceChecks && !map_can_construct_with_clear_at(x, y, z, zHigh, (void*)0x006A6733, bl))
return MONEY32_UNDEFINED;
RCT2_GLOBAL(0x00F3EFA4, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_ELEMENT_LOCATION_COMPARED_TO_GROUND_AND_WATER, uint8);
if (!gCheatsDisableClearanceChecks && (RCT2_GLOBAL(RCT2_ADDRESS_ELEMENT_LOCATION_COMPARED_TO_GROUND_AND_WATER, uint8) & ELEMENT_IS_UNDERWATER)) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_CANT_BUILD_THIS_UNDERWATER;
return MONEY32_UNDEFINED;
}
mapElement = map_get_surface_element_at((x / 32), (y / 32));
int supportHeight = z - mapElement->base_height;
RCT2_GLOBAL(0x00F3EFD9, money32) += supportHeight < 0 ? MONEY(20, 00) : (supportHeight / 2) * MONEY(5, 00);
if (flags & GAME_COMMAND_FLAG_APPLY) {
mapElement = map_element_insert(x / 32, y / 32, z, 0x0F);
mapElement->type = MAP_ELEMENT_TYPE_PATH;
mapElement->clearance_height = z + 4 + (slope & 4 ? 2 : 0);
mapElement->properties.path.type = (type << 4) | (slope & 7);
mapElement->type |= type >> 7;
mapElement->properties.path.additions = 0;
mapElement->properties.path.addition_status = 255;
mapElement->properties.path.edges = edges & 0xF;
mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
if (flags & (1 << 6))
mapElement->flags |= MAP_ELEMENT_FLAG_GHOST;
map_invalidate_tile_full(x, y);
}
return RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY ? 0 : RCT2_GLOBAL(0x00F3EFD9, money32);
}
/*
* rct2: 0x006A68AE
*/
void game_command_place_footpath_from_track(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
*ebx = footpath_place_from_track(
(*edx >> 8) & 0xFF,
*eax & 0xFFFF,
*ecx & 0xFFFF,
*edx & 0xFF,
((*ebx >> 13) & 0x3) | ((*ebx >> 10) & 0x4),
(*ebx >> 8) & 0xF,
*ebx & 0xFF
);
}
/**
*
* rct2: 0x006A67C0

View File

@ -50,6 +50,7 @@ extern const rct_xy16 word_981D6C[4];
money32 footpath_remove_real(int x, int y, int z, int flags);
void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_place_footpath_from_track(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_remove_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
money32 footpath_place(int type, int x, int y, int z, int slope, int flags);
void footpath_remove(int x, int y, int z, int flags);