mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fixed few multiplayer desync issues. (#5578)
This addresses some of the desync causes: * `vehicle_create_car` was using `scenario_rand` when it shouldn't have * ghost elements affected grass growth * ghost elements affecting peep logic[1] It also adds some desync debug facilities, enabled at compile time. It also reverts part of change introduced in https://github.com/OpenRCT2/OpenRCT2/pull/5185, namely reorder of desync check vs call to `ProcessGameCommandQueue();` [1] It is not ideal to have this check in multiple locations, it is prone to human error. We already have `map_remove_provisional_elements`, but it is possible it does not work as well as it should. This needs further investigation.
This commit is contained in:
parent
0757582c93
commit
60bf5083fc
|
@ -78,6 +78,7 @@ Includes all git commit authors. Aliases are GitHub user names.
|
||||||
* Marco Benzi Tobar (Lisergishnu)
|
* Marco Benzi Tobar (Lisergishnu)
|
||||||
* Richard Jenkins (rwjuk)
|
* Richard Jenkins (rwjuk)
|
||||||
* (ceeac)
|
* (ceeac)
|
||||||
|
* Matthias Moninger (Zeh Matt)
|
||||||
|
|
||||||
## Toolchain
|
## Toolchain
|
||||||
* (Balletie) - macOS
|
* (Balletie) - macOS
|
||||||
|
|
|
@ -305,6 +305,10 @@ void game_update()
|
||||||
// Update the animation list. Note this does not
|
// Update the animation list. Note this does not
|
||||||
// increment the map animation.
|
// increment the map animation.
|
||||||
map_animation_invalidate_all();
|
map_animation_invalidate_all();
|
||||||
|
|
||||||
|
// Special case because we set numUpdates to 0, otherwise in game_logic_update.
|
||||||
|
game_handle_input();
|
||||||
|
network_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the game one or more times
|
// Update the game one or more times
|
||||||
|
@ -337,6 +341,28 @@ void game_update()
|
||||||
window_dispatch_update_all();
|
window_dispatch_update_all();
|
||||||
|
|
||||||
gGameCommandNestLevel = 0;
|
gGameCommandNestLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void game_logic_update()
|
||||||
|
{
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
gInUpdateCode = true;
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
network_update();
|
||||||
|
|
||||||
|
if (network_get_mode() == NETWORK_MODE_CLIENT && network_get_status() == NETWORK_STATUS_CONNECTED && network_get_authstatus() == NETWORK_AUTH_OK) {
|
||||||
|
// Can't be in sync with server, round trips won't work if we are at same level.
|
||||||
|
if (gCurrentTicks >= network_get_server_tick()) {
|
||||||
|
// Don't run past the server
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gScreenAge++;
|
||||||
|
if (gScreenAge == 0)
|
||||||
|
gScreenAge--;
|
||||||
|
|
||||||
if (!gOpenRCT2Headless)
|
if (!gOpenRCT2Headless)
|
||||||
{
|
{
|
||||||
|
@ -366,25 +392,6 @@ void game_update()
|
||||||
gUnk141F568 = gUnk13CA740;
|
gUnk141F568 = gUnk13CA740;
|
||||||
game_handle_input();
|
game_handle_input();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void game_logic_update()
|
|
||||||
{
|
|
||||||
///////////////////////////
|
|
||||||
gInUpdateCode = true;
|
|
||||||
///////////////////////////
|
|
||||||
network_update();
|
|
||||||
if (network_get_mode() == NETWORK_MODE_CLIENT && network_get_status() == NETWORK_STATUS_CONNECTED && network_get_authstatus() == NETWORK_AUTH_OK) {
|
|
||||||
if (gCurrentTicks >= network_get_server_tick()) {
|
|
||||||
// Don't run past the server
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gCurrentTicks++;
|
|
||||||
gScenarioTicks++;
|
|
||||||
gScreenAge++;
|
|
||||||
if (gScreenAge == 0)
|
|
||||||
gScreenAge--;
|
|
||||||
|
|
||||||
sub_68B089();
|
sub_68B089();
|
||||||
scenario_update();
|
scenario_update();
|
||||||
|
@ -403,6 +410,7 @@ void game_logic_update()
|
||||||
ride_ratings_update_all();
|
ride_ratings_update_all();
|
||||||
ride_measurements_update();
|
ride_measurements_update();
|
||||||
news_item_update_current();
|
news_item_update_current();
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
gInUpdateCode = false;
|
gInUpdateCode = false;
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
@ -413,8 +421,6 @@ void game_logic_update()
|
||||||
climate_update_sound();
|
climate_update_sound();
|
||||||
editor_open_windows_for_current_step();
|
editor_open_windows_for_current_step();
|
||||||
|
|
||||||
gSavedAge++;
|
|
||||||
|
|
||||||
// Update windows
|
// Update windows
|
||||||
//window_dispatch_update_all();
|
//window_dispatch_update_all();
|
||||||
|
|
||||||
|
@ -431,8 +437,13 @@ void game_logic_update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start autosave timer after update
|
// Start autosave timer after update
|
||||||
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE)
|
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE) {
|
||||||
gLastAutoSaveUpdate = platform_get_ticks();
|
gLastAutoSaveUpdate = platform_get_ticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
gCurrentTicks++;
|
||||||
|
gScenarioTicks++;
|
||||||
|
gSavedAge++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -561,7 +572,8 @@ sint32 game_do_command_p(sint32 command, sint32 *eax, sint32 *ebx, sint32 *ecx,
|
||||||
|
|
||||||
// Do the callback (required for multiplayer to work correctly), but only for top level commands
|
// Do the callback (required for multiplayer to work correctly), but only for top level commands
|
||||||
if (gGameCommandNestLevel == 1) {
|
if (gGameCommandNestLevel == 1) {
|
||||||
if (game_command_callback && !(flags & GAME_COMMAND_FLAG_GHOST)) {
|
if (game_command_callback && !(flags & GAME_COMMAND_FLAG_GHOST))
|
||||||
|
{
|
||||||
game_command_callback(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp);
|
game_command_callback(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp);
|
||||||
game_command_callback = 0;
|
game_command_callback = 0;
|
||||||
}
|
}
|
||||||
|
@ -1399,6 +1411,8 @@ void game_load_or_quit_no_save_prompt()
|
||||||
*/
|
*/
|
||||||
void game_init_all(sint32 mapSize)
|
void game_init_all(sint32 mapSize)
|
||||||
{
|
{
|
||||||
|
gInUpdateCode = true;
|
||||||
|
|
||||||
map_init(mapSize);
|
map_init(mapSize);
|
||||||
park_init();
|
park_init();
|
||||||
finance_init();
|
finance_init();
|
||||||
|
@ -1412,6 +1426,8 @@ void game_init_all(sint32 mapSize)
|
||||||
news_item_init_queue();
|
news_item_init_queue();
|
||||||
user_string_clear_all();
|
user_string_clear_all();
|
||||||
|
|
||||||
|
gInUpdateCode = false;
|
||||||
|
|
||||||
window_new_ride_init_vars();
|
window_new_ride_init_vars();
|
||||||
window_guest_list_init_vars_a();
|
window_guest_list_init_vars_a();
|
||||||
window_guest_list_init_vars_b();
|
window_guest_list_init_vars_b();
|
||||||
|
|
|
@ -520,8 +520,11 @@ void Network::UpdateClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check synchronisation
|
// Check synchronisation
|
||||||
|
ProcessGameCommandQueue();
|
||||||
|
|
||||||
if (!_desynchronised && !CheckSRAND(gCurrentTicks, gScenarioSrand0)) {
|
if (!_desynchronised && !CheckSRAND(gCurrentTicks, gScenarioSrand0)) {
|
||||||
_desynchronised = true;
|
_desynchronised = true;
|
||||||
|
|
||||||
char str_desync[256];
|
char str_desync[256];
|
||||||
format_string(str_desync, 256, STR_MULTIPLAYER_DESYNC, NULL);
|
format_string(str_desync, 256, STR_MULTIPLAYER_DESYNC, NULL);
|
||||||
window_network_status_open(str_desync, NULL);
|
window_network_status_open(str_desync, NULL);
|
||||||
|
@ -530,7 +533,6 @@ void Network::UpdateClient()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessGameCommandQueue();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,12 +616,17 @@ bool Network::CheckSRAND(uint32 tick, uint32 srand0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tick == server_srand0_tick) {
|
if (tick == server_srand0_tick)
|
||||||
|
{
|
||||||
server_srand0_tick = 0;
|
server_srand0_tick = 0;
|
||||||
// Check that the server and client sprite hashes match
|
// Check that the server and client sprite hashes match
|
||||||
const bool sprites_mismatch = server_sprite_hash[0] != '\0' && strcmp(sprite_checksum(), server_sprite_hash);
|
const char *client_sprite_hash = sprite_checksum();
|
||||||
|
const bool sprites_mismatch = server_sprite_hash[0] != '\0' && strcmp(client_sprite_hash, server_sprite_hash);
|
||||||
// Check PRNG values and sprite hashes, if exist
|
// Check PRNG values and sprite hashes, if exist
|
||||||
if ((srand0 != server_srand0) || sprites_mismatch) {
|
if ((srand0 != server_srand0) || sprites_mismatch) {
|
||||||
|
#ifdef DEBUG_DESYNC
|
||||||
|
dbg_report_desync(tick, srand0, server_srand0, client_sprite_hash, server_sprite_hash);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1322,13 @@ void Network::ProcessPacket(NetworkConnection& connection, NetworkPacket& packet
|
||||||
|
|
||||||
void Network::ProcessGameCommandQueue()
|
void Network::ProcessGameCommandQueue()
|
||||||
{
|
{
|
||||||
while (game_command_queue.begin() != game_command_queue.end() && game_command_queue.begin()->tick == gCurrentTicks) {
|
while (game_command_queue.begin() != game_command_queue.end()) {
|
||||||
|
// If our tick is higher than the command tick we are in trouble.
|
||||||
|
assert(game_command_queue.begin()->tick >= gCurrentTicks);
|
||||||
|
|
||||||
|
if (game_command_queue.begin()->tick != gCurrentTicks)
|
||||||
|
return;
|
||||||
|
|
||||||
// run all the game commands at the current tick
|
// run all the game commands at the current tick
|
||||||
const GameCommand& gc = (*game_command_queue.begin());
|
const GameCommand& gc = (*game_command_queue.begin());
|
||||||
if (GetPlayerID() == gc.playerid) {
|
if (GetPlayerID() == gc.playerid) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ extern "C" {
|
||||||
// This define specifies which version of network stream current build uses.
|
// This define specifies which version of network stream current build uses.
|
||||||
// It is used for making sure only compatible builds get connected, even within
|
// It is used for making sure only compatible builds get connected, even within
|
||||||
// single OpenRCT2 version.
|
// single OpenRCT2 version.
|
||||||
#define NETWORK_STREAM_VERSION "10"
|
#define NETWORK_STREAM_VERSION "11"
|
||||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -174,6 +174,12 @@ static void peep_update_ride_inspected(sint32 rideIndex);
|
||||||
|
|
||||||
bool loc_690FD0(rct_peep *peep, uint8 *rideToView, uint8 *rideSeatToView, rct_map_element *esi);
|
bool loc_690FD0(rct_peep *peep, uint8 *rideToView, uint8 *rideSeatToView, rct_map_element *esi);
|
||||||
|
|
||||||
|
#ifdef DEBUG_DESYNC
|
||||||
|
#define peep_rand() scenario_rand_data(peep)
|
||||||
|
#else
|
||||||
|
#define peep_rand() scenario_rand()
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *gPeepEasterEggNames[] = {
|
const char *gPeepEasterEggNames[] = {
|
||||||
"MICHAEL SCHUMACHER",
|
"MICHAEL SCHUMACHER",
|
||||||
"JACQUES VILLENEUVE",
|
"JACQUES VILLENEUVE",
|
||||||
|
@ -736,7 +742,7 @@ static void peep_decide_whether_to_leave_park(rct_peep *peep)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Approx 95% chance of staying in the park
|
// Approx 95% chance of staying in the park
|
||||||
if ((scenario_rand() & 0xFFFF) > 3276) {
|
if ((peep_rand() & 0xFFFF) > 3276) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,7 +925,7 @@ static void sub_68F41A(rct_peep *peep, sint32 index)
|
||||||
* to reduce how often the content in this conditional
|
* to reduce how often the content in this conditional
|
||||||
* is executed to once every four calls. */
|
* is executed to once every four calls. */
|
||||||
if (peep->peep_flags & PEEP_FLAGS_CROWDED){
|
if (peep->peep_flags & PEEP_FLAGS_CROWDED){
|
||||||
uint8 thought_type = crowded_thoughts[scenario_rand() & 0xF];
|
uint8 thought_type = crowded_thoughts[peep_rand() & 0xF];
|
||||||
if (thought_type != PEEP_THOUGHT_TYPE_NONE){
|
if (thought_type != PEEP_THOUGHT_TYPE_NONE){
|
||||||
peep_insert_new_thought(peep, thought_type, 0xFF);
|
peep_insert_new_thought(peep, thought_type, 0xFF);
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1022,7 @@ static void sub_68F41A(rct_peep *peep, sint32 index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFFFF) <= ((peep->item_standard_flags & PEEP_ITEM_MAP) ? 8192U : 2184U)){
|
if ((peep_rand() & 0xFFFF) <= ((peep->item_standard_flags & PEEP_ITEM_MAP) ? 8192U : 2184U)){
|
||||||
peep_pick_ride_to_go_on(peep);
|
peep_pick_ride_to_go_on(peep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,7 +1078,7 @@ static void sub_68F41A(rct_peep *peep, sint32 index)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_thoughts != 0){
|
if (num_thoughts != 0){
|
||||||
uint8 chosen_thought = possible_thoughts[scenario_rand() % num_thoughts];
|
uint8 chosen_thought = possible_thoughts[peep_rand() % num_thoughts];
|
||||||
|
|
||||||
peep_insert_new_thought(peep, chosen_thought, 0xFF);
|
peep_insert_new_thought(peep, chosen_thought, 0xFF);
|
||||||
|
|
||||||
|
@ -1214,7 +1220,7 @@ static void sub_68F41A(rct_peep *peep, sint32 index)
|
||||||
if (peep->state == PEEP_STATE_WALKING &&
|
if (peep->state == PEEP_STATE_WALKING &&
|
||||||
peep->nausea_growth_rate >= 128){
|
peep->nausea_growth_rate >= 128){
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFF) <= (uint8)((peep->nausea - 128) / 2)){
|
if ((peep_rand() & 0xFF) <= (uint8)((peep->nausea - 128) / 2)){
|
||||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||||
peep->action = PEEP_ACTION_THROW_UP;
|
peep->action = PEEP_ACTION_THROW_UP;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
|
@ -1623,7 +1629,7 @@ static sint32 peep_update_action(sint16* x, sint16* y, sint16* xy_distance, rct_
|
||||||
// Create sick at location
|
// Create sick at location
|
||||||
litter_create(peep->x, peep->y, peep->z, peep->sprite_direction, (peep->sprite_index & 1) ? LITTER_TYPE_SICK_ALT: LITTER_TYPE_SICK);
|
litter_create(peep->x, peep->y, peep->z, peep->sprite_direction, (peep->sprite_index & 1) ? LITTER_TYPE_SICK_ALT: LITTER_TYPE_SICK);
|
||||||
|
|
||||||
sint32 sound_id = SOUND_COUGH_1 + (scenario_rand() & 3);
|
sint32 sound_id = SOUND_COUGH_1 + (peep_rand() & 3);
|
||||||
audio_play_sound_at_location(sound_id, peep->x, peep->y, peep->z);
|
audio_play_sound_at_location(sound_id, peep->x, peep->y, peep->z);
|
||||||
|
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
@ -1727,11 +1733,11 @@ void peep_update_sprite_type(rct_peep* peep)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
peep->sprite_type == PEEP_SPRITE_TYPE_BALLOON &&
|
peep->sprite_type == PEEP_SPRITE_TYPE_BALLOON &&
|
||||||
(scenario_rand() & 0xFFFF) <= 327
|
(peep_rand() & 0xFFFF) <= 327
|
||||||
) {
|
) {
|
||||||
bool isBalloonPopped = false;
|
bool isBalloonPopped = false;
|
||||||
if (peep->x != SPRITE_LOCATION_NULL) {
|
if (peep->x != SPRITE_LOCATION_NULL) {
|
||||||
if ((scenario_rand() & 0xFFFF) <= 13107) {
|
if ((peep_rand() & 0xFFFF) <= 13107) {
|
||||||
isBalloonPopped = true;
|
isBalloonPopped = true;
|
||||||
audio_play_sound_at_location(SOUND_BALLOON_POP, peep->x, peep->y, peep->z);
|
audio_play_sound_at_location(SOUND_BALLOON_POP, peep->x, peep->y, peep->z);
|
||||||
}
|
}
|
||||||
|
@ -2260,7 +2266,7 @@ static void peep_update_sitting(rct_peep* peep){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peep_has_food(peep)){
|
if (peep_has_food(peep)){
|
||||||
if ((scenario_rand() & 0xFFFF) > 1310){
|
if ((peep_rand() & 0xFFFF) > 1310){
|
||||||
peep_try_get_up_from_sitting(peep);
|
peep_try_get_up_from_sitting(peep);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2272,7 +2278,7 @@ static void peep_update_sitting(rct_peep* peep){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32 rand = scenario_rand();
|
sint32 rand = peep_rand();
|
||||||
if ((rand & 0xFFFF) > 131){
|
if ((rand & 0xFFFF) > 131){
|
||||||
peep_try_get_up_from_sitting(peep);
|
peep_try_get_up_from_sitting(peep);
|
||||||
return;
|
return;
|
||||||
|
@ -2330,10 +2336,10 @@ void remove_peep_from_queue(rct_peep* peep)
|
||||||
* rct2: 0x00691C6E
|
* rct2: 0x00691C6E
|
||||||
*/
|
*/
|
||||||
static rct_vehicle* peep_choose_car_from_ride(rct_peep* peep, rct_ride* ride, uint8* car_array, uint8 car_array_size){
|
static rct_vehicle* peep_choose_car_from_ride(rct_peep* peep, rct_ride* ride, uint8* car_array, uint8 car_array_size){
|
||||||
uint8 chosen_car = scenario_rand();
|
uint8 chosen_car = peep_rand();
|
||||||
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)
|
||||||
&& ((chosen_car & 0xC) != 0xC)){
|
&& ((chosen_car & 0xC) != 0xC)){
|
||||||
chosen_car = (scenario_rand() & 1) ? 0 : car_array_size - 1;
|
chosen_car = (peep_rand() & 1) ? 0 : car_array_size - 1;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
chosen_car = (chosen_car * (uint16)car_array_size) >> 8;
|
chosen_car = (chosen_car * (uint16)car_array_size) >> 8;
|
||||||
|
@ -2655,7 +2661,7 @@ static void peep_update_ride_sub_state_1(rct_peep* peep){
|
||||||
y += TileDirectionDelta[direction_entrance].y;
|
y += TileDirectionDelta[direction_entrance].y;
|
||||||
|
|
||||||
uint8 direction = direction_entrance * 4 + 11;
|
uint8 direction = direction_entrance * 4 + 11;
|
||||||
if (scenario_rand() & 0x40){
|
if (peep_rand() & 0x40){
|
||||||
direction += 4;
|
direction += 4;
|
||||||
peep->maze_last_edge += 2;
|
peep->maze_last_edge += 2;
|
||||||
}
|
}
|
||||||
|
@ -3583,7 +3589,7 @@ static void peep_update_ride_sub_state_14(rct_peep* peep){
|
||||||
else if (peep->current_car++ != 0){
|
else if (peep->current_car++ != 0){
|
||||||
if (ride->mode == RIDE_MODE_SINGLE_RIDE_PER_ADMISSION)
|
if (ride->mode == RIDE_MODE_SINGLE_RIDE_PER_ADMISSION)
|
||||||
last_ride = 1;
|
last_ride = 1;
|
||||||
if ((uint8)(peep->current_car - 1) > (scenario_rand() & 0xF))
|
if ((uint8)(peep->current_car - 1) > (peep_rand() & 0xF))
|
||||||
last_ride = 1;
|
last_ride = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3846,7 +3852,7 @@ static void peep_update_ride_sub_state_17(rct_peep* peep){
|
||||||
|
|
||||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||||
if (peep->energy > 64 &&
|
if (peep->energy > 64 &&
|
||||||
(scenario_rand() & 0xFFFF) <= 2427){
|
(peep_rand() & 0xFFFF) <= 2427){
|
||||||
|
|
||||||
peep->action = PEEP_ACTION_JUMP;
|
peep->action = PEEP_ACTION_JUMP;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
|
@ -3898,7 +3904,7 @@ static void peep_update_ride_sub_state_17(rct_peep* peep){
|
||||||
if (open_hedges == 0)
|
if (open_hedges == 0)
|
||||||
open_hedges |= (1 << maze_last_edge);
|
open_hedges |= (1 << maze_last_edge);
|
||||||
|
|
||||||
uint8 chosen_edge = scenario_rand() & 0x3;
|
uint8 chosen_edge = peep_rand() & 0x3;
|
||||||
while (!(open_hedges & (1 << chosen_edge))){
|
while (!(open_hedges & (1 << chosen_edge))){
|
||||||
chosen_edge = (chosen_edge + 1) & 3;
|
chosen_edge = (chosen_edge + 1) & 3;
|
||||||
}
|
}
|
||||||
|
@ -4386,7 +4392,7 @@ static bool peep_update_fixing_sub_state_2345(bool firstRun, rct_peep *peep, rct
|
||||||
if (!firstRun) {
|
if (!firstRun) {
|
||||||
peep->sprite_direction = peep->direction << 3;
|
peep->sprite_direction = peep->direction << 3;
|
||||||
|
|
||||||
peep->action = (scenario_rand() & 1) ? PEEP_ACTION_STAFF_FIX_2 : PEEP_ACTION_STAFF_FIX;
|
peep->action = (peep_rand() & 1) ? PEEP_ACTION_STAFF_FIX_2 : PEEP_ACTION_STAFF_FIX;
|
||||||
peep->action_sprite_image_offset = 0;
|
peep->action_sprite_image_offset = 0;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
peep_update_current_action_sprite_type(peep);
|
peep_update_current_action_sprite_type(peep);
|
||||||
|
@ -4882,7 +4888,7 @@ static void peep_update_queuing(rct_peep* peep){
|
||||||
peep_perform_next_action(peep);
|
peep_perform_next_action(peep);
|
||||||
if (peep->action < 0xFE)return;
|
if (peep->action < 0xFE)return;
|
||||||
if (peep->sprite_type == PEEP_SPRITE_TYPE_NORMAL) {
|
if (peep->sprite_type == PEEP_SPRITE_TYPE_NORMAL) {
|
||||||
if (peep->time_in_queue >= 2000 && (0xFFFF & scenario_rand()) <= 119){
|
if (peep->time_in_queue >= 2000 && (0xFFFF & peep_rand()) <= 119){
|
||||||
// Eat Food/Look at watch
|
// Eat Food/Look at watch
|
||||||
peep->action = PEEP_ACTION_EAT_FOOD;
|
peep->action = PEEP_ACTION_EAT_FOOD;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
|
@ -4890,7 +4896,7 @@ static void peep_update_queuing(rct_peep* peep){
|
||||||
peep_update_current_action_sprite_type(peep);
|
peep_update_current_action_sprite_type(peep);
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
}
|
}
|
||||||
if (peep->time_in_queue >= 3500 && (0xFFFF & scenario_rand()) <= 93)
|
if (peep->time_in_queue >= 3500 && (0xFFFF & peep_rand()) <= 93)
|
||||||
{
|
{
|
||||||
//Create the I have been waiting in line ages thought
|
//Create the I have been waiting in line ages thought
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_QUEUING_AGES, peep->current_ride);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_QUEUING_AGES, peep->current_ride);
|
||||||
|
@ -4933,7 +4939,7 @@ static void peep_update_queuing(rct_peep* peep){
|
||||||
}
|
}
|
||||||
if (peep->time_in_queue < 4300) return;
|
if (peep->time_in_queue < 4300) return;
|
||||||
|
|
||||||
if (peep->happiness <= 65 && (0xFFFF & scenario_rand()) < 2184){
|
if (peep->happiness <= 65 && (0xFFFF & peep_rand()) < 2184){
|
||||||
//Give up queueing for the ride
|
//Give up queueing for the ride
|
||||||
peep->sprite_direction ^= (1 << 4);
|
peep->sprite_direction ^= (1 << 4);
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
@ -5270,7 +5276,7 @@ static void peep_update_watching(rct_peep* peep){
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (peep_has_food(peep)){
|
if (peep_has_food(peep)){
|
||||||
if ((scenario_rand() & 0xFFFF) <= 1310){
|
if ((peep_rand() & 0xFFFF) <= 1310){
|
||||||
peep->action = PEEP_ACTION_EAT_FOOD;
|
peep->action = PEEP_ACTION_EAT_FOOD;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
peep->action_sprite_image_offset = 0;
|
peep->action_sprite_image_offset = 0;
|
||||||
|
@ -5280,7 +5286,7 @@ static void peep_update_watching(rct_peep* peep){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFFFF) <= 655){
|
if ((peep_rand() & 0xFFFF) <= 655){
|
||||||
peep->action = PEEP_ACTION_TAKE_PHOTO;
|
peep->action = PEEP_ACTION_TAKE_PHOTO;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
peep->action_sprite_image_offset = 0;
|
peep->action_sprite_image_offset = 0;
|
||||||
|
@ -5290,7 +5296,7 @@ static void peep_update_watching(rct_peep* peep){
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((peep->standing_flags & 1)){
|
if ((peep->standing_flags & 1)){
|
||||||
if ((scenario_rand() & 0xFFFF) <= 655){
|
if ((peep_rand() & 0xFFFF) <= 655){
|
||||||
peep->action = PEEP_ACTION_WAVE;
|
peep->action = PEEP_ACTION_WAVE;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
peep->action_sprite_image_offset = 0;
|
peep->action_sprite_image_offset = 0;
|
||||||
|
@ -5380,7 +5386,7 @@ static sint32 peep_update_walking_find_bench(rct_peep* peep){
|
||||||
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
||||||
if (edges == 0) return 0;
|
if (edges == 0) return 0;
|
||||||
|
|
||||||
uint8 chosen_edge = scenario_rand() & 0x3;
|
uint8 chosen_edge = peep_rand() & 0x3;
|
||||||
|
|
||||||
for (; !(edges & (1 << chosen_edge));)chosen_edge = (chosen_edge + 1) & 0x3;
|
for (; !(edges & (1 << chosen_edge));)chosen_edge = (chosen_edge + 1) & 0x3;
|
||||||
|
|
||||||
|
@ -5405,7 +5411,7 @@ static sint32 peep_update_walking_find_bench(rct_peep* peep){
|
||||||
|
|
||||||
free_edge ^= 0x3;
|
free_edge ^= 0x3;
|
||||||
if (!free_edge){
|
if (!free_edge){
|
||||||
if (scenario_rand() & 0x8000000) free_edge = 1;
|
if (peep_rand() & 0x8000000) free_edge = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
peep->var_37 = ((free_edge & 1) << 2) | chosen_edge;
|
peep->var_37 = ((free_edge & 1) << 2) | chosen_edge;
|
||||||
|
@ -5463,7 +5469,7 @@ static sint32 peep_update_walking_find_bin(rct_peep* peep){
|
||||||
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
||||||
if (edges == 0) return 0;
|
if (edges == 0) return 0;
|
||||||
|
|
||||||
uint8 chosen_edge = scenario_rand() & 0x3;
|
uint8 chosen_edge = peep_rand() & 0x3;
|
||||||
|
|
||||||
// Note: Bin quantity is inverted 0 = full, 3 = empty
|
// Note: Bin quantity is inverted 0 = full, 3 = empty
|
||||||
uint8 bin_quantities = map_element->properties.path.addition_status;
|
uint8 bin_quantities = map_element->properties.path.addition_status;
|
||||||
|
@ -5516,7 +5522,7 @@ static void peep_update_walking_break_scenery(rct_peep* peep){
|
||||||
if ((peep->litter_count & 0xC0) != 0xC0 &&
|
if ((peep->litter_count & 0xC0) != 0xC0 &&
|
||||||
(peep->disgusting_count & 0xC0) != 0xC0) return;
|
(peep->disgusting_count & 0xC0) != 0xC0) return;
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFFFF) > 3276) return;
|
if ((peep_rand() & 0xFFFF) > 3276) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peep->next_var_29 & 0x18) return;
|
if (peep->next_var_29 & 0x18) return;
|
||||||
|
@ -5793,7 +5799,7 @@ static void peep_update_using_bin(rct_peep* peep){
|
||||||
// OpenRCT2 modification: This previously used
|
// OpenRCT2 modification: This previously used
|
||||||
// the tick count as a simple random function
|
// the tick count as a simple random function
|
||||||
// switched to scenario_rand as it is more reliable
|
// switched to scenario_rand as it is more reliable
|
||||||
if ((scenario_rand() & 7) == 0) space_left_in_bin--;
|
if ((peep_rand() & 7) == 0) space_left_in_bin--;
|
||||||
peep->item_standard_flags &= ~(1 << cur_container);
|
peep->item_standard_flags &= ~(1 << cur_container);
|
||||||
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||||
peep_update_sprite_type(peep);
|
peep_update_sprite_type(peep);
|
||||||
|
@ -5802,10 +5808,10 @@ static void peep_update_using_bin(rct_peep* peep){
|
||||||
uint8 bp = item_standard_litter[cur_container];
|
uint8 bp = item_standard_litter[cur_container];
|
||||||
|
|
||||||
sint32 x, y;
|
sint32 x, y;
|
||||||
x = peep->x + (scenario_rand() & 7) - 3;
|
x = peep->x + (peep_rand() & 7) - 3;
|
||||||
y = peep->y + (scenario_rand() & 7) - 3;
|
y = peep->y + (peep_rand() & 7) - 3;
|
||||||
|
|
||||||
litter_create(x, y, peep->z, scenario_rand() & 3, bp);
|
litter_create(x, y, peep->z, peep_rand() & 3, bp);
|
||||||
peep->item_standard_flags &= ~(1 << cur_container);
|
peep->item_standard_flags &= ~(1 << cur_container);
|
||||||
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||||
|
|
||||||
|
@ -5823,7 +5829,7 @@ static void peep_update_using_bin(rct_peep* peep){
|
||||||
// OpenRCT2 modification: This previously used
|
// OpenRCT2 modification: This previously used
|
||||||
// the tick count as a simple random function
|
// the tick count as a simple random function
|
||||||
// switched to scenario_rand as it is more reliable
|
// switched to scenario_rand as it is more reliable
|
||||||
if ((scenario_rand() & 7) == 0) space_left_in_bin--;
|
if ((peep_rand() & 7) == 0) space_left_in_bin--;
|
||||||
peep->item_extra_flags &= ~(1 << cur_container);
|
peep->item_extra_flags &= ~(1 << cur_container);
|
||||||
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||||
|
|
||||||
|
@ -5833,10 +5839,10 @@ static void peep_update_using_bin(rct_peep* peep){
|
||||||
uint8 bp = item_extra_litter[cur_container];
|
uint8 bp = item_extra_litter[cur_container];
|
||||||
|
|
||||||
sint32 x, y;
|
sint32 x, y;
|
||||||
x = peep->x + (scenario_rand() & 7) - 3;
|
x = peep->x + (peep_rand() & 7) - 3;
|
||||||
y = peep->y + (scenario_rand() & 7) - 3;
|
y = peep->y + (peep_rand() & 7) - 3;
|
||||||
|
|
||||||
litter_create(x, y, peep->z, scenario_rand() & 3, bp);
|
litter_create(x, y, peep->z, peep_rand() & 3, bp);
|
||||||
peep->item_extra_flags &= ~(1 << cur_container);
|
peep->item_extra_flags &= ~(1 << cur_container);
|
||||||
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||||
|
|
||||||
|
@ -6103,7 +6109,7 @@ static sint32 peep_update_patrolling_find_watering(rct_peep* peep){
|
||||||
if (!(peep->staff_orders & STAFF_ORDERS_WATER_FLOWERS))
|
if (!(peep->staff_orders & STAFF_ORDERS_WATER_FLOWERS))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint8 chosen_position = scenario_rand() & 7;
|
uint8 chosen_position = peep_rand() & 7;
|
||||||
for (sint32 i = 0; i < 8; ++i, ++chosen_position){
|
for (sint32 i = 0; i < 8; ++i, ++chosen_position){
|
||||||
chosen_position &= 7;
|
chosen_position &= 7;
|
||||||
|
|
||||||
|
@ -6373,7 +6379,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
if (peep->peep_flags & PEEP_FLAGS_WAVING){
|
if (peep->peep_flags & PEEP_FLAGS_WAVING){
|
||||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||||
if ((0xFFFF & scenario_rand()) < 936){
|
if ((0xFFFF & peep_rand()) < 936){
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
|
||||||
peep->action = PEEP_ACTION_WAVE_2;
|
peep->action = PEEP_ACTION_WAVE_2;
|
||||||
|
@ -6388,7 +6394,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
if (peep->peep_flags & PEEP_FLAGS_PHOTO){
|
if (peep->peep_flags & PEEP_FLAGS_PHOTO){
|
||||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||||
if ((0xFFFF & scenario_rand()) < 936){
|
if ((0xFFFF & peep_rand()) < 936){
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
|
||||||
peep->action = PEEP_ACTION_TAKE_PHOTO;
|
peep->action = PEEP_ACTION_TAKE_PHOTO;
|
||||||
|
@ -6403,7 +6409,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
if (peep->peep_flags & PEEP_FLAGS_PAINTING){
|
if (peep->peep_flags & PEEP_FLAGS_PAINTING){
|
||||||
if (peep->action >= PEEP_ACTION_NONE_1){
|
if (peep->action >= PEEP_ACTION_NONE_1){
|
||||||
if ((0xFFFF & scenario_rand()) < 936){
|
if ((0xFFFF & peep_rand()) < 936){
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
|
||||||
peep->action = PEEP_ACTION_DRAW_PICTURE;
|
peep->action = PEEP_ACTION_DRAW_PICTURE;
|
||||||
|
@ -6418,17 +6424,17 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
if (peep->peep_flags & PEEP_FLAGS_LITTER){
|
if (peep->peep_flags & PEEP_FLAGS_LITTER){
|
||||||
if (!(peep->next_var_29 & 0x18)){
|
if (!(peep->next_var_29 & 0x18)){
|
||||||
if ((0xFFFF & scenario_rand()) <= 4096){
|
if ((0xFFFF & peep_rand()) <= 4096){
|
||||||
static const uint8 litter_types[] = {
|
static const uint8 litter_types[] = {
|
||||||
LITTER_TYPE_EMPTY_CAN,
|
LITTER_TYPE_EMPTY_CAN,
|
||||||
LITTER_TYPE_RUBBISH,
|
LITTER_TYPE_RUBBISH,
|
||||||
LITTER_TYPE_EMPTY_BURGER_BOX,
|
LITTER_TYPE_EMPTY_BURGER_BOX,
|
||||||
LITTER_TYPE_EMPTY_CUP,
|
LITTER_TYPE_EMPTY_CUP,
|
||||||
};
|
};
|
||||||
sint32 ebp = litter_types[scenario_rand() & 0x3];
|
sint32 ebp = litter_types[peep_rand() & 0x3];
|
||||||
sint32 x = peep->x + (scenario_rand() & 0x7) - 3;
|
sint32 x = peep->x + (peep_rand() & 0x7) - 3;
|
||||||
sint32 y = peep->y + (scenario_rand() & 0x7) - 3;
|
sint32 y = peep->y + (peep_rand() & 0x7) - 3;
|
||||||
sint32 direction = (scenario_rand() & 0x3);
|
sint32 direction = (peep_rand() & 0x3);
|
||||||
|
|
||||||
litter_create(x, y, peep->z, direction, ebp);
|
litter_create(x, y, peep->z, direction, ebp);
|
||||||
}
|
}
|
||||||
|
@ -6437,7 +6443,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
else if (peep_has_empty_container(peep)){
|
else if (peep_has_empty_container(peep)){
|
||||||
if ((!(peep->next_var_29 & 0x18)) &&
|
if ((!(peep->next_var_29 & 0x18)) &&
|
||||||
((uint32)(peep->sprite_index & 0x1FF) == (gCurrentTicks & 0x1FF))&&
|
((uint32)(peep->sprite_index & 0x1FF) == (gCurrentTicks & 0x1FF))&&
|
||||||
((0xFFFF & scenario_rand()) <= 4096)){
|
((0xFFFF & peep_rand()) <= 4096)){
|
||||||
|
|
||||||
uint8 pos_stnd = 0;
|
uint8 pos_stnd = 0;
|
||||||
for (sint32 container = peep_empty_container_standard_flag(peep); pos_stnd < 32; pos_stnd++)
|
for (sint32 container = peep_empty_container_standard_flag(peep); pos_stnd < 32; pos_stnd++)
|
||||||
|
@ -6462,9 +6468,9 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||||
peep_update_sprite_type(peep);
|
peep_update_sprite_type(peep);
|
||||||
|
|
||||||
sint32 x = peep->x + (scenario_rand() & 0x7) - 3;
|
sint32 x = peep->x + (peep_rand() & 0x7) - 3;
|
||||||
sint32 y = peep->y + (scenario_rand() & 0x7) - 3;
|
sint32 y = peep->y + (peep_rand() & 0x7) - 3;
|
||||||
sint32 direction = (scenario_rand() & 0x3);
|
sint32 direction = (peep_rand() & 0x3);
|
||||||
|
|
||||||
litter_create(x, y, peep->z, direction, bp);
|
litter_create(x, y, peep->z, direction, bp);
|
||||||
}
|
}
|
||||||
|
@ -6512,7 +6518,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
uint16 chance = peep_has_food(peep) ? 13107 : 2849;
|
uint16 chance = peep_has_food(peep) ? 13107 : 2849;
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFFFF) > chance)return;
|
if ((peep_rand() & 0xFFFF) > chance)return;
|
||||||
|
|
||||||
if (peep->next_var_29 & 0x1C)return;
|
if (peep->next_var_29 & 0x1C)return;
|
||||||
|
|
||||||
|
@ -6540,7 +6546,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
sint32 edges = (map_element->properties.path.edges & 0xF) ^ 0xF;
|
||||||
if (edges == 0) return;
|
if (edges == 0) return;
|
||||||
|
|
||||||
uint8 chosen_edge = scenario_rand() & 0x3;
|
uint8 chosen_edge = peep_rand() & 0x3;
|
||||||
|
|
||||||
for (; !(edges & (1 << chosen_edge));)chosen_edge = (chosen_edge + 1) & 3;
|
for (; !(edges & (1 << chosen_edge));)chosen_edge = (chosen_edge + 1) & 3;
|
||||||
|
|
||||||
|
@ -6565,7 +6571,7 @@ static void peep_update_walking(rct_peep* peep){
|
||||||
|
|
||||||
if (!ebp)return;
|
if (!ebp)return;
|
||||||
|
|
||||||
uint8 chosen_position = scenario_rand() & 0x3;
|
uint8 chosen_position = peep_rand() & 0x3;
|
||||||
|
|
||||||
for (; !(ebp & (1 << chosen_position));)chosen_position = (chosen_position + 1) & 3;
|
for (; !(ebp & (1 << chosen_position));)chosen_position = (chosen_position + 1) & 3;
|
||||||
|
|
||||||
|
@ -7150,7 +7156,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
sprite_move(x, y, z, (rct_sprite*)peep);
|
sprite_move(x, y, z, (rct_sprite*)peep);
|
||||||
invalidate_sprite_2((rct_sprite*)peep);
|
invalidate_sprite_2((rct_sprite*)peep);
|
||||||
|
|
||||||
peep->var_41 = (scenario_rand() & 0x1F) + 45;
|
peep->var_41 = (peep_rand() & 0x1F) + 45;
|
||||||
peep->var_C4 = 0;
|
peep->var_C4 = 0;
|
||||||
peep->interaction_ride_index = 0xFF;
|
peep->interaction_ride_index = 0xFF;
|
||||||
peep->type = PEEP_TYPE_GUEST;
|
peep->type = PEEP_TYPE_GUEST;
|
||||||
|
@ -7158,7 +7164,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
peep->thoughts->type = PEEP_THOUGHT_TYPE_NONE;
|
peep->thoughts->type = PEEP_THOUGHT_TYPE_NONE;
|
||||||
peep->window_invalidate_flags = 0;
|
peep->window_invalidate_flags = 0;
|
||||||
|
|
||||||
uint8 al = (scenario_rand() & 0x7) + 3;
|
uint8 al = (peep_rand() & 0x7) + 3;
|
||||||
uint8 ah = min(al, 7) - 3;
|
uint8 ah = min(al, 7) - 3;
|
||||||
|
|
||||||
if (al >= 7) al = 15;
|
if (al >= 7) al = 15;
|
||||||
|
@ -7175,7 +7181,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
|
|
||||||
peep->intensity = (al << 4) | ah;
|
peep->intensity = (al << 4) | ah;
|
||||||
|
|
||||||
uint8 nausea_tolerance = scenario_rand() & 0x7;
|
uint8 nausea_tolerance = peep_rand() & 0x7;
|
||||||
if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES){
|
if (gParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES){
|
||||||
nausea_tolerance += 4;
|
nausea_tolerance += 4;
|
||||||
}
|
}
|
||||||
|
@ -7191,7 +7197,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
if (gGuestInitialHappiness == 0)
|
if (gGuestInitialHappiness == 0)
|
||||||
peep->happiness = 128;
|
peep->happiness = 128;
|
||||||
/* Initial value will vary by -15..16 */
|
/* Initial value will vary by -15..16 */
|
||||||
sint8 happiness_delta = (scenario_rand() & 0x1F) - 15;
|
sint8 happiness_delta = (peep_rand() & 0x1F) - 15;
|
||||||
/* Adjust by the delta, clamping at min=0 and max=255. */
|
/* Adjust by the delta, clamping at min=0 and max=255. */
|
||||||
peep->happiness = clamp(0, peep->happiness + happiness_delta, 255);
|
peep->happiness = clamp(0, peep->happiness + happiness_delta, 255);
|
||||||
peep->happiness_growth_rate = peep->happiness;
|
peep->happiness_growth_rate = peep->happiness;
|
||||||
|
@ -7203,7 +7209,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
* to any value 0..255. */
|
* to any value 0..255. */
|
||||||
peep->hunger = gGuestInitialHunger;
|
peep->hunger = gGuestInitialHunger;
|
||||||
/* Initial value will vary by -15..16 */
|
/* Initial value will vary by -15..16 */
|
||||||
sint8 hunger_delta = (scenario_rand() & 0x1F) - 15;
|
sint8 hunger_delta = (peep_rand() & 0x1F) - 15;
|
||||||
/* Adjust by the delta, clamping at min=0 and max=255. */
|
/* Adjust by the delta, clamping at min=0 and max=255. */
|
||||||
peep->hunger = clamp(0, peep->hunger + hunger_delta, 255);
|
peep->hunger = clamp(0, peep->hunger + hunger_delta, 255);
|
||||||
|
|
||||||
|
@ -7212,7 +7218,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
* to any value 0..255. */
|
* to any value 0..255. */
|
||||||
peep->thirst = gGuestInitialThirst;
|
peep->thirst = gGuestInitialThirst;
|
||||||
/* Initial value will vary by -15..16 */
|
/* Initial value will vary by -15..16 */
|
||||||
sint8 thirst_delta = (scenario_rand() & 0x1F) - 15;
|
sint8 thirst_delta = (peep_rand() & 0x1F) - 15;
|
||||||
/* Adjust by the delta, clamping at min=0 and max=255. */
|
/* Adjust by the delta, clamping at min=0 and max=255. */
|
||||||
peep->thirst = clamp(0, peep->thirst + thirst_delta, 0xFF);
|
peep->thirst = clamp(0, peep->thirst + thirst_delta, 0xFF);
|
||||||
|
|
||||||
|
@ -7225,7 +7231,7 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
peep->id = gNextGuestNumber++;
|
peep->id = gNextGuestNumber++;
|
||||||
peep->name_string_idx = STR_GUEST_X;
|
peep->name_string_idx = STR_GUEST_X;
|
||||||
|
|
||||||
money32 cash = (scenario_rand() & 0x3) * 100 - 100 + gGuestInitialCash;
|
money32 cash = (peep_rand() & 0x3) * 100 - 100 + gGuestInitialCash;
|
||||||
if (cash < 0) cash = 0;
|
if (cash < 0) cash = 0;
|
||||||
|
|
||||||
if (gGuestInitialCash == 0){
|
if (gGuestInitialCash == 0){
|
||||||
|
@ -7265,15 +7271,15 @@ rct_peep *peep_generate(sint32 x, sint32 y, sint32 z)
|
||||||
peep->angriness = 0;
|
peep->angriness = 0;
|
||||||
peep->var_F4 = 0;
|
peep->var_F4 = 0;
|
||||||
|
|
||||||
uint8 tshirt_colour = scenario_rand() % countof(tshirt_colours);
|
uint8 tshirt_colour = peep_rand() % countof(tshirt_colours);
|
||||||
peep->tshirt_colour = tshirt_colours[tshirt_colour];
|
peep->tshirt_colour = tshirt_colours[tshirt_colour];
|
||||||
|
|
||||||
uint8 trousers_colour = scenario_rand() % countof(trouser_colours);
|
uint8 trousers_colour = peep_rand() % countof(trouser_colours);
|
||||||
peep->trousers_colour = trouser_colours[trousers_colour];
|
peep->trousers_colour = trouser_colours[trousers_colour];
|
||||||
|
|
||||||
/* It looks like 65 is about 50% energy level, so this initialises
|
/* It looks like 65 is about 50% energy level, so this initialises
|
||||||
* a peep with approx 50%-100% energy. */
|
* a peep with approx 50%-100% energy. */
|
||||||
uint8 energy = (scenario_rand() & 0x3F) + 65;
|
uint8 energy = (peep_rand() & 0x3F) + 65;
|
||||||
peep->energy = energy;
|
peep->energy = energy;
|
||||||
peep->energy_growth_rate = energy;
|
peep->energy_growth_rate = energy;
|
||||||
|
|
||||||
|
@ -8228,7 +8234,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
if (peep->var_EF & 0x3E &&
|
if (peep->var_EF & 0x3E &&
|
||||||
!(peep->var_EF & 0xC0)){
|
!(peep->var_EF & 0xC0)){
|
||||||
|
|
||||||
if ((scenario_rand() & 0xFFFF) <= 10922){
|
if ((peep_rand() & 0xFFFF) <= 10922){
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_VANDALISM, 0xFF);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_VANDALISM, 0xFF);
|
||||||
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
||||||
}
|
}
|
||||||
|
@ -8237,7 +8243,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peep->var_EF & 0xC0 &&
|
if (peep->var_EF & 0xC0 &&
|
||||||
(scenario_rand()&0xFFFF) <= 4369){
|
(peep_rand()&0xFFFF) <= 4369){
|
||||||
peep->var_EF -= 0x40;
|
peep->var_EF -= 0x40;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8273,7 +8279,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
|
|
||||||
if (crowded >= 10 &&
|
if (crowded >= 10 &&
|
||||||
peep->state == PEEP_STATE_WALKING &&
|
peep->state == PEEP_STATE_WALKING &&
|
||||||
(scenario_rand() & 0xFFFF) <= 21845){
|
(peep_rand() & 0xFFFF) <= 21845){
|
||||||
|
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CROWDED, 0xFF);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CROWDED, 0xFF);
|
||||||
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 14);
|
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 14);
|
||||||
|
@ -8287,7 +8293,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
peep->disgusting_count = disgusting_count | disgusting_time;
|
peep->disgusting_count = disgusting_count | disgusting_time;
|
||||||
|
|
||||||
if (disgusting_time & 0xC0 &&
|
if (disgusting_time & 0xC0 &&
|
||||||
(scenario_rand() & 0xFFFF) <= 4369){
|
(peep_rand() & 0xFFFF) <= 4369){
|
||||||
// Reduce the disgusting time
|
// Reduce the disgusting time
|
||||||
peep->disgusting_count -= 0x40;
|
peep->disgusting_count -= 0x40;
|
||||||
}
|
}
|
||||||
|
@ -8298,7 +8304,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_sick >= 3 &&
|
if (total_sick >= 3 &&
|
||||||
(scenario_rand() & 0xFFFF) <= 10922){
|
(peep_rand() & 0xFFFF) <= 10922){
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_PATH_DISGUSTING, 0xFF);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_PATH_DISGUSTING, 0xFF);
|
||||||
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
||||||
// Reset disgusting time
|
// Reset disgusting time
|
||||||
|
@ -8311,7 +8317,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
peep->litter_count = litter_count | litter_time;
|
peep->litter_count = litter_count | litter_time;
|
||||||
|
|
||||||
if (litter_time & 0xC0 &&
|
if (litter_time & 0xC0 &&
|
||||||
(scenario_rand() & 0xFFFF) <= 4369){
|
(peep_rand() & 0xFFFF) <= 4369){
|
||||||
// Reduce the litter time
|
// Reduce the litter time
|
||||||
peep->litter_count -= 0x40;
|
peep->litter_count -= 0x40;
|
||||||
}
|
}
|
||||||
|
@ -8322,7 +8328,7 @@ static sint32 peep_footpath_move_forward(rct_peep* peep, sint16 x, sint16 y, rct
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_litter >= 3 &&
|
if (total_litter >= 3 &&
|
||||||
(scenario_rand() & 0xFFFF) <= 10922){
|
(peep_rand() & 0xFFFF) <= 10922){
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_BAD_LITTER, 0xFF);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_BAD_LITTER, 0xFF);
|
||||||
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
peep->happiness_growth_rate = max(0, peep->happiness_growth_rate - 17);
|
||||||
// Reset litter time
|
// Reset litter time
|
||||||
|
@ -8549,7 +8555,7 @@ static sint32 peep_move_one_tile(uint8 direction, rct_peep* peep){
|
||||||
peep->destination_y = y + 16;
|
peep->destination_y = y + 16;
|
||||||
peep->destination_tolerence = 2;
|
peep->destination_tolerence = 2;
|
||||||
if (peep->state != PEEP_STATE_QUEUING){
|
if (peep->state != PEEP_STATE_QUEUING){
|
||||||
peep->destination_tolerence = (scenario_rand() & 7) + 2;
|
peep->destination_tolerence = (peep_rand() & 7) + 2;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8562,7 +8568,7 @@ static sint32 guest_surface_path_finding(rct_peep* peep){
|
||||||
sint16 x = peep->next_x;
|
sint16 x = peep->next_x;
|
||||||
sint16 y = peep->next_y;
|
sint16 y = peep->next_y;
|
||||||
sint16 z = peep->next_z;
|
sint16 z = peep->next_z;
|
||||||
uint8 randDirection = scenario_rand() & 3;
|
uint8 randDirection = peep_rand() & 3;
|
||||||
|
|
||||||
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
|
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
|
||||||
x += TileDirectionDelta[randDirection].x;
|
x += TileDirectionDelta[randDirection].x;
|
||||||
|
@ -8577,7 +8583,7 @@ static sint32 guest_surface_path_finding(rct_peep* peep){
|
||||||
}
|
}
|
||||||
|
|
||||||
randDirection++;
|
randDirection++;
|
||||||
uint8 rand_backwards = scenario_rand() & 1;
|
uint8 rand_backwards = peep_rand() & 1;
|
||||||
if (rand_backwards){
|
if (rand_backwards){
|
||||||
randDirection -= 2;
|
randDirection -= 2;
|
||||||
}
|
}
|
||||||
|
@ -8854,7 +8860,7 @@ static uint8 footpath_element_destination_in_direction(sint16 x, sint16 y, sint1
|
||||||
* rct2: 0x00695225
|
* rct2: 0x00695225
|
||||||
*/
|
*/
|
||||||
static sint32 guest_path_find_aimless(rct_peep* peep, uint8 edges){
|
static sint32 guest_path_find_aimless(rct_peep* peep, uint8 edges){
|
||||||
if (scenario_rand() & 1){
|
if (peep_rand() & 1){
|
||||||
// If possible go straight
|
// If possible go straight
|
||||||
if (edges & (1 << peep->direction)){
|
if (edges & (1 << peep->direction)){
|
||||||
return peep_move_one_tile(peep->direction, peep);
|
return peep_move_one_tile(peep->direction, peep);
|
||||||
|
@ -8862,7 +8868,7 @@ static sint32 guest_path_find_aimless(rct_peep* peep, uint8 edges){
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1){
|
while (1){
|
||||||
uint8 direction = scenario_rand() & 3;
|
uint8 direction = peep_rand() & 3;
|
||||||
// Otherwise go in a random direction allowed from the tile.
|
// Otherwise go in a random direction allowed from the tile.
|
||||||
if (edges & (1 << direction)){
|
if (edges & (1 << direction)){
|
||||||
return peep_move_one_tile(direction, peep);
|
return peep_move_one_tile(direction, peep);
|
||||||
|
@ -8880,7 +8886,7 @@ static uint8 peep_pathfind_get_max_number_junctions(rct_peep* peep){
|
||||||
|
|
||||||
// PEEP_FLAGS_2? It's cleared here but not set anywhere!
|
// PEEP_FLAGS_2? It's cleared here but not set anywhere!
|
||||||
if ((peep->peep_flags & PEEP_FLAGS_2)){
|
if ((peep->peep_flags & PEEP_FLAGS_2)){
|
||||||
if ((scenario_rand() & 0xFFFF) <= 7281)
|
if ((peep_rand() & 0xFFFF) <= 7281)
|
||||||
peep->peep_flags &= ~PEEP_FLAGS_2;
|
peep->peep_flags &= ~PEEP_FLAGS_2;
|
||||||
|
|
||||||
return 8;
|
return 8;
|
||||||
|
@ -10274,7 +10280,7 @@ static sint32 guest_path_finding(rct_peep* peep)
|
||||||
* In principle, peeps with food are not paying as much attention to
|
* In principle, peeps with food are not paying as much attention to
|
||||||
* where they are going and are consequently more like to walk up
|
* where they are going and are consequently more like to walk up
|
||||||
* dead end paths, paths to ride exits, etc. */
|
* dead end paths, paths to ride exits, etc. */
|
||||||
if (!peep_has_food(peep) && (scenario_rand() & 0xFFFF) >= 2184) {
|
if (!peep_has_food(peep) && (peep_rand() & 0xFFFF) >= 2184) {
|
||||||
uint8 adjustedEdges = edges;
|
uint8 adjustedEdges = edges;
|
||||||
for (sint32 chosenDirection = 0; chosenDirection < 4; chosenDirection++) {
|
for (sint32 chosenDirection = 0; chosenDirection < 4; chosenDirection++) {
|
||||||
// If there is no path in that direction try another
|
// If there is no path in that direction try another
|
||||||
|
@ -10305,7 +10311,7 @@ static sint32 guest_path_finding(rct_peep* peep)
|
||||||
if (peep_heading_for_ride_or_park_exit(peep)) {
|
if (peep_heading_for_ride_or_park_exit(peep)) {
|
||||||
probability = 9362;
|
probability = 9362;
|
||||||
}
|
}
|
||||||
if ((scenario_rand() & 0xFFFF) < probability) {
|
if ((peep_rand() & 0xFFFF) < probability) {
|
||||||
peep_read_map(peep);
|
peep_read_map(peep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10829,7 +10835,7 @@ static bool peep_should_go_on_ride_again(rct_peep *peep, rct_ride *ride)
|
||||||
if (peep->thirst < 20) return false;
|
if (peep->thirst < 20) return false;
|
||||||
if (peep->balloon_colour > 170) return false;
|
if (peep->balloon_colour > 170) return false;
|
||||||
|
|
||||||
uint8 r = (scenario_rand() & 0xFF);
|
uint8 r = (peep_rand() & 0xFF);
|
||||||
if (r <= 128) {
|
if (r <= 128) {
|
||||||
if (peep->no_of_rides > 7) return false;
|
if (peep->no_of_rides > 7) return false;
|
||||||
if (r > 64) return false;
|
if (r > 64) return false;
|
||||||
|
@ -10843,7 +10849,7 @@ static bool peep_should_preferred_intensity_increase(rct_peep *peep)
|
||||||
if (gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) return false;
|
if (gParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) return false;
|
||||||
if (peep->happiness < 200) return false;
|
if (peep->happiness < 200) return false;
|
||||||
|
|
||||||
return (scenario_rand() & 0xFF) >= peep->intensity;
|
return (peep_rand() & 0xFF) >= peep->intensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool peep_really_liked_ride(rct_peep *peep, rct_ride *ride)
|
static bool peep_really_liked_ride(rct_peep *peep, rct_ride *ride)
|
||||||
|
@ -10897,7 +10903,7 @@ static void peep_on_exit_ride(rct_peep *peep, sint32 rideIndex)
|
||||||
if (peep_really_liked_ride(peep, ride)) {
|
if (peep_really_liked_ride(peep, ride)) {
|
||||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WAS_GREAT, rideIndex);
|
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WAS_GREAT, rideIndex);
|
||||||
|
|
||||||
sint32 laugh = scenario_rand() & 7;
|
sint32 laugh = peep_rand() & 7;
|
||||||
if (laugh < 3) {
|
if (laugh < 3) {
|
||||||
audio_play_sound_at_location(SOUND_LAUGH_1 + laugh, peep->x, peep->y, peep->z);
|
audio_play_sound_at_location(SOUND_LAUGH_1 + laugh, peep->x, peep->y, peep->z);
|
||||||
}
|
}
|
||||||
|
@ -10988,7 +10994,7 @@ static bool peep_decide_and_buy_item(rct_peep *peep, sint32 rideIndex, sint32 sh
|
||||||
goto loc_69B119;
|
goto loc_69B119;
|
||||||
|
|
||||||
if ((shopItem != SHOP_ITEM_MAP) && shop_item_is_souvenir(shopItem) && !has_voucher) {
|
if ((shopItem != SHOP_ITEM_MAP) && shop_item_is_souvenir(shopItem) && !has_voucher) {
|
||||||
if (((scenario_rand() & 0x7F) + 0x73) > peep->happiness)
|
if (((peep_rand() & 0x7F) + 0x73) > peep->happiness)
|
||||||
return 0;
|
return 0;
|
||||||
else if (peep->no_of_rides < 3)
|
else if (peep->no_of_rides < 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -11028,7 +11034,7 @@ loc_69B119:
|
||||||
if (peep->happiness >= 180)
|
if (peep->happiness >= 180)
|
||||||
value /= 2;
|
value /= 2;
|
||||||
|
|
||||||
if (value > ((money16)(scenario_rand() & 0x07))) {
|
if (value > ((money16)(peep_rand() & 0x07))) {
|
||||||
// "I'm not paying that much for x"
|
// "I'm not paying that much for x"
|
||||||
uint8 thought_type = (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2_MUCH + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON_MUCH + shopItem));
|
uint8 thought_type = (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2_MUCH + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON_MUCH + shopItem));
|
||||||
peep_insert_new_thought(peep, thought_type, rideIndex);
|
peep_insert_new_thought(peep, thought_type, rideIndex);
|
||||||
|
@ -11040,7 +11046,7 @@ loc_69B119:
|
||||||
value = max(8, value);
|
value = max(8, value);
|
||||||
|
|
||||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) {
|
if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) {
|
||||||
if (value >= (money32)(scenario_rand() & 0x07)) {
|
if (value >= (money32)(peep_rand() & 0x07)) {
|
||||||
// "This x is a really good value"
|
// "This x is a really good value"
|
||||||
uint8 thought_item = (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2 + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON + shopItem));
|
uint8 thought_item = (shopItem >= 32 ? (PEEP_THOUGHT_TYPE_PHOTO2 + (shopItem - 32)) : (PEEP_THOUGHT_TYPE_BALLOON + shopItem));
|
||||||
peep_insert_new_thought(peep, thought_item, rideIndex);
|
peep_insert_new_thought(peep, thought_item, rideIndex);
|
||||||
|
@ -11176,7 +11182,7 @@ static bool peep_should_use_cash_machine(rct_peep *peep, sint32 rideIndex)
|
||||||
if (gParkFlags & PARK_FLAGS_NO_MONEY) return false;
|
if (gParkFlags & PARK_FLAGS_NO_MONEY) return false;
|
||||||
if (peep->peep_flags & PEEP_FLAGS_LEAVING_PARK) return false;
|
if (peep->peep_flags & PEEP_FLAGS_LEAVING_PARK) return false;
|
||||||
if (peep->cash_in_pocket > MONEY(20,00)) return false;
|
if (peep->cash_in_pocket > MONEY(20,00)) return false;
|
||||||
if (115 + (scenario_rand() % 128) > peep->happiness) return false;
|
if (115 + (peep_rand() % 128) > peep->happiness) return false;
|
||||||
if (peep->energy < 80) return false;
|
if (peep->energy < 80) return false;
|
||||||
|
|
||||||
rct_ride *ride = get_ride(rideIndex);
|
rct_ride *ride = get_ride(rideIndex);
|
||||||
|
@ -11321,7 +11327,7 @@ static void peep_easter_egg_peep_interactions(rct_peep *peep)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peep->peep_flags & PEEP_FLAGS_JOY) {
|
if (peep->peep_flags & PEEP_FLAGS_JOY) {
|
||||||
if (scenario_rand() <= 1456) {
|
if (peep_rand() <= 1456) {
|
||||||
if (peep->action == PEEP_ACTION_NONE_1 || peep->action == PEEP_ACTION_NONE_2) {
|
if (peep->action == PEEP_ACTION_NONE_1 || peep->action == PEEP_ACTION_NONE_2) {
|
||||||
peep->action = PEEP_ACTION_JOY;
|
peep->action = PEEP_ACTION_JOY;
|
||||||
peep->action_frame = 0;
|
peep->action_frame = 0;
|
||||||
|
@ -11344,6 +11350,13 @@ static void peep_easter_egg_peep_interactions(rct_peep *peep)
|
||||||
*/
|
*/
|
||||||
static bool peep_should_watch_ride(rct_map_element *mapElement) {
|
static bool peep_should_watch_ride(rct_map_element *mapElement) {
|
||||||
rct_ride *ride = get_ride(mapElement->properties.track.ride_index);
|
rct_ride *ride = get_ride(mapElement->properties.track.ride_index);
|
||||||
|
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (gRideClassifications[ride->type] != RIDE_CLASS_RIDE) {
|
if (gRideClassifications[ride->type] != RIDE_CLASS_RIDE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -11394,6 +11407,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
|
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
||||||
if (map_element_get_direction(mapElement) != edge) continue;
|
if (map_element_get_direction(mapElement) != edge) continue;
|
||||||
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
||||||
|
@ -11415,6 +11433,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
|
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
||||||
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
||||||
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
||||||
|
@ -11429,6 +11452,12 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: Extract loop B
|
// TODO: Extract loop B
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
||||||
if (peep->next_z + 6 < mapElement->base_height) continue;
|
if (peep->next_z + 6 < mapElement->base_height) continue;
|
||||||
|
|
||||||
|
@ -11458,6 +11487,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: Extract loop C
|
// TODO: Extract loop C
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
||||||
if (peep->next_z + 6 < mapElement->base_height) continue;
|
if (peep->next_z + 6 < mapElement->base_height) continue;
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) continue;
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) continue;
|
||||||
|
@ -11485,6 +11519,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: extract loop A
|
// TODO: extract loop A
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
||||||
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
||||||
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
||||||
|
@ -11498,6 +11537,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: Extract loop B
|
// TODO: Extract loop B
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
||||||
if (peep->next_z + 8 < mapElement->base_height) continue;
|
if (peep->next_z + 8 < mapElement->base_height) continue;
|
||||||
|
|
||||||
|
@ -11527,6 +11571,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: Extract loop C
|
// TODO: Extract loop C
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
||||||
if (peep->next_z + 8 < mapElement->base_height) continue;
|
if (peep->next_z + 8 < mapElement->base_height) continue;
|
||||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) continue;
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) continue;
|
||||||
|
@ -11553,6 +11602,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: extract loop A
|
// TODO: extract loop A
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_WALL) continue;
|
||||||
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
if ((map_element_get_direction(mapElement) ^ 0x2) != edge) continue;
|
||||||
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
if (get_wall_entry(mapElement->properties.wall.type)->wall.flags2 & WALL_SCENERY_2_FLAG4) continue;
|
||||||
|
@ -11566,6 +11620,11 @@ static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToV
|
||||||
// TODO: Extract loop B
|
// TODO: Extract loop B
|
||||||
mapElement = surfaceElement;
|
mapElement = surfaceElement;
|
||||||
do {
|
do {
|
||||||
|
// Ghosts are purely this-client-side and should not cause any interaction,
|
||||||
|
// as that may lead to a desync.
|
||||||
|
if (network_get_mode() != NETWORK_MODE_NONE) {
|
||||||
|
if (map_element_is_ghost(mapElement)) continue;
|
||||||
|
}
|
||||||
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
if (mapElement->clearance_height + 1 < peep->next_z) continue;
|
||||||
if (peep->next_z + 10 < mapElement->base_height) continue;
|
if (peep->next_z + 10 < mapElement->base_height) continue;
|
||||||
|
|
||||||
|
@ -11848,7 +11907,7 @@ static bool peep_should_go_on_ride(rct_peep *peep, sint32 rideIndex, sint32 entr
|
||||||
// If the ride has not yet been rated and is capable of having g-forces,
|
// If the ride has not yet been rated and is capable of having g-forces,
|
||||||
// there's a 90% chance that the peep will ignore it.
|
// there's a 90% chance that the peep will ignore it.
|
||||||
if (!ride_has_ratings(ride) && (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_PEEP_CHECK_GFORCES)) {
|
if (!ride_has_ratings(ride) && (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_PEEP_CHECK_GFORCES)) {
|
||||||
if ((scenario_rand() & 0xFFFF) > 0x1999U) {
|
if ((peep_rand() & 0xFFFF) > 0x1999U) {
|
||||||
peep_chose_not_to_go_on_ride(peep, rideIndex, peepAtRide, false);
|
peep_chose_not_to_go_on_ride(peep, rideIndex, peepAtRide, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,7 +386,7 @@ void rct2_update()
|
||||||
|
|
||||||
// TODO: screenshot countdown process
|
// TODO: screenshot countdown process
|
||||||
|
|
||||||
network_update();
|
// network_update() is called in game_update
|
||||||
|
|
||||||
// check_cmdline_arg();
|
// check_cmdline_arg();
|
||||||
// Screens
|
// Screens
|
||||||
|
|
|
@ -566,20 +566,84 @@ static sint32 scenario_create_ducks()
|
||||||
*
|
*
|
||||||
* @return eax
|
* @return eax
|
||||||
*/
|
*/
|
||||||
|
#ifndef DEBUG_DESYNC
|
||||||
uint32 scenario_rand()
|
uint32 scenario_rand()
|
||||||
|
#else
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
static const char *realm = "LC";
|
||||||
|
|
||||||
|
uint32 dbg_scenario_rand(const char *file, const char *function, const uint32 line, const void *data)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
uint32 originalSrand0 = gScenarioSrand0;
|
||||||
|
gScenarioSrand0 += ror32(gScenarioSrand1 ^ 0x1234567F, 7);
|
||||||
|
gScenarioSrand1 = ror32(originalSrand0, 3);
|
||||||
|
|
||||||
#ifdef DEBUG_DESYNC
|
#ifdef DEBUG_DESYNC
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||||
|
{
|
||||||
|
fp = fopen("server_rand.txt", "wt");
|
||||||
|
realm = "SV";
|
||||||
|
}
|
||||||
|
else if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||||
|
{
|
||||||
|
fp = fopen("client_rand.txt", "wt");
|
||||||
|
realm = "CL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fp)
|
||||||
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
|
realm = "LC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "Tick: %d, Rand: %08X - REF: %s:%u %s (%p)\n", gCurrentTicks, gScenarioSrand1, file, line, function, data);
|
||||||
|
}
|
||||||
if (!gInUpdateCode) {
|
if (!gInUpdateCode) {
|
||||||
log_warning("scenario_rand called from outside game update");
|
log_warning("scenario_rand called from outside game update");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32 originalSrand0 = gScenarioSrand0;
|
return gScenarioSrand1;
|
||||||
gScenarioSrand0 += ror32(gScenarioSrand1 ^ 0x1234567F, 7);
|
|
||||||
return gScenarioSrand1 = ror32(originalSrand0, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_DESYNC
|
||||||
|
void dbg_report_desync(uint32 tick, uint32 srand0, uint32 server_srand0, const char *clientHash, const char *serverHash)
|
||||||
|
{
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||||
|
{
|
||||||
|
fp = fopen("server_rand.txt", "wt");
|
||||||
|
realm = "SV";
|
||||||
|
}
|
||||||
|
else if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||||
|
{
|
||||||
|
fp = fopen("client_rand.txt", "wt");
|
||||||
|
realm = "CL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
const bool sprites_mismatch = serverHash[0] != '\0' && strcmp(clientHash, serverHash);
|
||||||
|
|
||||||
|
fprintf(fp, "[%s] !! DESYNC !! Tick: %d, Client Hash: %s, Server Hash: %s, Client Rand: %08X, Server Rand: %08X - %s\n", realm,
|
||||||
|
tick,
|
||||||
|
clientHash,
|
||||||
|
( (serverHash[0] != '\0') ? serverHash : "<NONE:0>" ),
|
||||||
|
srand0,
|
||||||
|
server_srand0,
|
||||||
|
(sprites_mismatch ? "Sprite hash mismatch" : "scenario rand mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32 scenario_rand_max(uint32 max)
|
uint32 scenario_rand_max(uint32 max)
|
||||||
{
|
{
|
||||||
if (max < 2) return 0;
|
if (max < 2) return 0;
|
||||||
|
|
|
@ -393,8 +393,18 @@ sint32 scenario_load(const char *path);
|
||||||
sint32 scenario_load_and_play_from_path(const char *path);
|
sint32 scenario_load_and_play_from_path(const char *path);
|
||||||
void scenario_begin();
|
void scenario_begin();
|
||||||
void scenario_update();
|
void scenario_update();
|
||||||
|
|
||||||
|
#ifdef DEBUG_DESYNC
|
||||||
|
uint32 dbg_scenario_rand(const char *file, const char *function, const uint32 line, const void *data);
|
||||||
|
#define scenario_rand() dbg_scenario_rand(__FILE__, __FUNCTION__, __LINE__, NULL)
|
||||||
|
#define scenario_rand_data(data) dbg_scenario_rand(__FILE__, __FUNCTION__, __LINE__, data)
|
||||||
|
void dbg_report_desync(uint32 tick, uint32 srand0, uint32 server_srand0, const char *clientHash, const char *serverHash);
|
||||||
|
#else
|
||||||
uint32 scenario_rand();
|
uint32 scenario_rand();
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32 scenario_rand_max(uint32 max);
|
uint32 scenario_rand_max(uint32 max);
|
||||||
|
|
||||||
sint32 scenario_prepare_for_save();
|
sint32 scenario_prepare_for_save();
|
||||||
sint32 scenario_save(const utf8 * path, sint32 flags);
|
sint32 scenario_save(const utf8 * path, sint32 flags);
|
||||||
void scenario_remove_trackless_rides(rct_s6_data *s6);
|
void scenario_remove_trackless_rides(rct_s6_data *s6);
|
||||||
|
|
|
@ -3719,6 +3719,9 @@ static void map_update_grass_length(sint32 x, sint32 y, rct_map_element *mapElem
|
||||||
mapElementAbove++;
|
mapElementAbove++;
|
||||||
if (map_element_get_type(mapElementAbove) == MAP_ELEMENT_TYPE_WALL)
|
if (map_element_get_type(mapElementAbove) == MAP_ELEMENT_TYPE_WALL)
|
||||||
continue;
|
continue;
|
||||||
|
// Grass should not be affected by ghost elements.
|
||||||
|
if (map_element_is_ghost(mapElementAbove))
|
||||||
|
continue;
|
||||||
if (z0 >= mapElementAbove->clearance_height)
|
if (z0 >= mapElementAbove->clearance_height)
|
||||||
continue;
|
continue;
|
||||||
if (z1 < mapElementAbove->base_height)
|
if (z1 < mapElementAbove->base_height)
|
||||||
|
|
Loading…
Reference in New Issue