Merge branch 'fix-3140' into develop

fix #3140: Multiplayer Permissions should be Verified by the host before action is taken
This commit is contained in:
IntelOrca 2016-03-22 22:57:31 +00:00
commit 9a97959b1e
5 changed files with 403 additions and 238 deletions

View File

@ -3644,145 +3644,218 @@ void ride_music_update_final()
#pragma endregion
static bool ride_is_mode_valid(rct_ride *ride, uint8 mode)
{
rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
const uint8 *availableModes = ride_seek_available_modes(ride);
if ((rideEntry->flags & RIDE_ENTRY_DISABLE_FIRST_TWO_OPERATING_MODES) && !gCheatsShowAllOperatingModes){
availableModes += 2;
}
for (; *availableModes != 0xFF; availableModes++) {
if (*availableModes == mode) {
return true;
}
}
return false;
}
static bool ride_is_valid_lift_hill_speed(rct_ride *ride, int speed)
{
int minSpeed = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed;
int maxSpeed = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed;
return speed >= minSpeed && speed <= maxSpeed;
}
static bool ride_is_valid_num_circuits(rct_ride *ride, int numCircuits)
{
int minNumCircuits = 1;
int maxNumCircuits = gCheatsFastLiftHill ? 255 : 20;
return numCircuits >= minNumCircuits && numCircuits <= maxNumCircuits;
}
static bool ride_is_valid_operation_option(rct_ride *ride, uint8 value)
{
uint8 minValue = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 4, uint8);
uint8 maxValue = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 5, uint8);
if (ride->mode == RIDE_MODE_MAZE) {
// Allow 64 people in mazes under non-cheat settings. The old maximum of 16 was too little for even moderately big mazes.
maxValue = 64;
}
if (gCheatsFastLiftHill) {
minValue = 0;
maxValue = 255;
}
return value >= minValue && value <= maxValue;
}
static money32 ride_set_setting(uint8 rideIndex, uint8 setting, uint8 value, uint8 flags)
{
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
rct_ride *ride = get_ride(rideIndex);
if (ride == NULL || ride->type == RIDE_TYPE_NULL) {
log_warning("Invalid ride: #%u.", rideIndex);
return MONEY32_UNDEFINED;
}
switch (setting) {
case RIDE_SETTING_MODE:
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING;
return MONEY32_UNDEFINED;
}
if (ride->status != RIDE_STATUS_CLOSED) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_MUST_BE_CLOSED_FIRST;
return MONEY32_UNDEFINED;
}
if (!ride_is_mode_valid(ride, value)) {
log_warning("Invalid ride mode.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
invalidate_test_results(rideIndex);
ride_clear_for_construction(rideIndex);
ride_remove_peeps(rideIndex);
ride->mode = value;
ride_update_max_vehicles(rideIndex);
}
break;
case RIDE_SETTING_DEPARTURE:
if (flags & GAME_COMMAND_FLAG_APPLY) {
ride->depart_flags = value;
}
break;
case RIDE_SETTING_MIN_WAITING_TIME:
if (value > 250) {
log_warning("Invalid minimum waiting time.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
ride->min_waiting_time = value;
ride->max_waiting_time = max(value, ride->max_waiting_time);
}
break;
case RIDE_SETTING_MAX_WAITING_TIME:
if (value > 250) {
log_warning("Invalid maximum waiting time.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
ride->max_waiting_time = value;
ride->min_waiting_time = min(value, ride->min_waiting_time);
}
break;
case RIDE_SETTING_OPERATION_OPTION:
if (!ride_is_valid_operation_option(ride, value)) {
log_warning("Invalid operation option value.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
invalidate_test_results(rideIndex);
ride->operation_option = value;
}
break;
case RIDE_SETTING_INSPECTION_INTERVAL:
if (value > RIDE_INSPECTION_NEVER) {
log_warning("Invalid inspection interval.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
ride->inspection_interval = value;
}
break;
case RIDE_SETTING_MUSIC:
if (flags & GAME_COMMAND_FLAG_APPLY) {
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_MUSIC;
if (value) {
ride->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC;
}
}
break;
case RIDE_SETTING_MUSIC_TYPE:
if (value >= MUSIC_STYLE_COUNT) {
log_warning("Invalid music style.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
if (value != ride->music) {
ride->music = value;
ride->music_tune_id = 0xFF;
}
}
break;
case RIDE_SETTING_LIFT_HILL_SPEED:
if (!ride_is_valid_lift_hill_speed(ride, value)) {
log_warning("Invalid lift hill speed.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
if (value != ride->lift_hill_speed) {
ride->lift_hill_speed = value;
invalidate_test_results(rideIndex);
}
}
break;
case RIDE_SETTING_NUM_CIRCUITS:
if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT && value > 1) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_MULTICIRCUIT_NOT_POSSIBLE_WITH_CABLE_LIFT_HILL;
return MONEY32_UNDEFINED;
}
if (!ride_is_valid_num_circuits(ride, value)) {
log_warning("Invalid number of circuits.");
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
if (value != ride->num_circuits) {
ride->num_circuits = value;
invalidate_test_results(rideIndex);
}
}
break;
}
if (flags & GAME_COMMAND_FLAG_APPLY) {
if (ride->overall_view != (uint16)-1) {
rct_xyz16 coord;
coord.x = (ride->overall_view & 0xFF) * 32 + 16;
coord.y = (ride->overall_view >> 8) * 32 + 16;
coord.z = map_element_height(coord.x, coord.y);
network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
}
window_invalidate_by_number(WC_RIDE, rideIndex);
}
return 0;
}
/**
*
* rct2: 0x006B5559
*/
void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
uint8 ride_id = *edx & 0xFF;
if (ride_id >= MAX_RIDES)
{
log_warning("Invalid game command for ride %u", ride_id);
*ebx = MONEY32_UNDEFINED;
return;
}
rct_ride* ride = get_ride(ride_id);
if (ride->type == RIDE_TYPE_NULL)
{
log_warning("Invalid game command.");
*ebx = MONEY32_UNDEFINED;
return;
}
uint8 flags = *ebx & 0xFF;
uint8 new_value = (*ebx >> 8) & 0xFF;
uint8 rideIndex = *edx & 0xFF;
uint8 setting = (*edx >> 8) & 0xFF;
if (setting == 0){
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN){
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING;
*ebx = MONEY32_UNDEFINED;
return;
}
if (ride->status != RIDE_STATUS_CLOSED){
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_MUST_BE_CLOSED_FIRST;
*ebx = MONEY32_UNDEFINED;
return;
}
}
if (setting == 9 &&
ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT &&
new_value > 1){
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_MULTICIRCUIT_NOT_POSSIBLE_WITH_CABLE_LIFT_HILL;
*ebx = MONEY32_UNDEFINED;
return;
}
if (flags == 0){
*ebx = 0;
return;
}
if (ride->overall_view != (uint16)-1) {
rct_xyz16 coord;
coord.x = (ride->overall_view & 0xFF) * 32 + 16;
coord.y = (ride->overall_view >> 8) * 32 + 16;
coord.z = map_element_height(coord.x, coord.y);
network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
}
switch (setting){
case 0:
// Alteration: only check if the ride mode exists, and fall back to the default if it doesn't.
invalidate_test_results(ride_id);
ride_clear_for_construction(ride_id);
ride_remove_peeps(ride_id);
rct_ride_entry* ride_entry = get_ride_entry(ride->subtype);
const uint8* available_modes = ride_seek_available_modes(ride);
if ((ride_entry->flags & RIDE_ENTRY_DISABLE_FIRST_TWO_OPERATING_MODES) && !gCheatsShowAllOperatingModes){
available_modes += 2;
}
uint8 default_mode = available_modes[0];
available_modes = AllRideModesAvailable;
for (; *available_modes != 0xFF; available_modes++){
if (*available_modes == new_value)
break;
}
if (*available_modes == 0xFF) {
log_warning("Tried to use incorrect ride mode, using default for this ride type.");
new_value = default_mode;
}
ride->mode = new_value;
ride_update_max_vehicles(ride_id);
break;
case 1:
ride->depart_flags = new_value;
break;
case 2:
ride->min_waiting_time = new_value;
ride->max_waiting_time = max(new_value, ride->max_waiting_time);
break;
case 3:
ride->max_waiting_time = new_value;
ride->min_waiting_time = min(new_value, ride->min_waiting_time);
break;
case 4:
invalidate_test_results(ride_id);
ride->time_limit = new_value;
break;
case 5:
ride->inspection_interval = new_value;
break;
case 6:
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_MUSIC;
if (new_value){
ride->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC;
}
break;
case 7:
if (new_value != ride->music){
ride->music = new_value;
ride->music_tune_id = 0xFF;
}
break;
case 8:
if (new_value != ride->lift_hill_speed){
ride->lift_hill_speed = new_value;
invalidate_test_results(ride_id);
}
break;
case 9:
if (new_value != ride->num_circuits){
ride->num_circuits = new_value;
invalidate_test_results(ride_id);
}
break;
}
window_invalidate_by_number(WC_RIDE, ride_id);
*ebx = 0;
uint8 newValue = (*ebx >> 8) & 0xFF;
uint8 flags = *ebx & 0xFF;
*ebx = ride_set_setting(rideIndex, setting, newValue, flags);
}
/**
@ -7486,54 +7559,138 @@ void ride_set_num_cars_per_vehicle(int rideIndex, int numCarsPerVehicle)
);
}
/**
*
* rct2: 0x006B52D4
*/
void game_command_set_ride_vehicles(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
static bool ride_is_vehicle_type_valid(rct_ride *ride, uint8 inputRideEntryIndex)
{
rct_ride *ride;
rct_ride_entry *rideEntry;
rct_window *w;
int rideIndex, commandType, value;
bool selectionShouldBeExpanded;
int rideTypeIterator, rideTypeIteratorMax;
commandType = (*ebx >> 8) & 0xFF;
rideIndex = *edx & 0xFF;
if (rideIndex >= MAX_RIDES)
{
log_warning("Invalid game command for ride %u", rideIndex);
*ebx = MONEY32_UNDEFINED;
return;
if (gCheatsShowVehiclesFromOtherTrackTypes &&
!(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE || ride->type == RIDE_TYPE_MINI_GOLF)
) {
selectionShouldBeExpanded = true;
rideTypeIterator = 0;
rideTypeIteratorMax = 90;
} else {
selectionShouldBeExpanded = false;
rideTypeIterator = ride->type;
rideTypeIteratorMax = ride->type;
}
value = (*edx >> 8) & 0xFF;
ride = get_ride(rideIndex);
if (ride->type == RIDE_TYPE_NULL)
{
log_warning("Invalid game command for ride %u", rideIndex);
*ebx = MONEY32_UNDEFINED;
return;
for (; rideTypeIterator <= rideTypeIteratorMax; rideTypeIterator++) {
if (selectionShouldBeExpanded) {
if (ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE)) continue;
if (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF) continue;
}
uint8 *rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != 0xFF; currentRideEntryIndex++) {
uint8 rideEntryIndex = *currentRideEntryIndex;
if (rideEntryIndex == inputRideEntryIndex) {
rct_ride_entry *currentRideEntry = get_ride_entry(rideEntryIndex);
// Skip if vehicle has the same track type, but not same subtype, unless subtype switching is enabled
if ((currentRideEntry->flags & (RIDE_ENTRY_FLAG_SEPARATE_RIDE | RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME)) &&
!(gConfigInterface.select_by_track_type || selectionShouldBeExpanded)
) {
continue;
}
// Skip if vehicle type is not invented yet
int quadIndex = rideEntryIndex >> 5;
int bitIndex = rideEntryIndex & 0x1F;
if (!(RCT2_ADDRESS(0x01357424, uint32)[quadIndex] & (1 << bitIndex))) {
continue;
}
return true;
}
}
}
return false;
}
money32 ride_set_vehicles(uint8 rideIndex, uint8 setting, uint8 value, uint8 flags, uint8 ex)
{
rct_ride_entry *rideEntry;
rct_ride *ride = get_ride(rideIndex);
if (ride == NULL || ride->type == RIDE_TYPE_NULL) {
log_warning("Invalid game command for ride #%u", rideIndex);
return MONEY32_UNDEFINED;
}
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING;
*ebx = MONEY32_UNDEFINED;
return;
return MONEY32_UNDEFINED;
}
if (ride->status != RIDE_STATUS_CLOSED) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_MUST_BE_CLOSED_FIRST;
*ebx = MONEY32_UNDEFINED;
return;
return MONEY32_UNDEFINED;
}
if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) {
*ebx = 0;
return;
switch (setting) {
case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_TRAINS:
if (!(flags & GAME_COMMAND_FLAG_APPLY)) {
return 0;
}
ride_clear_for_construction(rideIndex);
ride_remove_peeps(rideIndex);
ride->vehicle_change_timeout = 100;
ride->proposed_num_vehicles = value;
break;
case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_CARS_PER_TRAIN:
if (!(flags & GAME_COMMAND_FLAG_APPLY)) {
return 0;
}
ride_clear_for_construction(rideIndex);
ride_remove_peeps(rideIndex);
ride->vehicle_change_timeout = 100;
invalidate_test_results(rideIndex);
rideEntry = get_ride_entry(ride->subtype);
value = clamp(rideEntry->min_cars_in_train, value, rideEntry->max_cars_in_train);
ride->proposed_num_cars_per_train = value;
break;
case RIDE_SET_VEHICLES_COMMAND_TYPE_RIDE_ENTRY:
if (!ride_is_vehicle_type_valid(ride, value)) {
log_error("Invalid vehicle type.");
return MONEY32_UNDEFINED;
}
if (!(flags & GAME_COMMAND_FLAG_APPLY)) {
return 0;
}
ride_clear_for_construction(rideIndex);
ride_remove_peeps(rideIndex);
ride->vehicle_change_timeout = 100;
invalidate_test_results(rideIndex);
rideEntry = get_ride_entry(ride->subtype);
ride->subtype = value;
uint8 preset = ex;
if (!(flags & GAME_COMMAND_FLAG_NETWORKED)) {
preset = ride_get_unused_preset_vehicle_colour(ride->type, ride->subtype);
}
ride_set_vehicle_colours_to_random_preset(ride, preset);
ride->proposed_num_cars_per_train = clamp(rideEntry->min_cars_in_train, ride->proposed_num_cars_per_train, rideEntry->max_cars_in_train);
break;
default:
log_error("Unknown vehicle command.");
return MONEY32_UNDEFINED;
}
ride->num_circuits = 1;
ride_update_max_vehicles(rideIndex);
if (ride->overall_view != (uint16)-1) {
rct_xyz16 coord;
coord.x = (ride->overall_view & 0xFF) * 32 + 16;
@ -7542,55 +7699,30 @@ void game_command_set_ride_vehicles(int *eax, int *ebx, int *ecx, int *edx, int
network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
}
ride_clear_for_construction(rideIndex);
ride_remove_peeps(rideIndex);
ride->vehicle_change_timeout = 100;
if (ride->type != RIDE_TYPE_ENTERPRISE) {
gfx_invalidate_screen();
}
switch (commandType) {
case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_TRAINS:
ride->proposed_num_vehicles = value;
if (ride->type != RIDE_TYPE_SPACE_RINGS) {
gfx_invalidate_screen();
}
break;
case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_CARS_PER_TRAIN:
invalidate_test_results(rideIndex);
rideEntry = get_ride_entry(ride->subtype);
value = clamp(rideEntry->min_cars_in_train, value, rideEntry->max_cars_in_train);
ride->proposed_num_cars_per_train = value;
break;
case RIDE_SET_VEHICLES_COMMAND_TYPE_RIDE_ENTRY:
invalidate_test_results(rideIndex);
rideEntry = get_ride_entry(ride->subtype);
ride->subtype = value;
if (!(*ebx & GAME_COMMAND_FLAG_NETWORKED)) {
*eax =
ride_get_unused_preset_vehicle_colour(ride->type, ride->subtype);
}
ride_set_vehicle_colours_to_random_preset(ride, *eax & 0xFF);
ride->proposed_num_cars_per_train = clamp(rideEntry->min_cars_in_train, ride->proposed_num_cars_per_train, rideEntry->max_cars_in_train);
break;
default:
log_error("Unknown command!");
}
ride->num_circuits = 1;
ride_update_max_vehicles(rideIndex);
w = window_find_by_number(WC_RIDE, rideIndex);
rct_window *w = window_find_by_number(WC_RIDE, rideIndex);
if (w != NULL) {
if (w->page == 4) {
w->var_48C = 0;
}
window_invalidate(w);
}
*ebx = 0;
gfx_invalidate_screen();
return 0;
}
/**
*
* rct2: 0x006B52D4
*/
void game_command_set_ride_vehicles(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
uint8 rideIndex = *edx & 0xFF;
uint8 setting = (*ebx >> 8) & 0xFF;
uint8 value = (*edx >> 8) & 0xFF;
uint8 flags = *ebx & 0xFF;
uint8 ex = *eax & 0xFF;
*ebx = ride_set_vehicles(rideIndex, setting, value, flags, ex);
}
/**

View File

@ -626,7 +626,8 @@ enum {
MUSIC_STYLE_MODERN,
MUSIC_STYLE_PIRATES,
MUSIC_STYLE_ROCK_STYLE_3,
MUSIC_STYLE_CANDY_STYLE
MUSIC_STYLE_CANDY_STYLE,
MUSIC_STYLE_COUNT
};
enum {
@ -843,6 +844,19 @@ enum {
SHOP_ITEM_COUNT = 56
};
enum {
RIDE_SETTING_MODE,
RIDE_SETTING_DEPARTURE,
RIDE_SETTING_MIN_WAITING_TIME,
RIDE_SETTING_MAX_WAITING_TIME,
RIDE_SETTING_OPERATION_OPTION,
RIDE_SETTING_INSPECTION_INTERVAL,
RIDE_SETTING_MUSIC,
RIDE_SETTING_MUSIC_TYPE,
RIDE_SETTING_LIFT_HILL_SPEED,
RIDE_SETTING_NUM_CIRCUITS,
};
#define MAX_RIDES 255
#define MAX_RIDE_MEASUREMENTS 8

View File

@ -2792,7 +2792,7 @@ static void window_ride_mode_tweak_set(rct_window *w, uint8 value)
)
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 1868;
game_do_command(0, (value << 8) | 1, 0, (4 << 8) | w->number, GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
set_operating_setting(w->number, RIDE_SETTING_OPERATION_OPTION, value);
}
/**
@ -2802,18 +2802,21 @@ static void window_ride_mode_tweak_set(rct_window *w, uint8 value)
static void window_ride_mode_tweak_increase(rct_window *w)
{
rct_ride *ride = get_ride(w->number);
uint8 value = ride->operation_option;
//fast_lift_hill is the cheat that allows maxing out many limits on the Operating tab.
uint8 max_value = gCheatsFastLiftHill ? 255 : RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 5, uint8);
//Allow 64 people in mazes under non-cheat settings. The old maximum of 16 was too little for even moderately big mazes.
if(ride->mode == RIDE_MODE_MAZE && !gCheatsFastLiftHill)
max_value = 64;
uint8 maxValue = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 5, uint8);
if (ride->mode == RIDE_MODE_MAZE) {
// Allow 64 people in mazes under non-cheat settings. The old maximum of 16 was too little for even moderately big mazes.
maxValue = 64;
}
if (gCheatsFastLiftHill) {
maxValue = 255;
}
if (value < max_value)
value += ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
window_ride_mode_tweak_set(w, value);
uint8 increment = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
uint8 newValue = ride->operation_option + increment;
if (newValue < maxValue) {
window_ride_mode_tweak_set(w, newValue);
}
}
/**
@ -2823,14 +2826,17 @@ static void window_ride_mode_tweak_increase(rct_window *w)
static void window_ride_mode_tweak_decrease(rct_window *w)
{
rct_ride *ride = get_ride(w->number);
uint8 value = ride->operation_option;
//fast_lift_hill is the cheat that allows maxing many limits on the Operating tab.
uint8 min_value = gCheatsFastLiftHill ? 0 : RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 4, uint8);
if (value > min_value)
value -= ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
uint8 minValue = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 4, uint8);
if (gCheatsFastLiftHill) {
minValue = 0;
}
window_ride_mode_tweak_set(w, value);
uint8 decrement = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
uint8 newValue = ride->operation_option - decrement;
if (newValue > minValue) {
window_ride_mode_tweak_set(w, newValue);
}
}
/**
@ -2948,19 +2954,19 @@ static void window_ride_operating_mouseup(rct_window *w, int widgetIndex)
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_LOAD_CHECKBOX:
set_operating_setting(w->number, 1, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_LOAD);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_LOAD);
break;
case WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX:
set_operating_setting(w->number, 1, ride->depart_flags ^ RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES);
break;
case WIDX_MINIMUM_LENGTH_CHECKBOX:
set_operating_setting(w->number, 1, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH);
break;
case WIDX_MAXIMUM_LENGTH_CHECKBOX:
set_operating_setting(w->number, 1, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH);
break;
case WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX:
set_operating_setting(w->number, 1, ride->depart_flags ^ RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS);
break;
}
}
@ -2992,23 +2998,23 @@ static void window_ride_operating_mousedown(int widgetIndex, rct_window *w, rct_
break;
case WIDX_LIFT_HILL_SPEED_INCREASE:
parameter_check = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed;
set_operating_setting(w->number, 8, min(ride->lift_hill_speed + 1, parameter_check));
set_operating_setting(w->number, RIDE_SETTING_LIFT_HILL_SPEED, min(ride->lift_hill_speed + 1, parameter_check));
break;
case WIDX_LIFT_HILL_SPEED_DECREASE:
parameter_check = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed;
set_operating_setting(w->number, 8, max(ride->lift_hill_speed - 1, parameter_check));
set_operating_setting(w->number, RIDE_SETTING_LIFT_HILL_SPEED, max(ride->lift_hill_speed - 1, parameter_check));
break;
case WIDX_MINIMUM_LENGTH_INCREASE:
set_operating_setting(w->number, 2, min(ride->min_waiting_time + 1, 250));
set_operating_setting(w->number, RIDE_SETTING_MIN_WAITING_TIME, min(ride->min_waiting_time + 1, 250));
break;
case WIDX_MINIMUM_LENGTH_DECREASE:
set_operating_setting(w->number, 2, max(0, ride->min_waiting_time - 1));
set_operating_setting(w->number, RIDE_SETTING_MIN_WAITING_TIME, max(0, ride->min_waiting_time - 1));
break;
case WIDX_MAXIMUM_LENGTH_INCREASE:
set_operating_setting(w->number, 3, min(ride->max_waiting_time + 1, 250));
set_operating_setting(w->number, RIDE_SETTING_MAX_WAITING_TIME, min(ride->max_waiting_time + 1, 250));
break;
case WIDX_MAXIMUM_LENGTH_DECREASE:
set_operating_setting(w->number, 3, max(0, ride->max_waiting_time - 1));
set_operating_setting(w->number, RIDE_SETTING_MAX_WAITING_TIME, max(0, ride->max_waiting_time - 1));
break;
case WIDX_MODE_DROPDOWN:
window_ride_mode_dropdown(w, widget);
@ -3018,10 +3024,10 @@ static void window_ride_operating_mousedown(int widgetIndex, rct_window *w, rct_
break;
case WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE:
parameter_check = gCheatsFastLiftHill ? 255 : 20;
set_operating_setting(w->number, 9, min(ride->num_circuits + 1, parameter_check));
set_operating_setting(w->number, RIDE_SETTING_NUM_CIRCUITS, min(ride->num_circuits + 1, parameter_check));
break;
case WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE:
set_operating_setting(w->number, 9, max(ride->num_circuits - 1, 1));
set_operating_setting(w->number, RIDE_SETTING_NUM_CIRCUITS, max(ride->num_circuits - 1, 1));
break;
}
}
@ -3045,10 +3051,10 @@ static void window_ride_operating_dropdown(rct_window *w, int widgetIndex, int d
// Seek to available modes for this ride
availableModes = ride_seek_available_modes(ride);
set_operating_setting(w->number, 0, availableModes[dropdownIndex]);
set_operating_setting(w->number, RIDE_SETTING_MODE, availableModes[dropdownIndex]);
break;
case WIDX_LOAD_DROPDOWN:
set_operating_setting(w->number, 1, (ride->depart_flags & ~RIDE_DEPART_WAIT_FOR_LOAD_MASK) | dropdownIndex);
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, (ride->depart_flags & ~RIDE_DEPART_WAIT_FOR_LOAD_MASK) | dropdownIndex);
break;
}
}

View File

@ -4876,6 +4876,10 @@ void map_clear_all_elements()
}
money32 place_park_entrance(int flags, sint16 x, sint16 y, sint16 z, uint8 direction) {
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) {
return MONEY32_UNDEFINED;
}
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LAND_PURCHASE * 4;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_X, sint16) = x;

View File

@ -806,6 +806,11 @@ void game_command_remove_park_entrance(int *eax, int *ebx, int *ecx, int *edx, i
y = *ecx & 0xFFFF;
z = *edx * 16;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) {
*ebx = MONEY32_UNDEFINED;
return;
}
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LAND_PURCHASE * 4;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Y, uint16) = y;
@ -987,6 +992,10 @@ money32 map_buy_land_rights_for_tile(int x, int y, int setting, int flags) {
}
return 0;
default:
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode) {
return MONEY32_UNDEFINED;
}
if (x <= 32 || y <= 32) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3215;
return MONEY32_UNDEFINED;