Merge pull request #5007 from IntelOrca/feature/rct1/import-vehicles

RCT1: import vehicles
This commit is contained in:
Ted John 2017-01-27 07:49:20 +00:00 committed by GitHub
commit 233a3040e1
15 changed files with 1216 additions and 265 deletions

View File

@ -8,6 +8,7 @@
- Feature: [#5113] Entertainers are now hired with a random costume.
- Improved: [#4847] Guest / staff pathfinding.
- Improved: [#4938] Checksum calculations speeded up.
- Improved: [#5007] Vehicles and functioning rides are now imported when loading SC4 / SV4 parks.
- Improved: Guests and staff are now imported when loading SC4 / SV4 parks.
- Fix: [#4571] Only start autosave timer after update or game command.
- Fix: [#4584] Junior Coaster diagonal flat-to-steep slopes not drawn.

View File

@ -729,14 +729,20 @@ void game_convert_strings_to_utf8()
}
}
// News items
for (sint32 i = 0; i < MAX_NEWS_ITEMS; i++) {
NewsItem *newsItem = news_item_get(i);
// News items
game_convert_news_items_to_utf8();
if (!str_is_null_or_empty(newsItem->Text)) {
rct2_to_utf8_self(newsItem->Text, sizeof(newsItem->Text));
}
}
}
void game_convert_news_items_to_utf8()
{
for (sint32 i = 0; i < MAX_NEWS_ITEMS; i++) {
NewsItem *newsItem = news_item_get(i);
if (!str_is_null_or_empty(newsItem->Text)) {
rct2_to_utf8_self(newsItem->Text, sizeof(newsItem->Text));
}
}
}
/**

View File

@ -181,6 +181,7 @@ void rct2_exit();
void rct2_exit_reason(rct_string_id title, rct_string_id body);
void game_autosave();
void game_convert_strings_to_utf8();
void game_convert_news_items_to_utf8();
void game_convert_strings_to_rct2(rct_s6_data *s6);
void game_fix_save_vars();
bool game_load_save_or_scenario(const utf8 * path);

View File

@ -4650,7 +4650,7 @@ static bool peep_update_fixing_sub_state_11(bool firstRun, rct_peep *peep, rct_r
peep_update_action(&tmp_x, &tmp_y, &tmp_xy_distance, peep);
if (peep->action_frame == 0x28) {
ride->mechanic_status = 4;
ride->mechanic_status = RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES;
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE;
}

View File

@ -27,8 +27,9 @@
#include "world/map.h"
#include "world/sprite.h"
#define RCT1_MAX_MAP_ELEMENTS 0xC000
#define RCT1_MAX_SPRITES 5000
#define RCT1_MAX_MAP_ELEMENTS 0xC000
#define RCT1_MAX_SPRITES 5000
#define RCT1_MAX_VEHICLES_PER_RIDE 12
#pragma pack(push, 1)
typedef struct rct1_entrance {
@ -52,7 +53,7 @@ typedef struct rct1_ride {
struct {
colour_t body;
colour_t trim;
} vehicle_colours[12];
} vehicle_colours[RCT1_MAX_VEHICLES_PER_RIDE];
colour_t track_primary_colour;
colour_t track_secondary_colour;
colour_t track_support_colour;
@ -70,7 +71,7 @@ typedef struct rct1_ride {
uint16 exit[4];
uint16 last_peep_in_queue[4];
uint8 num_peeps_in_queue[4];
uint16 vehicles[12];
uint16 vehicles[RCT1_MAX_VEHICLES_PER_RIDE];
uint8 depart_flags;
uint8 num_stations;
uint8 num_trains;
@ -156,11 +157,29 @@ typedef struct rct1_ride {
uint8 popularity_time_out;
uint8 popularity_next;
uint8 num_riders;
uint8 unk_10C[36];
sint16 build_date;
money16 upkeep_cost;
uint8 unk_134[15];
uint8 breakdown_reason;
uint8 music_tune_id; // 0x10C
uint8 slide_in_use; // 0x10D
union {
uint16 slide_peep; // 0x10E
uint16 maze_tiles; // 0x10E
};
uint8 pad_110[0xE];
uint8 slide_peep_t_shirt_colour;// 0x11E
uint8 pad_11F[0x7];
uint8 spiral_slide_progress; // 0x126
uint8 pad_127[0x9];
sint16 build_date; // 0x130
money16 upkeep_cost; // 0x131
uint16 race_winner; // 0x132
uint8 unk_134[2];
uint32 music_position; // 0x138
uint8 breakdown_reason_pending; // 0x13C
uint8 mechanic_status; // 0x13D
uint16 mechanic; // 0x13E
uint8 inspection_station; // 0x140
uint8 broken_vehicle; // 0x141
uint8 broken_car; // 0x142
uint8 breakdown_reason; // 0x143
uint8 unk_144[2];
uint16 reliability;
uint8 unreliability_factor;
@ -213,6 +232,122 @@ typedef struct rct1_unk_sprite {
uint8 var_71;
} rct1_unk_sprite;
typedef struct rct1_vehicle {
uint8 sprite_identifier; // 0x00
uint8 is_child; // 0x01
uint16 next_in_quadrant; // 0x02
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
// Height from center of sprite to bottom
uint8 sprite_height_negative; // 0x09
uint16 sprite_index; // 0x0A
uint16 flags; // 0x0C
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
// Width from center of sprite to edge
uint8 sprite_width; // 0x14
// Height from center of sprite to top
uint8 sprite_height_positive; // 0x15
sint16 sprite_left; // 0x16
sint16 sprite_top; // 0x18
sint16 sprite_right; // 0x1A
sint16 sprite_bottom; // 0x1C
uint8 sprite_direction; // 0x1E
uint8 vehicle_sprite_type; // 0x1F
uint8 bank_rotation; // 0x20
uint8 pad_21[3];
sint32 remaining_distance; // 0x24
sint32 velocity; // 0x28
sint32 acceleration; // 0x2C
uint8 ride; // 0x30
uint8 vehicle_type; // 0x31
rct_vehicle_colour colours; // 0x32
union {
uint16 track_progress; // 0x34
struct {
sint8 var_34;
uint8 var_35;
};
};
union {
sint16 track_direction; // 0x36 (0000 0000 0000 0011)
sint16 track_type; // 0x36 (0000 0011 1111 1100)
rct_xy8 boat_location; // 0x36
};
uint16 track_x; // 0x38
uint16 track_y; // 0x3A
uint16 track_z; // 0x3C
uint16 next_vehicle_on_train; // 0x3E
// The previous vehicle on the same train or the last vehicle on the previous or only train.
uint16 prev_vehicle_on_ride; // 0x40
// The next vehicle on the same train or the first vehicle on the next or only train
uint16 next_vehicle_on_ride; // 0x42
uint16 var_44;
uint16 friction; // 0x46
uint16 update_flags; // 0x48
uint8 var_4A;
uint8 current_station; // 0x4B
union {
sint16 swinging_car_var_0; // 0x4C
sint16 current_time; // 0x4C
struct {
sint8 ferris_wheel_var_0; // 0x4C
sint8 ferris_wheel_var_1; // 0x4D
};
};
sint16 var_4E;
uint8 status; // 0x50
uint8 sub_state; // 0x51
uint16 peep[32]; // 0x52
uint8 peep_tshirt_colours[32]; // 0x92
uint8 num_seats; // 0xB2
uint8 num_peeps; // 0xB3
uint8 next_free_seat; // 0xB4
uint8 restraints_position; // 0xB5 0 == Close, 255 == Open
sint16 var_B6;
uint16 var_B8;
uint8 var_BA;
uint8 sound1_id; // 0xBB
uint8 sound1_volume; // 0xBC
uint8 sound2_id; // 0xBD
uint8 sound2_volume; // 0xBE
sint8 var_BF;
union {
uint16 var_C0;
uint16 time_waiting; // 0xC0
uint16 cable_lift_target; // 0xC0
};
uint8 speed; // 0xC2
uint8 powered_acceleration; // 0xC3
uint8 var_C4;
uint8 var_C5;
uint8 pad_C6[0x2];
uint16 var_C8;
uint16 var_CA;
uint8 scream_sound_id; // 0xCC
uint8 var_CD;
union {
uint8 var_CE;
uint8 num_laps; // 0xCE
};
union {
uint8 var_CF;
uint8 brake_speed; // 0xCF
};
uint16 lost_time_out; // 0xD0
sint8 vertical_drop_countdown; // 0xD1
uint8 var_D3;
uint8 mini_golf_current_animation;
uint8 mini_golf_flags; // 0xD5
uint8 ride_subtype; // 0xD6
uint8 colours_extended; // 0xD7
} rct1_vehicle;
typedef struct rct1_peep {
uint8 sprite_identifier; // 0x00
uint8 misc_identifier; // 0x01
@ -405,6 +540,7 @@ enum RCT1_PEEP_SPRITE_TYPE {
typedef union rct1_sprite {
uint8 pad_00[0x100];
rct1_unk_sprite unknown;
rct1_vehicle vehicle;
rct1_peep peep;
rct_litter litter;
rct_balloon balloon;
@ -1003,7 +1139,54 @@ enum {
RCT1_PARK_FLAGS_LOCK_REAL_NAMES_OPTION = (1 << 15),
};
enum {
STEEL_RC_FRONT = 0,
STEEL_RC_CARRIAGE = 1,
WOODEN_RC_TRAIN = 2,
MONORAIL_CARRIAGE = 10,
MONORAIL_FRONT = 11,
MONORAIL_BACK = 12,
MINIATURE_RAILWAY_TENDER = 15,
MINIATURE_RAILWAY_LOCOMOTIVE = 16,
MINIATURE_RAILWAY_CARRIAGE = 17,
MINE_TRAIN_FRONT = 35,
MINE_TRAIN_CARRIAGE = 36,
CORKSCREW_RC_FRONT = 38,
CORKSCREW_RC_CARRIAGE = 39,
GHOST_TRAIN_CAR = 63,
TWISTER_RC_SPOILER = 64,
TWISTER_RC_CARRIAGE = 65,
GHOST_TRAIN_INVISIBLE = 66,
ARTICULATED_RC_FRONT = 67,
ARTICULATED_RC_CARRIAGE = 68,
MINIATURE_RAILWAY_CARRIAGE_COVERED = 71,
STANDUP_TWISTER_RC_CARRIAGE = 72,
REVERSER_RC_CAR = 79,
REVERSER_RC_BOGIE = 80,
MINIGOLF_PLAYER = 81,
MINIGOLF_BALL = 82,
HYPERCOASTER_FRONT = 96,
HYPERCOASTER_CARRIAGE = 97,
INVERTED_4_ACROSS_CARRIAGE = 98,
WATER_COASTER_BOAT = 99,
WATER_COASTER_INVISIBLE = 101,
RIVER_RAFT = 103,
};
enum {
COPY_COLOUR_1 = -1,
COPY_COLOUR_2 = -2,
};
enum {
RCT1_WATER_CYAN,
RCT1_WATER_ORANGE
};
#define RCT1_MAX_STATIONS 4
#define RCT1_MAX_TRAINS_PER_RIDE 12
#define RCT1_MAX_MAP_SIZE 128
#define RCT1_MAX_RIDES_IN_PARK 128
extern const uint8 gRideCategories[0x60];

File diff suppressed because it is too large Load Diff

View File

@ -24,15 +24,21 @@
namespace RCT1
{
struct RCT1VehicleColourSchemeCopyDescriptor {
sint8 colour1, colour2, colour3;
};
colour_t GetColour(colour_t colour);
uint8 GetPeepSpriteType(uint8 rct1SpriteType);
uint8 GetTerrain(uint8 terrain);
uint8 GetTerrainEdge(uint8 terrainEdge);
uint8 GetRideType(uint8 rideType);
RCT1VehicleColourSchemeCopyDescriptor GetColourSchemeCopyDescriptor(uint8 vehicleType);
bool RideTypeUsesVehicles(uint8 rideType);
bool PathIsQueue(uint8 pathType);
uint8 NormalisePathAddition(uint8 pathAdditionType);
uint8 GetVehicleSubEntryIndex(uint8 vehicleSubEntry);
const char * GetRideTypeObject(uint8 rideType);
const char * GetVehicleObject(uint8 vehicleType);
@ -42,6 +48,7 @@ namespace RCT1
const char * GetPathObject(uint8 pathType);
const char * GetPathAddtionObject(uint8 pathAdditionType);
const char * GetSceneryGroupObject(uint8 sceneryGroupType);
const char * GetWaterObject(uint8 waterType);
const std::vector<const char *> GetSceneryObjects(uint8 sceneryType);

View File

@ -67,7 +67,11 @@ namespace RCT1
COLOUR_BRIGHT_YELLOW,
COLOUR_ICY_BLUE
};
Guard::ArgumentInRange<size_t>(colour, 0, Util::CountOf(map), "Unsupported RCT1 colour.");
if (colour < 0 || colour >= Util::CountOf(map))
{
log_warning("Unsupported RCT1 colour.");
return COLOUR_BLACK;
}
return map[colour];
}
@ -75,39 +79,47 @@ namespace RCT1
{
static const uint8 map[] =
{
PEEP_SPRITE_TYPE_NORMAL,
PEEP_SPRITE_TYPE_HANDYMAN,
PEEP_SPRITE_TYPE_MECHANIC,
PEEP_SPRITE_TYPE_SECURITY,
PEEP_SPRITE_TYPE_ENTERTAINER_PANDA,
PEEP_SPRITE_TYPE_ENTERTAINER_TIGER,
PEEP_SPRITE_TYPE_ENTERTAINER_ELEPHANT,
PEEP_SPRITE_TYPE_ENTERTAINER_ROMAN,
PEEP_SPRITE_TYPE_ENTERTAINER_GORILLA,
PEEP_SPRITE_TYPE_ENTERTAINER_SNOWMAN,
PEEP_SPRITE_TYPE_ENTERTAINER_KNIGHT,
PEEP_SPRITE_TYPE_ENTERTAINER_ASTRONAUT,
PEEP_SPRITE_TYPE_NORMAL, // Not used
PEEP_SPRITE_TYPE_NORMAL, // Not used
PEEP_SPRITE_TYPE_NORMAL, // Not used
PEEP_SPRITE_TYPE_NORMAL, // Not used
PEEP_SPRITE_TYPE_BALLOON,
PEEP_SPRITE_TYPE_CANDYFLOSS,
PEEP_SPRITE_TYPE_UMBRELLA,
PEEP_SPRITE_TYPE_PIZZA,
PEEP_SPRITE_TYPE_SECURITY_ALT,
PEEP_SPRITE_TYPE_POPCORN,
PEEP_SPRITE_TYPE_ARMS_CROSSED,
PEEP_SPRITE_TYPE_HEAD_DOWN,
PEEP_SPRITE_TYPE_NAUSEOUS,
PEEP_SPRITE_TYPE_VERY_NAUSEOUS,
PEEP_SPRITE_TYPE_REQUIRE_BATHROOM,
PEEP_SPRITE_TYPE_HAT,
PEEP_SPRITE_TYPE_BURGER,
PEEP_SPRITE_TYPE_TENTACLE,
PEEP_SPRITE_TYPE_TOFFEE_APPLE
PEEP_SPRITE_TYPE_NORMAL, // 0x00
PEEP_SPRITE_TYPE_HANDYMAN, // 0x01
PEEP_SPRITE_TYPE_MECHANIC, // 0x02
PEEP_SPRITE_TYPE_SECURITY, // 0x03
PEEP_SPRITE_TYPE_ENTERTAINER_PANDA, // 0x04
PEEP_SPRITE_TYPE_ENTERTAINER_TIGER, // 0x05
PEEP_SPRITE_TYPE_ENTERTAINER_ELEPHANT, // 0x06
PEEP_SPRITE_TYPE_ENTERTAINER_ROMAN, // 0x07
PEEP_SPRITE_TYPE_ENTERTAINER_GORILLA, // 0x08
PEEP_SPRITE_TYPE_ENTERTAINER_SNOWMAN, // 0x09
PEEP_SPRITE_TYPE_ENTERTAINER_KNIGHT, // 0x0A
PEEP_SPRITE_TYPE_ENTERTAINER_ASTRONAUT, // 0x0B
PEEP_SPRITE_TYPE_ICE_CREAM, // 0x0C
PEEP_SPRITE_TYPE_FRIES, // 0x0D
PEEP_SPRITE_TYPE_BURGER, // 0x0E
PEEP_SPRITE_TYPE_DRINK, // 0x0F
PEEP_SPRITE_TYPE_BALLOON, // 0x10
PEEP_SPRITE_TYPE_CANDYFLOSS, // 0x11
PEEP_SPRITE_TYPE_UMBRELLA, // 0x12
PEEP_SPRITE_TYPE_PIZZA, // 0x13
PEEP_SPRITE_TYPE_SECURITY_ALT, // 0x14
PEEP_SPRITE_TYPE_POPCORN, // 0x15
PEEP_SPRITE_TYPE_ARMS_CROSSED, // 0x16
PEEP_SPRITE_TYPE_HEAD_DOWN, // 0x17
PEEP_SPRITE_TYPE_NAUSEOUS, // 0x18
PEEP_SPRITE_TYPE_VERY_NAUSEOUS, // 0x19
PEEP_SPRITE_TYPE_REQUIRE_BATHROOM, // 0x1A
PEEP_SPRITE_TYPE_HAT, // 0x1B
PEEP_SPRITE_TYPE_HOT_DOG, // 0x1C
PEEP_SPRITE_TYPE_TENTACLE, // 0x1D
PEEP_SPRITE_TYPE_TOFFEE_APPLE, // 0x1E
PEEP_SPRITE_TYPE_DONUT, // 0x1F
PEEP_SPRITE_TYPE_COFFEE, // 0x20
PEEP_SPRITE_TYPE_CHICKEN, // 0x21
PEEP_SPRITE_TYPE_LEMONADE, // 0x22
};
Guard::ArgumentInRange<size_t>(rct1SpriteType, 0, Util::CountOf(map), "Unsupported RCT1 sprite type.");
if (rct1SpriteType < 0 || rct1SpriteType > Util::CountOf(map))
{
log_warning("Unsupported RCT1 peep sprite type: %d.", rct1SpriteType);
return PEEP_SPRITE_TYPE_NORMAL;
}
return map[rct1SpriteType];
}
@ -256,6 +268,105 @@ namespace RCT1
return map[rideType];
}
RCT1VehicleColourSchemeCopyDescriptor GetColourSchemeCopyDescriptor(uint8 vehicleType)
{
static RCT1VehicleColourSchemeCopyDescriptor map[89] =
{
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEEL_ROLLER_COASTER_TRAIN = 0,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEEL_ROLLER_COASTER_TRAIN_BACKWARDS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WOODEN_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_INVERTED_COASTER_TRAIN, // Not in RCT2
{ COPY_COLOUR_1, COPY_COLOUR_2, COPY_COLOUR_2 }, // RCT1_VEHICLE_TYPE_SUSPENDED_SWINGING_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_LADYBIRD_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_1, COPY_COLOUR_2 }, // RCT1_VEHICLE_TYPE_STANDUP_ROLLER_COASTER_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SPINNING_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SINGLE_PERSON_SWINGING_CHAIRS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SWANS_PEDAL_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_DARK_BLUE }, // RCT1_VEHICLE_TYPE_LARGE_MONORAIL_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CANOES,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_ROWING_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEAM_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COPY_COLOUR_2 }, // RCT1_VEHICLE_TYPE_WOODEN_MOUSE_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_BUMPER_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WOODEN_ROLLER_COASTER_TRAIN_BACKWARDS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_ROCKET_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HORSES, // Steeplechase
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SPORTSCARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_LYING_DOWN_SWINGING_CARS, // Inverted single-rail
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WOODEN_MINE_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SUSPENDED_SWINGING_AIRPLANE_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SMALL_MONORAIL_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WATER_TRICYCLES,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_LAUNCHED_FREEFALL_CAR,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_BOBSLEIGH_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_DINGHIES,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_ROTATING_CABIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_MINE_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CHAIRLIFT_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CORKSCREW_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_MOTORBIKES,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_RACING_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_TRUCKS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_GO_KARTS,
{ COPY_COLOUR_1, COLOUR_BLACK, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_RAPIDS_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_LOG_FLUME_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_DODGEMS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SWINGING_SHIP,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SWINGING_INVERTER_SHIP,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_MERRY_GO_ROUND,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_FERRIS_WHEEL,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SIMULATOR_POD,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CINEMA_BUILDING,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_TOPSPIN_CAR,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SPACE_RINGS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_REVERSE_FREEFALL_ROLLER_COASTER_CAR,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_VERTICAL_ROLLER_COASTER_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CAT_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_TWIST_ARMS_AND_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HAUNTED_HOUSE_BUILDING,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_LOG_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CIRCUS_TENT,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_GHOST_TRAIN_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEEL_TWISTER_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WOODEN_TWISTER_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WOODEN_SIDE_FRICTION_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_VINTAGE_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEAM_TRAIN_COVERED_CARS,
{ COPY_COLOUR_1, COLOUR_BLACK, COPY_COLOUR_2 }, // RCT1_VEHICLE_TYPE_STAND_UP_STEEL_TWISTER_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_FLOORLESS_STEEL_TWISTER_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_STEEL_MOUSE_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CHAIRLIFT_CARS_ALTERNATIVE,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SUSPENDED_MONORAIL_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HELICOPTER_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_VIRGINIA_REEL_TUBS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_REVERSER_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_GOLFERS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_RIVER_RIDE_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_FLYING_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_NON_LOOPING_STEEL_TWISTER_ROLLER_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HEARTLINE_TWISTER_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HEARTLINE_TWISTER_CARS_REVERSED,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_RESERVED,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_ROTODROP_CAR,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_FLYING_SAUCERS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_CROOKED_HOUSE_BUILDING,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_BICYCLES,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_HYPERCOASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_4_ACROSS_INVERTED_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_WATER_COASTER_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_FACEOFF_CARS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_JET_SKIS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_RAFT_BOATS,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_AMERICAN_STYLE_STEAM_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_AIR_POWERED_COASTER_TRAIN,
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_SUSPENDED_WILD_MOUSE_CARS, // Inverted Hairpin in RCT2
{ COPY_COLOUR_1, COPY_COLOUR_2, COLOUR_BLACK }, // RCT1_VEHICLE_TYPE_ENTERPRISE_WHEEL
};
Guard::ArgumentInRange<size_t>(vehicleType, 0, Util::CountOf(map), "Unsupported RCT1 vehicle type.");
return map[vehicleType];
}
bool RideTypeUsesVehicles(uint8 rideType)
{
switch (rideType) {
@ -314,6 +425,270 @@ namespace RCT1
return pathAdditionType;
}
uint8 GetVehicleSubEntryIndex(uint8 vehicleSubEntry)
{
static const uint8 map[] =
{
0, // STEEL_RC_FRONT
1, // STEEL_RC_CARRIAGE
0,
0,
0,
0,
0,
0,
0,
0,
0, // MONORAIL_CARRIAGE
1, // MONORAIL_FRONT
2, // MONORAIL_BACK
0,
0,
1, // MINIATURE_RAILWAY_TENDER
0, // MINIATURE_RAILWAY_LOCOMOTIVE
2, // MINIATURE_RAILWAY_CARRIAGE
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // MINE_TRAIN_FRONT
1, // MINE_TRAIN_CARRIAGE
0,
0, // CORKSCREW_RC_FRONT
1, // CORKSCREW_RC_CARRIAGE
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // GHOST_TRAIN_CAR
1, // TWISTER_RC_SPOILER
0, // TWISTER_RC_CARRIAGE
1, // GHOST_TRAIN_INVISIBLE
0, // ARTICULATED_RC_FRONT
1, // ARTICULATED_RC_CARRIAGE
0,
0,
2, // MINIATURE_RAILWAY_CARRIAGE_COVERED
0, // STANDUP_TWISTER_RC_CARRIAGE
0,
0,
0,
0,
0,
0,
0, // REVERSER_RC_CAR
2, // REVERSER_RC_BOGIE
1, // MINIGOLF_PLAYER
0, // MINIGOLF_BALL
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // HYPERCOASTER_FRONT
1, // HYPERCOASTER_CARRIAGE
0, // INVERTED_4_ACROSS_CARRIAGE
0, // WATER_COASTER_BOAT
0,
1, // WATER_COASTER_INVISIBLE
0,
0, // RIVER_RAFT
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
return map[vehicleSubEntry];
}
const char * GetRideTypeObject(uint8 rideType)
{
static const char * map[] =
@ -997,9 +1372,7 @@ namespace RCT1
return map[sceneryGroupType];
}
#pragma warning(push)
#pragma warning(disable : 4505) // 'identifier' unreferenced local function has been removed
static const char * GetWaterObject(uint8 waterType)
const char * GetWaterObject(uint8 waterType)
{
static const char * map[] =
{
@ -1008,7 +1381,6 @@ namespace RCT1
};
return map[waterType];
}
#pragma warning(pop)
const std::vector<const char *> GetPreferedRideEntryOrder(uint8 rideType)
{

View File

@ -2498,7 +2498,7 @@ static void ride_breakdown_status_update(sint32 rideIndex)
if (
!(ride->not_fixed_timeout & 15) &&
ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING &&
ride->mechanic_status != RIDE_MECHANIC_STATUS_4
ride->mechanic_status != RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES
) {
set_format_arg(0, rct_string_id, ride->name);
set_format_arg(2, uint32, ride->name_arguments);
@ -2546,8 +2546,11 @@ static void ride_mechanic_status_update(sint32 rideIndex, sint32 mechanicStatus)
ride_call_closest_mechanic(rideIndex);
break;
case RIDE_MECHANIC_STATUS_HEADING:
mechanic = &(get_sprite(ride->mechanic)->peep);
if (
mechanic = NULL;
if (ride->mechanic != SPRITE_INDEX_NULL) {
mechanic = &(get_sprite(ride->mechanic)->peep);
}
if (mechanic == NULL ||
!peep_is_mechanic(mechanic) ||
(mechanic->state != PEEP_STATE_HEADING_TO_INSPECTION && mechanic->state != PEEP_STATE_ANSWERING) ||
mechanic->current_ride != rideIndex
@ -2558,8 +2561,11 @@ static void ride_mechanic_status_update(sint32 rideIndex, sint32 mechanicStatus)
}
break;
case RIDE_MECHANIC_STATUS_FIXING:
mechanic = &(get_sprite(ride->mechanic)->peep);
if (
mechanic = NULL;
if (ride->mechanic != SPRITE_INDEX_NULL) {
mechanic = &(get_sprite(ride->mechanic)->peep);
}
if (mechanic == NULL ||
!peep_is_mechanic(mechanic) ||
(
mechanic->state != PEEP_STATE_HEADING_TO_INSPECTION &&
@ -2702,8 +2708,8 @@ rct_peep *ride_get_assigned_mechanic(rct_ride *ride)
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) {
if (
ride->mechanic_status == RIDE_MECHANIC_STATUS_HEADING ||
ride->mechanic_status == 3 ||
ride->mechanic_status == 4
ride->mechanic_status == RIDE_MECHANIC_STATUS_FIXING ||
ride->mechanic_status == RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES
) {
rct_peep *peep = &(get_sprite(ride->mechanic)->peep);
if (peep_is_mechanic(peep))

View File

@ -662,7 +662,7 @@ enum {
RIDE_MECHANIC_STATUS_CALLING,
RIDE_MECHANIC_STATUS_HEADING,
RIDE_MECHANIC_STATUS_FIXING,
RIDE_MECHANIC_STATUS_4
RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES
};
enum {

View File

@ -37,6 +37,12 @@ static void facility_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 dir
rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
if (rideEntry == NULL || firstVehicleEntry == NULL)
{
log_error("Error drawing facility, rideEntry or firstVehicleEntry is NULL.");
return;
}
uint32 imageId = gTrackColours[SCHEME_TRACK];
imageId |= firstVehicleEntry->base_image_id;
imageId += (direction + 2) & 3;

View File

@ -37,6 +37,12 @@ static void shop_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 directi
rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
if (rideEntry == NULL || firstVehicleEntry == NULL)
{
log_error("Error drawing shop, rideEntry or firstVehicleEntry is NULL.");
return;
}
uint32 imageId = gTrackColours[SCHEME_TRACK];
if (imageId & 0x80000000) {
imageId &= 0x60FFFFFF;

View File

@ -188,7 +188,7 @@ static rct_track_td6 * track_design_open_from_td4(uint8 *src, size_t srcLength)
td6->version_and_colour_scheme = td4->version_and_colour_scheme;
// Vehicle colours
for (sint32 i = 0; i < 12; i++) {
for (sint32 i = 0; i < RCT1_MAX_VEHICLES_PER_RIDE; i++) {
td6->vehicle_colours[i].body_colour = rct1_get_colour(td4->vehicle_colours[i].body_colour);
td6->vehicle_colours[i].trim_colour = rct1_get_colour(td4->vehicle_colours[i].trim_colour);
@ -198,7 +198,7 @@ static rct_track_td6 * track_design_open_from_td4(uint8 *src, size_t srcLength)
}
}
// Set remaining vehicles to same colour as first vehicle
for (sint32 i = 12; i < 32; i++) {
for (sint32 i = RCT1_MAX_VEHICLES_PER_RIDE; i < 32; i++) {
td6->vehicle_colours[i] = td6->vehicle_colours[0];
}
// Set additional colour to trim colour for all vehicles

View File

@ -3344,7 +3344,7 @@ static void vehicle_update_arriving(rct_vehicle* vehicle)
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN &&
ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE &&
ride->inspection_station == vehicle->current_station &&
ride->mechanic_status != RIDE_MECHANIC_STATUS_4
ride->mechanic_status != RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES
) {
unkF64E35 = 0;
}
@ -7492,7 +7492,7 @@ loc_6DAEB9:
if (!(
ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN &&
ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE &&
ride->mechanic_status == RIDE_MECHANIC_STATUS_4
ride->mechanic_status == RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES
)) {
regs.eax = vehicle->brake_speed << 16;
if (regs.eax < _vehicleVelocityF64E08) {
@ -7507,15 +7507,9 @@ loc_6DAEB9:
}
}
else if (trackType == TRACK_ELEM_BOOSTER && ride->type != RIDE_TYPE_WILD_MOUSE) {
if (!(
ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN &&
ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE &&
ride->mechanic_status == RIDE_MECHANIC_STATUS_4
)) {
regs.eax = (vehicle->brake_speed << 16);
if (regs.eax > _vehicleVelocityF64E08) {
vehicle->acceleration = RideProperties[ride->type].acceleration << 16; //_vehicleVelocityF64E08 * 1.2;
}
regs.eax = (vehicle->brake_speed << 16);
if (regs.eax > _vehicleVelocityF64E08) {
vehicle->acceleration = RideProperties[ride->type].acceleration << 16; //_vehicleVelocityF64E08 * 1.2;
}
}

View File

@ -553,7 +553,7 @@ sint32 sawyercoding_detect_file_type(const uint8 *src, size_t length)
sint32 sawyercoding_detect_rct1_version(sint32 gameVersion)
{
sint32 fileType = (gameVersion) > 0 ? FILE_TYPE_SV4 : FILE_TYPE_SC4;
gameVersion=abs(gameVersion);
gameVersion = abs(gameVersion);
if (gameVersion >= 108000 && gameVersion < 110000)
return (FILE_VERSION_RCT1 | fileType);