2015-06-26 23:40:09 +02:00
|
|
|
#include "cheats.h"
|
2016-02-02 01:04:39 +01:00
|
|
|
#include "config.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "interface/window.h"
|
|
|
|
#include "network/network.h"
|
|
|
|
#include "world/climate.h"
|
|
|
|
#include "world/footpath.h"
|
|
|
|
#include "world/scenery.h"
|
2015-06-26 23:40:09 +02:00
|
|
|
|
|
|
|
bool gCheatsSandboxMode = false;
|
|
|
|
bool gCheatsDisableClearanceChecks = false;
|
|
|
|
bool gCheatsDisableSupportLimits = false;
|
2015-09-18 10:54:48 +02:00
|
|
|
bool gCheatsShowAllOperatingModes = false;
|
2015-10-12 15:58:15 +02:00
|
|
|
bool gCheatsShowVehiclesFromOtherTrackTypes = false;
|
2016-01-25 21:24:18 +01:00
|
|
|
bool gCheatsFastLiftHill = false;
|
|
|
|
bool gCheatsDisableBrakesFailure = false;
|
|
|
|
bool gCheatsDisableAllBreakdowns = false;
|
|
|
|
bool gCheatsUnlockAllPrices = false;
|
|
|
|
bool gCheatsBuildInPauseMode = false;
|
|
|
|
bool gCheatsIgnoreRideIntensity = false;
|
|
|
|
bool gCheatsDisableVandalism = false;
|
2016-02-15 15:55:36 +01:00
|
|
|
bool gCheatsNeverendingMarketing = false;
|
2016-02-17 17:39:33 +01:00
|
|
|
bool gCheatsFreezeClimate = false;
|
2015-06-26 23:40:09 +02:00
|
|
|
|
2016-02-02 01:04:39 +01:00
|
|
|
int park_rating_spinner_value;
|
|
|
|
|
|
|
|
#pragma region Cheat functions
|
|
|
|
|
|
|
|
static void cheat_set_grass_length(int length)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
rct_map_element *mapElement;
|
|
|
|
|
|
|
|
for (y = 0; y < 256; y++) {
|
|
|
|
for (x = 0; x < 256; x++) {
|
|
|
|
mapElement = map_get_surface_element_at(x, y);
|
|
|
|
if (!(mapElement->properties.surface.ownership & OWNERSHIP_OWNED))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (map_element_get_terrain(mapElement) != TERRAIN_GRASS)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((mapElement->properties.surface.terrain & 0x1F) > 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
mapElement->properties.surface.grass_length = length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_water_plants()
|
|
|
|
{
|
|
|
|
map_element_iterator it;
|
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
map_element_iterator it;
|
|
|
|
|
|
|
|
map_element_iterator_begin(&it);
|
|
|
|
do {
|
|
|
|
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_PATH)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!footpath_element_has_path_scenery(it.element))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
it.element->flags &= ~MAP_ELEMENT_FLAG_BROKEN;
|
|
|
|
} while (map_element_iterator_next(&it));
|
|
|
|
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_remove_litter()
|
|
|
|
{
|
|
|
|
rct_litter* litter;
|
|
|
|
uint16 spriteIndex, nextSpriteIndex;
|
|
|
|
|
|
|
|
for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) {
|
|
|
|
litter = &(g_sprite_list[spriteIndex].litter);
|
|
|
|
nextSpriteIndex = litter->next;
|
|
|
|
sprite_remove((rct_sprite*)litter);
|
|
|
|
}
|
|
|
|
|
|
|
|
map_element_iterator it;
|
|
|
|
rct_scenery_entry *sceneryEntry;
|
|
|
|
|
|
|
|
map_element_iterator_begin(&it);
|
|
|
|
do {
|
|
|
|
if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_PATH)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!footpath_element_has_path_scenery(it.element))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
sceneryEntry = g_pathBitSceneryEntries[footpath_element_get_path_scenery_index(it.element)];
|
|
|
|
if(sceneryEntry->path_bit.var_06 & (1 << 0))
|
|
|
|
it.element->properties.path.addition_status = 0xFF;
|
|
|
|
|
|
|
|
} while (map_element_iterator_next(&it));
|
|
|
|
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_fix_rides()
|
|
|
|
{
|
|
|
|
int rideIndex;
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_peep *mechanic;
|
|
|
|
|
|
|
|
FOR_ALL_RIDES(rideIndex, ride)
|
|
|
|
{
|
|
|
|
if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)))
|
|
|
|
{
|
|
|
|
mechanic = ride_get_assigned_mechanic(ride);
|
|
|
|
|
|
|
|
if (mechanic != NULL){
|
|
|
|
remove_peep_from_ride(mechanic);
|
|
|
|
}
|
|
|
|
|
|
|
|
ride_fix_breakdown(rideIndex, 0);
|
|
|
|
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_renew_rides()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
rct_ride *ride;
|
|
|
|
|
|
|
|
FOR_ALL_RIDES(i, ride)
|
|
|
|
{
|
|
|
|
// Set build date to current date (so the ride is brand new)
|
|
|
|
ride->build_date = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16);
|
|
|
|
// Set reliability to 100
|
|
|
|
ride->reliability = (100 << 8);
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_RIDE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_make_destructible()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
rct_ride *ride;
|
|
|
|
FOR_ALL_RIDES(i, ride)
|
|
|
|
{
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE)
|
|
|
|
ride->lifecycle_flags&=~RIDE_LIFECYCLE_INDESTRUCTIBLE;
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK)
|
|
|
|
ride->lifecycle_flags&=~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK;
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_RIDE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_reset_crash_status()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
rct_ride *ride;
|
|
|
|
|
|
|
|
FOR_ALL_RIDES(i, ride){
|
|
|
|
//reset crash status
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)
|
|
|
|
ride->lifecycle_flags&=~RIDE_LIFECYCLE_CRASHED;
|
|
|
|
//reset crash history
|
|
|
|
ride->last_crash_type=RIDE_CRASH_TYPE_NONE;
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_RIDE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_10_minute_inspections()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
rct_ride *ride;
|
|
|
|
|
|
|
|
FOR_ALL_RIDES(i, ride) {
|
|
|
|
// Set inspection interval to 10 minutes
|
|
|
|
ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES;
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_RIDE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_increase_money(money32 amount)
|
|
|
|
{
|
|
|
|
money32 currentMoney;
|
|
|
|
|
|
|
|
currentMoney = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32));
|
|
|
|
if (currentMoney < INT_MAX - amount)
|
|
|
|
currentMoney += amount;
|
|
|
|
else
|
|
|
|
currentMoney = INT_MAX;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(currentMoney);
|
|
|
|
|
|
|
|
window_invalidate_by_class(WC_FINANCES);
|
|
|
|
window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_clear_loan()
|
|
|
|
{
|
|
|
|
// First give money
|
|
|
|
game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_INCREASEMONEY, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), GAME_COMMAND_CHEAT, 0, 0);
|
|
|
|
|
|
|
|
// Then pay the loan
|
|
|
|
money32 newLoan;
|
|
|
|
newLoan = MONEY(0, 00);
|
|
|
|
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, newLoan, GAME_COMMAND_SET_CURRENT_LOAN, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_generate_guests(int count)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
generate_new_guest();
|
|
|
|
|
|
|
|
window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_set_guest_parameter(int parameter, int value)
|
|
|
|
{
|
|
|
|
int spriteIndex;
|
|
|
|
rct_peep *peep;
|
|
|
|
|
|
|
|
FOR_ALL_GUESTS(spriteIndex, peep) {
|
|
|
|
switch(parameter) {
|
|
|
|
case GUEST_PARAMETER_HAPPINESS:
|
|
|
|
peep->happiness = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_ENERGY:
|
|
|
|
peep->energy = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_HUNGER:
|
|
|
|
peep->hunger = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_THIRST:
|
|
|
|
peep->thirst = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_NAUSEA:
|
|
|
|
peep->nausea = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_NAUSEA_TOLERANCE:
|
|
|
|
peep->nausea_tolerance = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_BATHROOM:
|
|
|
|
peep->bathroom = value;
|
|
|
|
break;
|
|
|
|
case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY:
|
|
|
|
peep->intensity = (15 << 4) | value;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
peep_update_sprite_type(peep);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_give_all_guests(int object)
|
|
|
|
{
|
|
|
|
int spriteIndex;
|
|
|
|
rct_peep *peep;
|
|
|
|
|
|
|
|
FOR_ALL_GUESTS(spriteIndex, peep) {
|
|
|
|
switch(object)
|
|
|
|
{
|
|
|
|
case OBJECT_MONEY:
|
|
|
|
peep->cash_in_pocket = MONEY(1000,00);
|
|
|
|
break;
|
|
|
|
case OBJECT_PARK_MAP:
|
|
|
|
peep->item_standard_flags |= PEEP_ITEM_MAP;
|
|
|
|
break;
|
|
|
|
case OBJECT_BALLOON:
|
|
|
|
peep->item_standard_flags |= PEEP_ITEM_BALLOON;
|
|
|
|
peep->balloon_colour=scenario_rand_max(31);
|
|
|
|
peep_update_sprite_type(peep);
|
|
|
|
break;
|
|
|
|
case OBJECT_UMBRELLA:
|
|
|
|
peep->item_standard_flags |= PEEP_ITEM_UMBRELLA;
|
|
|
|
peep->umbrella_colour=scenario_rand_max(31);
|
|
|
|
peep_update_sprite_type(peep);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_PEEP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_remove_all_guests()
|
|
|
|
{
|
|
|
|
rct_peep *peep;
|
|
|
|
uint16 spriteIndex, nextSpriteIndex;
|
|
|
|
|
|
|
|
for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) {
|
|
|
|
peep = &(g_sprite_list[spriteIndex].peep);
|
|
|
|
nextSpriteIndex = peep->next;
|
|
|
|
if (peep->type == PEEP_TYPE_GUEST) {
|
|
|
|
peep_remove(peep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int i;
|
|
|
|
rct_ride *ride;
|
|
|
|
|
|
|
|
FOR_ALL_RIDES(i, ride)
|
|
|
|
{
|
|
|
|
ride_clear_for_construction(i);
|
|
|
|
ride_set_status(i, RIDE_STATUS_CLOSED);
|
|
|
|
|
|
|
|
for(int i=0;i<4;i++) {
|
|
|
|
ride->queue_length[i] = 0;
|
|
|
|
ride->last_peep_in_queue[i]=0xFFFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_RIDE);
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_explode_guests()
|
|
|
|
{
|
|
|
|
int sprite_index;
|
|
|
|
rct_peep *peep;
|
|
|
|
|
|
|
|
FOR_ALL_GUESTS(sprite_index, peep) {
|
|
|
|
if (scenario_rand_max(6) == 0) {
|
2016-02-23 18:22:19 +01:00
|
|
|
peep->peep_flags |= PEEP_FLAGS_EXPLODE;
|
2016-02-02 01:04:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cheat_set_staff_speed(uint8 value)
|
|
|
|
{
|
|
|
|
uint16 spriteIndex;
|
|
|
|
rct_peep *peep;
|
|
|
|
|
|
|
|
FOR_ALL_STAFF(spriteIndex, peep) {
|
|
|
|
peep->energy = value;
|
|
|
|
peep->energy_growth_rate = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
void game_command_cheat(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
|
|
|
|
{
|
|
|
|
int cheat = *ecx;
|
|
|
|
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
|
|
|
switch (cheat) {
|
|
|
|
case CHEAT_SANDBOXMODE: gCheatsSandboxMode = !gCheatsSandboxMode; window_invalidate_by_class(WC_MAP); window_invalidate_by_class(WC_FOOTPATH); break;
|
|
|
|
case CHEAT_DISABLECLEARANCECHECKS: gCheatsDisableClearanceChecks = !gCheatsDisableClearanceChecks; break;
|
|
|
|
case CHEAT_DISABLESUPPORTLIMITS: gCheatsDisableSupportLimits = !gCheatsDisableSupportLimits; break;
|
|
|
|
case CHEAT_SHOWALLOPERATINGMODES: gCheatsShowAllOperatingModes = !gCheatsShowAllOperatingModes; break;
|
|
|
|
case CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES: gCheatsShowVehiclesFromOtherTrackTypes = !gCheatsShowVehiclesFromOtherTrackTypes; break;
|
|
|
|
case CHEAT_FASTLIFTHILL: gCheatsFastLiftHill = !gCheatsFastLiftHill; break;
|
|
|
|
case CHEAT_DISABLEBRAKESFAILURE: gCheatsDisableBrakesFailure = !gCheatsDisableBrakesFailure; break;
|
|
|
|
case CHEAT_DISABLEALLBREAKDOWNS: gCheatsDisableAllBreakdowns = !gCheatsDisableAllBreakdowns; break;
|
|
|
|
case CHEAT_UNLOCKALLPRICES: gCheatsUnlockAllPrices = !gCheatsUnlockAllPrices; window_invalidate_by_class(WC_RIDE); window_invalidate_by_class(WC_PARK_INFORMATION); break;
|
|
|
|
case CHEAT_BUILDINPAUSEMODE: gCheatsBuildInPauseMode = !gCheatsBuildInPauseMode; break;
|
|
|
|
case CHEAT_IGNORERIDEINTENSITY: gCheatsIgnoreRideIntensity = !gCheatsIgnoreRideIntensity; break;
|
|
|
|
case CHEAT_DISABLEVANDALISM: gCheatsDisableVandalism = !gCheatsDisableVandalism; break;
|
|
|
|
case CHEAT_INCREASEMONEY: cheat_increase_money(*edx); break;
|
|
|
|
case CHEAT_CLEARLOAN: cheat_clear_loan(); break;
|
|
|
|
case CHEAT_SETGUESTPARAMETER: cheat_set_guest_parameter(*edx, *edi); break;
|
|
|
|
case CHEAT_GENERATEGUESTS: cheat_generate_guests(*edx); break;
|
|
|
|
case CHEAT_REMOVEALLGUESTS: cheat_remove_all_guests(); break;
|
|
|
|
case CHEAT_EXPLODEGUESTS: cheat_explode_guests(); break;
|
|
|
|
case CHEAT_GIVEALLGUESTS: cheat_give_all_guests(*edx); break;
|
|
|
|
case CHEAT_SETGRASSLENGTH: cheat_set_grass_length(*edx); break;
|
|
|
|
case CHEAT_WATERPLANTS: cheat_water_plants(); break;
|
|
|
|
case CHEAT_FIXVANDALISM: cheat_fix_vandalism(); break;
|
|
|
|
case CHEAT_REMOVELITTER: cheat_remove_litter(); break;
|
|
|
|
case CHEAT_SETSTAFFSPEED: cheat_set_staff_speed(*edx); break;
|
|
|
|
case CHEAT_RENEWRIDES: cheat_renew_rides(); break;
|
|
|
|
case CHEAT_MAKEDESTRUCTIBLE: cheat_make_destructible(); break;
|
|
|
|
case CHEAT_FIXRIDES: cheat_fix_rides(); break;
|
|
|
|
case CHEAT_RESETCRASHSTATUS: cheat_reset_crash_status(); break;
|
|
|
|
case CHEAT_10MINUTEINSPECTIONS: cheat_10_minute_inspections(); break;
|
|
|
|
case CHEAT_WINSCENARIO: scenario_success(); break;
|
|
|
|
case CHEAT_FORCEWEATHER: climate_force_weather(*edx); break;
|
2016-02-17 17:39:33 +01:00
|
|
|
case CHEAT_FREEZECLIMATE: gCheatsFreezeClimate = !gCheatsFreezeClimate; break;
|
2016-02-15 15:55:36 +01:00
|
|
|
case CHEAT_NEVERENDINGMARKETING: gCheatsNeverendingMarketing = !gCheatsNeverendingMarketing; break;
|
2016-02-02 01:04:39 +01:00
|
|
|
case CHEAT_OPENCLOSEPARK: park_set_open(park_is_open() ? 0 : 1); break;
|
|
|
|
case CHEAT_HAVEFUN: RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) = OBJECTIVE_HAVE_FUN; break;
|
|
|
|
case CHEAT_SETFORCEDPARKRATING: if(*edx > -1) { park_rating_spinner_value = *edx; } set_forced_park_rating(*edx); break;
|
|
|
|
}
|
|
|
|
if (network_get_mode() == NETWORK_MODE_NONE) {
|
|
|
|
config_save_default();
|
|
|
|
}
|
|
|
|
window_invalidate_by_class(WC_CHEATS);
|
|
|
|
}
|
|
|
|
*ebx = 0;
|
|
|
|
}
|
|
|
|
|
2015-06-26 23:40:09 +02:00
|
|
|
void cheats_reset()
|
|
|
|
{
|
|
|
|
gCheatsSandboxMode = false;
|
|
|
|
gCheatsDisableClearanceChecks = false;
|
|
|
|
gCheatsDisableSupportLimits = false;
|
2015-09-18 10:54:48 +02:00
|
|
|
gCheatsShowAllOperatingModes = false;
|
2015-10-12 15:58:15 +02:00
|
|
|
gCheatsShowVehiclesFromOtherTrackTypes = false;
|
2016-01-25 21:24:18 +01:00
|
|
|
gCheatsFastLiftHill = false;
|
|
|
|
gCheatsDisableBrakesFailure = false;
|
|
|
|
gCheatsDisableAllBreakdowns = false;
|
|
|
|
gCheatsUnlockAllPrices = false;
|
|
|
|
gCheatsBuildInPauseMode = false;
|
|
|
|
gCheatsIgnoreRideIntensity = false;
|
|
|
|
gCheatsDisableVandalism = false;
|
2016-02-17 17:39:33 +01:00
|
|
|
gCheatsNeverendingMarketing = false;
|
|
|
|
gCheatsFreezeClimate = false;
|
2015-06-26 23:40:09 +02:00
|
|
|
}
|