From 5fbe85aded87fb05119f1590ffeb2cf98f9afd3c Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Wed, 21 May 2014 23:27:31 +0900 Subject: [PATCH] WIP: add ratings for crooked house --- src/finance.c | 4 +- src/news_item.c | 4 +- src/ride.h | 38 ++++++++++-- src/ride_ratings.c | 151 +++++++++++++++++++++++++++++++++++++++++++++ src/ride_ratings.h | 28 +++++++++ 5 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 src/ride_ratings.c create mode 100644 src/ride_ratings.h diff --git a/src/finance.c b/src/finance.c index dc6276455d..10a00f67ea 100644 --- a/src/finance.c +++ b/src/finance.c @@ -115,7 +115,7 @@ void finance_pay_ride_upkeep() if (ride->type == RIDE_TYPE_NULL) continue; - if (!(ride->var_1D0 & 0x1000)) { + if (!(ride->lifecycle_flags & 0x1000)) { ride->build_date = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16); ride->var_196 = 25855; // durability? @@ -179,4 +179,4 @@ void sub_69E869() { value += RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, sint32); value = ror32(value, 3); RCT2_GLOBAL(0x013587C4, sint32) = value; -} \ No newline at end of file +} diff --git a/src/news_item.c b/src/news_item.c index 4b5fa14e7c..8637c8eabd 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -205,8 +205,8 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * // Find which ride peep is on ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]); - // Check if there are trains on the track (first bit of var_1D0) - if (!(ride->var_1D0 & 1)) { + // Check if there are trains on the track (first bit of history_flags) + if (!(ride->lifecycle_flags & 1)) { *x = SPRITE_LOCATION_NULL; break; } diff --git a/src/ride.h b/src/ride.h index 84eb778120..a5c48298db 100644 --- a/src/ride.h +++ b/src/ride.h @@ -29,6 +29,8 @@ */ typedef struct { uint8 type; // 0x000 + // pointer to static info. for example, wild mouse type is 0x36, subtype is + // 0x4c. uint8 subtype; // 0x001 uint16 pad_002; uint8 mode; // 0x004 @@ -77,15 +79,22 @@ typedef struct { sint16 upkeep_cost; // 0x182 uint8 pad_184[0x12]; uint16 var_196; - uint8 pad_198; + // used in computing excitement, nausea, etc + uint8 var_198; uint8 var_199; uint8 pad_19A[0x1A]; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 - uint8 pad_1BC[0x12]; + uint8 pad_1BC[0x11]; + uint8 var_1CD; uint16 guests_favourite; // 0x1CE - uint32 var_1D0; - uint8 pad_1D4[0x2C]; + uint32 lifecycle_flags; + uint8 pad_1D4[0x20]; + // Example value for wild mouse ride is d5 (before it's been constructed) + // I tried searching the IDA file for "1F4" but couldn't find places where + // this is written to. + uint16 var_1F4; + uint8 pad_1F6[0x0a]; uint16 queue_length[4]; // 0x200 uint8 pad_208[0x58]; } rct_ride; @@ -105,6 +114,27 @@ enum { RIDE_CLASS_KIOSK_OR_FACILITY }; +// Constants used by the lifecycle_flags property at 0x1D0 +enum { + RIDE_LIFECYCLE_ON_TRACK = 1, + RIDE_LIFECYCLE_TESTED = 1 << 1, + RIDE_LIFECYCLE_TEST_IN_PROGRESS = 1 << 2, + RIDE_LIFECYCLE_NO_RAW_STATS = 1 << 3, + RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING = 1 << 4, + RIDE_LIFECYCLE_ON_RIDE_PHOTO = 1 << 5, + + RIDE_LIFECYCLE_BROKEN_DOWN = 1 << 7, + + RIDE_LIFECYCLE_CRASHED = 1 << 10, + + RIDE_LIFECYCLE_EVER_BEEN_OPENED = 1 << 12, + RIDE_LIFECYCLE_MUSIC = 1 << 13, + RIDE_LIFECYCLE_INDESTRUCTIBLE = 1 << 14, + RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK = 1 << 15, + + RIDE_LIFECYCLE_CABLE_LIFT = 1 << 17, +} + enum { RIDE_TYPE_NULL = 255, RIDE_TYPE_SPIRAL_ROLLER_COASTER = 0, diff --git a/src/ride_ratings.c b/src/ride_ratings.c new file mode 100644 index 0000000000..67e194a735 --- /dev/null +++ b/src/ride_ratings.c @@ -0,0 +1,151 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "ride.h" + +/** + * rct2: 0x0065C4D4 + * + * Compute excitement, intensity, etc. for a crooked house ride. + */ +void crooked_house_excitement(rct_ride *ride) +{ + // Set lifecycle bits + ride->lifecycle_flags |= RIDE_LIFECYCLE_TESTED; + ride->lifecycle_flags |= RIDE_LIFECYCLE_NO_RAW_STATS; + ride->var_198 = 5; + sub_655FD6(ride); + + excitement = 215; + intensity = 62; + nausea = 34; + + // NB this should get marked out by the compiler, if it's smart. + excitement = apply_intensity_penalty(excitement, intensity); + rating_tuple tup = per_ride_rating_adjustments(ride, excitement, intensity, nausea); + excitement = tup.excitement; + intensity = tup.intensity; + nausea = tup.nausea; + + ride->excitement = excitement; + ride->intensity = intensity; + ride->nausea = nausea; +} + +/** + * rct2: 0x0065E7FB + * + * inputs + * - bx: excitement + * - cx: intensity + * - bp: nausea + * - edi: ride ptr + */ +rating_tuple per_ride_rating_adjustments(rct_ride *ride, sint16 excitement, + sint16 intensity, sint16 nausea) +{ + // NB: The table here is allocated dynamically. Reading the exe will tell + // you nothing + subtype_p = RCT2_GLOBAL(0x009ACFA4 + ride->subtype * 4, uint32); + + // example value here: 12 (?) + sint16 ctr = RCT2_GLOBAL(subtype_p + 0x1b2); + excitement = excitement + ((excitement * ctr) >> 7); + + sint16 ctr = RCT2_GLOBAL(subtype_p + 0x1b3); + intensity = intensity + ((intensity * ctr) >> 7); + + sint16 ctr = RCT2_GLOBAL(subtype_p + 0x1b4); + nausea = nausea + ((nausea * ctr) >> 7); + + // As far as I can tell, this flag detects whether the ride is a roller + // coaster, or a log flume or rapids. Everything else it's not set. + // more detail: https://gist.github.com/kevinburke/d951e74e678b235eef3e + uint16 ridetype_var = RCT2_GLOBAL(ride->type * 8, uint16); + if (ridetype_var & 0x80) { + uint16 ax = ride->var_1F4; + if (RCT2_GLOBAL(subtype_p + 8, uint32) & 0x800) { + // 65e86e + ax = ax - 96; + if (ax >= 0) { + ax = ax >> 3; + excitement = excitement - ax; + ax = ax >> 1; + nausea = nausea - ax; + } + } else { + ax = ax >> 3; + excitement = excitement + ax; + ax = ax >> 1; + nausea += ax; + } + } + rating_tuple tup = {excitement, intensity, nausea}; + return tup; +} + +/** + * rct2: 0x0065E7A3 + * + * inputs from x86 + * - bx: excitement + * - cx: intensity + * - bp: nausea + * + * returns: the excitement level, with intensity penalties applied + */ +sint16 apply_intensity_penalty(sint16 excitement, sint16 intensity) +{ + // intensity penalty + if (intensity >= 1000) { + excitement = excitement - (excitement >> 2); + } + if (intensity >= 1100) { + excitement = excitement - (excitement >> 2); + } + if (intensity >= 1200) { + excitement = excitement - (excitement >> 2); + } + if (intensity >= 1320) { + excitement = excitement - (excitement >> 2); + } + if (intensity >= 1450) { + excitement = excitement - (excitement >> 2); + } + return excitement; +} + +/** + * rct2: 0x00655FD6 + * + * Take ride property 1CD, make some modifications, store the modified value in + * property 198. + */ +void sub_655FD6(rct_ride *ride) +{ + uint8 al = ride->var_1CD; + // No idea what this address is; maybe like compensation of some kind? The + // maximum possible value? + // List of ride names/values is here: + // https://gist.github.com/kevinburke/5eebcda14d94e6ee99c0 + al -= RCT2_ADDRESS(0x0097D7C9, uint8)[4 * ride->type]; + al = al << 1; + ride->var198 += al; +} diff --git a/src/ride_ratings.h b/src/ride_ratings.h new file mode 100644 index 0000000000..fb6c922efd --- /dev/null +++ b/src/ride_ratings.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2014 Kevin Burke + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +// Used for return values, for functions that modify all three. +typedef struct { + sint16 excitement; + sint16 intensity; + sint16 nausea; +} rating_tuple; + +void crooked_house_excitement(rct_ride *ride);