1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

implement mine train coaster rating calculation

This commit is contained in:
IntelOrca
2014-10-11 23:07:20 +01:00
parent 13b4280404
commit c91c4f7ea0
3 changed files with 170 additions and 7 deletions

View File

@@ -117,7 +117,8 @@ typedef struct {
uint8 var_0D0;
uint8 pad_0D1[0x3];
uint8 measurement_index; // 0x0D4
uint8 pad_0D5[0x3];
uint8 var_0D5;
uint8 pad_0D6[0x2];
sint32 max_speed; // 0x0D8
sint32 average_speed; // 0x0DC
uint8 pad_0E0[0x4];
@@ -126,13 +127,21 @@ typedef struct {
fixed16_2dp max_positive_vertical_g; // 0x0FC
fixed16_2dp max_negative_vertical_g; // 0x0FE
fixed16_2dp max_lateral_g; // 0x100
uint8 pad_102[0x12];
uint8 inversions; // 0x114 (???X XXXX) holes for mini golf
uint8 pad_102[0xC];
uint16 var_10E;
uint16 var_110;
uint16 var_112;
union {
uint8 inversions; // 0x114 (???X XXXX)
uint8 holes; // 0x114 (???X XXXX)
};
uint8 drops; // 0x115 (??XX XXXX)
uint8 pad_116;
uint8 highest_drop_height; // 0x117
uint32 var_118;
uint8 pad_11C[0x08];
uint8 pad_11C[0x02];
uint8 var_11E;
uint8 pad_11F[0x05];
sint16 var_124;
sint16 var_126;
sint16 var_128;

View File

@@ -604,6 +604,10 @@ static int sub_65E72D(rct_ride *ride)
return edx & 0xFFFF;
}
/**
*
* rct2: 0x0065DDD1
*/
static rating_tuple sub_65DDD1(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
@@ -614,6 +618,10 @@ static rating_tuple sub_65DDD1(rct_ride *ride)
return rating;
}
/**
*
* rct2: 0x0065E1C2
*/
static rating_tuple sub_65E1C2(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
@@ -624,6 +632,34 @@ static rating_tuple sub_65E1C2(rct_ride *ride)
return rating;
}
/**
*
* rct2: 0x0065DCDC
*/
static rating_tuple ride_ratings_get_gforce_ratings(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
edi = (int)ride;
RCT2_CALLFUNC_X(0x0065DCDC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
rating_tuple rating = { ebx, ecx, ebp };
return rating;
}
/**
*
* rct2: 0x0065E139
*/
static rating_tuple ride_ratings_get_drop_ratings(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
edi = (int)ride;
RCT2_CALLFUNC_X(0x0065E139, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
rating_tuple rating = { ebx, ecx, ebp };
return rating;
}
/**
* Calculates a score based on the surrounding scenery.
* rct2: 0x0065E557
@@ -675,6 +711,124 @@ static int ride_ratings_get_scenery_score(rct_ride *ride)
#pragma region Ride rating calculation functions
static void ride_ratings_calculate_mine_train_coaster(rct_ride *ride)
{
rating_tuple ratings, unkRating;
int totalLength, time;
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED))
return;
ride->var_198 = 16;
sub_655FD6(ride);
// Base ratings
ratings.excitement = RIDE_RATING(2,90);
ratings.intensity = RIDE_RATING(2,30);
ratings.nausea = RIDE_RATING(2,10);
// Apply length of ride factor
totalLength = (ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3]) >> 16;
ratings.excitement += (min(6000, totalLength) * 764) >> 16;
// Apply racing coaster factor
if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS) {
ratings.excitement += RIDE_RATING(0,40);
ratings.intensity += RIDE_RATING(0,05);
}
// Apply length of train factor
ratings.excitement += ((ride->num_cars_per_train - 1) * 187245) >> 16;
// Apply maximum speed factor
ratings.excitement += ((ride->max_speed >> 16) * 44281) >> 16;
ratings.intensity += ((ride->max_speed >> 16) * 88562) >> 16;
ratings.nausea += ((ride->max_speed >> 16) * 35424) >> 16;
// Apply average speed factor
ratings.excitement += ((ride->average_speed >> 16) * 291271) >> 16;
ratings.intensity += ((ride->average_speed >> 16) * 436906) >> 16;
// Apply ride duration factor
time = ride->time[0] + ride->time[1] + ride->time[2] + ride->time[3];
ratings.excitement += (min(150, time) * 26214) >> 16;
// Apply G forces factor
unkRating = ride_ratings_get_gforce_ratings(ride);
ratings.excitement += (unkRating.excitement * 40960) >> 16;
ratings.intensity += (unkRating.intensity * 35746) >> 16;
ratings.nausea += (unkRating.nausea * 49648) >> 16;
// Apply ?
unkRating = sub_65DDD1(ride);
ratings.excitement += (unkRating.excitement * 29721) >> 16;
ratings.intensity += (unkRating.intensity * 34767) >> 16;
ratings.nausea += (unkRating.nausea * 45749) >> 16;
// Apply drops factor
unkRating = ride_ratings_get_drop_ratings(ride);
ratings.excitement += (unkRating.excitement * 29127) >> 16;
ratings.intensity += (unkRating.intensity * 46811) >> 16;
ratings.nausea += (unkRating.nausea * 49152) >> 16;
// Apply ?
unkRating = sub_65E1C2(ride);
ratings.excitement += (unkRating.excitement * 19275) >> 16;
ratings.intensity += (unkRating.intensity * 32768) >> 16;
ratings.nausea += (unkRating.nausea * 35108) >> 16;
// Apply ?
ratings.excitement += (sub_65E277() * 21472) >> 16;
ratings.excitement += (ride_ratings_get_scenery_score(ride) * 16732) >> 16;
// Apply low highest drop penalty
if (ride->highest_drop_height < 8) {
ride->excitement /= 2;
ride->intensity /= 2;
ride->nausea /= 2;
}
// Apply low max speed penalty
if (ride->max_speed < 0xA0000) {
ride->excitement /= 2;
ride->intensity /= 2;
ride->nausea /= 2;
}
// Apply low maximum negative vertical G force penalty
if (ride->max_negative_vertical_g > FIXED_2DP(0,10)) {
ride->excitement /= 2;
ride->intensity /= 2;
ride->nausea /= 2;
}
// Apply short ride penalty
if (ride->length[0] < 0x1720000) {
ride->excitement /= 2;
ride->intensity /= 2;
ride->nausea /= 2;
}
// Apply low number of drops penalty
if ((ride->drops & 0x3F) < 2) {
ride->excitement /= 2;
ride->intensity /= 2;
ride->nausea /= 2;
}
ride_ratings_apply_intensity_penalty(&ratings);
ride_ratings_apply_adjustments(ride, &ratings);
ride->ratings = ratings;
ride->upkeep_cost = ride_compute_upkeep(ride);
ride->var_14D |= 2;
ride->inversions &= 0x1F;
ride->inversions |= sub_65E72D(ride) << 5;
}
static void ride_ratings_calculate_maze(rct_ride *ride)
{
rating_tuple ratings;
@@ -890,7 +1044,7 @@ static void ride_ratings_calculate_mini_golf(rct_ride *ride)
ratings.excitement += (ride_ratings_get_scenery_score(ride) * 27887) >> 16;
// Apply golf holes factor
ratings.excitement += (ride->inversions & 0x1F) * 5;
ratings.excitement += (ride->holes & 0x1F) * 5;
// Apply no golf holes penalty
if ((ride->inversions & 0x1F) == 0) {
@@ -965,7 +1119,7 @@ static const ride_ratings_calculation ride_ratings_calculate_func_table[91] = {
NULL, // OBSERVATION_TOWER
NULL, // LOOPING_ROLLER_COASTER
NULL, // DINGHY_SLIDE
NULL, // MINE_TRAIN_COASTER
ride_ratings_calculate_mine_train_coaster, // MINE_TRAIN_COASTER
NULL, // CHAIRLIFT
NULL, // CORKSCREW_ROLLER_COASTER
ride_ratings_calculate_maze, // MAZE

View File

@@ -4602,7 +4602,7 @@ static void window_ride_measurements_paint()
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_NO_RAW_STATS)) {
if (ride->type == RIDE_TYPE_MINI_GOLF) {
// Holes
holes = ride->inversions & 0x1F;
holes = ride->holes & 0x1F;
gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y);
y += 10;
} else {