mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Move Update state functions to correct files
This commit is contained in:
@@ -3050,3 +3050,740 @@ void rct_peep::UpdateRide()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069030A
|
||||
*/
|
||||
void rct_peep::UpdateWalking()
|
||||
{
|
||||
if (!CheckForPath())
|
||||
return;
|
||||
|
||||
if (peep_flags & PEEP_FLAGS_WAVING)
|
||||
{
|
||||
if (action >= PEEP_ACTION_NONE_1)
|
||||
{
|
||||
if ((0xFFFF & scenario_rand()) < 936)
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
|
||||
action = PEEP_ACTION_WAVE_2;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peep_flags & PEEP_FLAGS_PHOTO)
|
||||
{
|
||||
if (action >= PEEP_ACTION_NONE_1)
|
||||
{
|
||||
if ((0xFFFF & scenario_rand()) < 936)
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
|
||||
action = PEEP_ACTION_TAKE_PHOTO;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peep_flags & PEEP_FLAGS_PAINTING)
|
||||
{
|
||||
if (action >= PEEP_ACTION_NONE_1)
|
||||
{
|
||||
if ((0xFFFF & scenario_rand()) < 936)
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
|
||||
action = PEEP_ACTION_DRAW_PICTURE;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peep_flags & PEEP_FLAGS_LITTER)
|
||||
{
|
||||
if (!(next_var_29 & 0x18))
|
||||
{
|
||||
if ((0xFFFF & scenario_rand()) <= 4096)
|
||||
{
|
||||
static constexpr const uint8 litter_types[] = {
|
||||
LITTER_TYPE_EMPTY_CAN,
|
||||
LITTER_TYPE_RUBBISH,
|
||||
LITTER_TYPE_EMPTY_BURGER_BOX,
|
||||
LITTER_TYPE_EMPTY_CUP,
|
||||
};
|
||||
sint32 ebp = litter_types[scenario_rand() & 0x3];
|
||||
sint32 litterX = x + (scenario_rand() & 0x7) - 3;
|
||||
sint32 litterY = y + (scenario_rand() & 0x7) - 3;
|
||||
sint32 litterDirection = (scenario_rand() & 0x3);
|
||||
|
||||
litter_create(litterX, litterY, z, litterDirection, ebp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (peep_has_empty_container(this))
|
||||
{
|
||||
if ((!(next_var_29 & 0x18)) && ((uint32)(sprite_index & 0x1FF) == (gCurrentTicks & 0x1FF)) &&
|
||||
((0xFFFF & scenario_rand()) <= 4096))
|
||||
{
|
||||
|
||||
uint8 pos_stnd = 0;
|
||||
for (sint32 container = peep_empty_container_standard_flag(this); pos_stnd < 32; pos_stnd++)
|
||||
if (container & (1u << pos_stnd))
|
||||
break;
|
||||
|
||||
sint32 bp = 0;
|
||||
|
||||
if (pos_stnd != 32)
|
||||
{
|
||||
item_standard_flags &= ~(1u << pos_stnd);
|
||||
bp = item_standard_litter[pos_stnd];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 pos_extr = 0;
|
||||
for (sint32 container = peep_empty_container_extra_flag(this); pos_extr < 32; pos_extr++)
|
||||
if (container & (1u << pos_extr))
|
||||
break;
|
||||
item_extra_flags &= ~(1u << pos_extr);
|
||||
bp = item_extra_litter[pos_extr];
|
||||
}
|
||||
|
||||
window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||
peep_update_sprite_type(this);
|
||||
|
||||
sint32 litterX = x + (scenario_rand() & 0x7) - 3;
|
||||
sint32 litterY = y + (scenario_rand() & 0x7) - 3;
|
||||
sint32 litterDirection = (scenario_rand() & 0x3);
|
||||
|
||||
litter_create(litterX, litterY, z, litterDirection, bp);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (!(pathingResult & PATHING_DESTINATION_REACHED))
|
||||
return;
|
||||
|
||||
if ((next_var_29 & 0x18) == 8)
|
||||
{
|
||||
rct_tile_element * tile_element = map_get_surface_element_at({next_x, next_y});
|
||||
|
||||
sint32 water_height = surface_get_water_height(tile_element);
|
||||
if (water_height)
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
water_height *= 16;
|
||||
sprite_move(x, y, water_height, (rct_sprite *)this);
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
|
||||
SetState(PEEP_STATE_FALLING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
peep_check_if_lost(this);
|
||||
peep_check_cant_find_ride(this);
|
||||
peep_check_cant_find_exit(this);
|
||||
|
||||
if (peep_update_walking_find_bench(this))
|
||||
return;
|
||||
|
||||
if (peep_update_walking_find_bin(this))
|
||||
return;
|
||||
|
||||
peep_update_walking_break_scenery(this);
|
||||
|
||||
if (state != PEEP_STATE_WALKING)
|
||||
return;
|
||||
|
||||
if (peep_flags & PEEP_FLAGS_LEAVING_PARK)
|
||||
return;
|
||||
|
||||
if (nausea > 140)
|
||||
return;
|
||||
|
||||
if (happiness < 120)
|
||||
return;
|
||||
|
||||
if (toilet > 140)
|
||||
return;
|
||||
|
||||
uint16 chance = HasFoodExtraFlag() ? 13107 : 2849;
|
||||
|
||||
if ((scenario_rand() & 0xFFFF) > chance)
|
||||
return;
|
||||
|
||||
if (next_var_29 & 0x1C)
|
||||
return;
|
||||
|
||||
rct_tile_element * tile_element = map_get_first_element_at(next_x / 32, next_y / 32);
|
||||
|
||||
for (;; tile_element++)
|
||||
{
|
||||
if (tile_element->GetType() == TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
if (next_z == tile_element->base_height)
|
||||
break;
|
||||
}
|
||||
if (tile_element_is_last_for_tile(tile_element))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sint32 positions_free = 15;
|
||||
|
||||
if (footpath_element_has_path_scenery(tile_element))
|
||||
{
|
||||
if (!footpath_element_path_scenery_is_ghost(tile_element))
|
||||
{
|
||||
rct_scenery_entry * sceneryEntry = get_footpath_item_entry(footpath_element_get_path_scenery_index(tile_element));
|
||||
if (sceneryEntry == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BENCH))
|
||||
positions_free = 9;
|
||||
}
|
||||
}
|
||||
|
||||
sint32 edges = (tile_element->properties.path.edges & 0xF) ^ 0xF;
|
||||
if (edges == 0)
|
||||
return;
|
||||
|
||||
uint8 chosen_edge = scenario_rand() & 0x3;
|
||||
|
||||
for (; !(edges & (1 << chosen_edge));)
|
||||
chosen_edge = (chosen_edge + 1) & 3;
|
||||
|
||||
uint8 ride_to_view, ride_seat_to_view;
|
||||
if (!peep_find_ride_to_look_at(this, chosen_edge, &ride_to_view, &ride_seat_to_view))
|
||||
return;
|
||||
|
||||
// Check if there is a peep watching (and if there is place for us)
|
||||
uint16 sprite_id = sprite_get_first_in_quadrant(x, y);
|
||||
for (rct_sprite * sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.next_in_quadrant)
|
||||
{
|
||||
sprite = get_sprite(sprite_id);
|
||||
|
||||
if (sprite->unknown.linked_list_type_offset != SPRITE_LIST_PEEP * 2)
|
||||
continue;
|
||||
|
||||
if (sprite->peep.state != PEEP_STATE_WATCHING)
|
||||
continue;
|
||||
|
||||
if (z != sprite->peep.z)
|
||||
continue;
|
||||
|
||||
if ((sprite->peep.var_37 & 0x3) != chosen_edge)
|
||||
continue;
|
||||
|
||||
positions_free &= ~(1 << ((sprite->peep.var_37 & 0x1C) >> 2));
|
||||
}
|
||||
|
||||
if (!positions_free)
|
||||
return;
|
||||
|
||||
uint8 chosen_position = scenario_rand() & 0x3;
|
||||
|
||||
for (; !(positions_free & (1 << chosen_position));)
|
||||
chosen_position = (chosen_position + 1) & 3;
|
||||
|
||||
current_ride = ride_to_view;
|
||||
current_seat = ride_seat_to_view;
|
||||
var_37 = chosen_edge | (chosen_position << 2);
|
||||
|
||||
SetState(PEEP_STATE_WATCHING);
|
||||
sub_state = 0;
|
||||
|
||||
sint32 ebx = var_37 & 0x1F;
|
||||
sint32 destX = (x & 0xFFE0) + _981F4C[ebx].x;
|
||||
sint32 destY = (y & 0xFFE0) + _981F4C[ebx].y;
|
||||
|
||||
destination_x = destX;
|
||||
destination_y = destY;
|
||||
destination_tolerance = 3;
|
||||
|
||||
if (current_seat & 1)
|
||||
{
|
||||
peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_NEW_RIDE, PEEP_THOUGHT_ITEM_NONE);
|
||||
}
|
||||
if (current_ride == 0xFF)
|
||||
{
|
||||
peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_SCENERY, PEEP_THOUGHT_ITEM_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x69185D
|
||||
*/
|
||||
void rct_peep::UpdateQueuing()
|
||||
{
|
||||
if (!CheckForPath())
|
||||
{
|
||||
RemoveFromQueue();
|
||||
return;
|
||||
}
|
||||
Ride * ride = get_ride(current_ride);
|
||||
if (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_TESTING)
|
||||
{
|
||||
RemoveFromQueue();
|
||||
SetState(PEEP_STATE_1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sub_state != 10)
|
||||
{
|
||||
bool is_front = true;
|
||||
if (next_in_queue != SPRITE_INDEX_NULL)
|
||||
{
|
||||
// Fix #4819: Occasionally the peep->next_in_queue is incorrectly set
|
||||
// to prevent this from causing the peeps to enter a loop
|
||||
// first check if the next in queue is actually nearby
|
||||
// if they are not then it's safe to assume that this is
|
||||
// the front of the queue.
|
||||
rct_peep * next_peep = GET_PEEP(next_in_queue);
|
||||
if (abs(next_peep->x - x) < 32 && abs(next_peep->y - y) < 32)
|
||||
{
|
||||
is_front = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_front)
|
||||
{
|
||||
// Happens every time peep goes onto ride.
|
||||
destination_tolerance = 0;
|
||||
SetState(PEEP_STATE_QUEUING_FRONT);
|
||||
sub_state = PEEP_RIDE_AT_ENTRANCE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Give up queueing for the ride
|
||||
sprite_direction ^= (1 << 4);
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
RemoveFromQueue();
|
||||
SetState(PEEP_STATE_1);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (action < 0xFE)
|
||||
return;
|
||||
if (sprite_type == PEEP_SPRITE_TYPE_NORMAL)
|
||||
{
|
||||
if (time_in_queue >= 2000 && (0xFFFF & scenario_rand()) <= 119)
|
||||
{
|
||||
// Eat Food/Look at watch
|
||||
action = PEEP_ACTION_EAT_FOOD;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
}
|
||||
if (time_in_queue >= 3500 && (0xFFFF & scenario_rand()) <= 93)
|
||||
{
|
||||
// Create the I have been waiting in line ages thought
|
||||
peep_insert_new_thought(this, PEEP_THOUGHT_TYPE_QUEUING_AGES, current_ride);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(time_in_queue & 0x3F) && action == 0xFE && next_action_sprite_type == 2)
|
||||
{
|
||||
switch (sprite_type)
|
||||
{
|
||||
case PEEP_SPRITE_TYPE_ICE_CREAM:
|
||||
case PEEP_SPRITE_TYPE_CHIPS:
|
||||
case PEEP_SPRITE_TYPE_BURGER:
|
||||
case PEEP_SPRITE_TYPE_DRINK:
|
||||
case PEEP_SPRITE_TYPE_CANDYFLOSS:
|
||||
case PEEP_SPRITE_TYPE_PIZZA:
|
||||
case PEEP_SPRITE_TYPE_POPCORN:
|
||||
case PEEP_SPRITE_TYPE_HOT_DOG:
|
||||
case PEEP_SPRITE_TYPE_TENTACLE:
|
||||
case PEEP_SPRITE_TYPE_TOFFEE_APPLE:
|
||||
case PEEP_SPRITE_TYPE_DOUGHNUT:
|
||||
case PEEP_SPRITE_TYPE_COFFEE:
|
||||
case PEEP_SPRITE_TYPE_CHICKEN:
|
||||
case PEEP_SPRITE_TYPE_LEMONADE:
|
||||
case PEEP_SPRITE_TYPE_PRETZEL:
|
||||
case PEEP_SPRITE_TYPE_SU_JONGKWA:
|
||||
case PEEP_SPRITE_TYPE_JUICE:
|
||||
case PEEP_SPRITE_TYPE_FUNNEL_CAKE:
|
||||
case PEEP_SPRITE_TYPE_NOODLES:
|
||||
case PEEP_SPRITE_TYPE_SAUSAGE:
|
||||
case PEEP_SPRITE_TYPE_SOUP:
|
||||
case PEEP_SPRITE_TYPE_SANDWICH:
|
||||
// Eat food
|
||||
action = PEEP_ACTION_EAT_FOOD;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (time_in_queue < 4300)
|
||||
return;
|
||||
|
||||
if (happiness <= 65 && (0xFFFF & scenario_rand()) < 2184)
|
||||
{
|
||||
// Give up queueing for the ride
|
||||
sprite_direction ^= (1 << 4);
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
RemoveFromQueue();
|
||||
SetState(PEEP_STATE_1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x691451
|
||||
*/
|
||||
void rct_peep::UpdateEnteringPark()
|
||||
{
|
||||
if (var_37 != 1)
|
||||
{
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if ((pathingResult & PATHING_OUTSIDE_PARK))
|
||||
{
|
||||
decrement_guests_heading_for_park();
|
||||
peep_sprite_remove(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
sint16 actionX = 0;
|
||||
sint16 actionY = 0;
|
||||
sint16 xy_distance;
|
||||
if (UpdateAction(&actionX, &actionY, &xy_distance))
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
sprite_move(actionX, actionY, z, (rct_sprite *)this);
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
return;
|
||||
}
|
||||
SetState(PEEP_STATE_FALLING);
|
||||
|
||||
outside_of_park = 0;
|
||||
time_in_park = gScenarioTicks;
|
||||
increment_guests_in_park();
|
||||
decrement_guests_heading_for_park();
|
||||
auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT);
|
||||
context_broadcast_intent(&intent);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x6914CD
|
||||
*/
|
||||
void rct_peep::UpdateLeavingPark()
|
||||
{
|
||||
if (var_37 != 0)
|
||||
{
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (!(pathingResult & PATHING_OUTSIDE_PARK))
|
||||
return;
|
||||
peep_sprite_remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
sint16 actionX = 0;
|
||||
sint16 actionY = 0;
|
||||
sint16 xy_distance;
|
||||
if (UpdateAction(&actionX, &actionY, &xy_distance))
|
||||
{
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
sprite_move(actionX, actionY, z, (rct_sprite *)this);
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
return;
|
||||
}
|
||||
|
||||
outside_of_park = 1;
|
||||
destination_tolerance = 5;
|
||||
decrement_guests_in_park();
|
||||
auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT);
|
||||
context_broadcast_intent(&intent);
|
||||
var_37 = 1;
|
||||
|
||||
window_invalidate_by_class(WC_GUEST_LIST);
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (!(pathingResult & PATHING_OUTSIDE_PARK))
|
||||
return;
|
||||
peep_sprite_remove(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x6916D6
|
||||
*/
|
||||
void rct_peep::UpdateWatching()
|
||||
{
|
||||
if (sub_state == 0)
|
||||
{
|
||||
if (!CheckForPath())
|
||||
return;
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (!(pathingResult & PATHING_DESTINATION_REACHED))
|
||||
return;
|
||||
|
||||
destination_x = x;
|
||||
destination_y = y;
|
||||
|
||||
sprite_direction = (var_37 & 3) * 8;
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
|
||||
action = 0xFE;
|
||||
next_action_sprite_type = 2;
|
||||
|
||||
SwitchNextActionSpriteType();
|
||||
|
||||
sub_state++;
|
||||
|
||||
time_to_stand = Math::Clamp(0, ((129 - energy) * 16 + 50) / 2, 255);
|
||||
peep_update_sprite_type(this);
|
||||
}
|
||||
else if (sub_state == 1)
|
||||
{
|
||||
if (action < 0xFE)
|
||||
{
|
||||
// 6917F6
|
||||
sint16 actionX = 0;
|
||||
sint16 actionY = 0;
|
||||
sint16 xy_distance;
|
||||
UpdateAction(&actionX, &actionY, &xy_distance);
|
||||
|
||||
if (action != 0xFF)
|
||||
return;
|
||||
action = 0xFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HasFood())
|
||||
{
|
||||
if ((scenario_rand() & 0xFFFF) <= 1310)
|
||||
{
|
||||
action = PEEP_ACTION_EAT_FOOD;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((scenario_rand() & 0xFFFF) <= 655)
|
||||
{
|
||||
action = PEEP_ACTION_TAKE_PHOTO;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((standing_flags & 1))
|
||||
{
|
||||
if ((scenario_rand() & 0xFFFF) <= 655)
|
||||
{
|
||||
action = PEEP_ACTION_WAVE;
|
||||
action_frame = 0;
|
||||
action_sprite_image_offset = 0;
|
||||
UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
standing_flags ^= (1 << 7);
|
||||
if (!(standing_flags & (1 << 7)))
|
||||
return;
|
||||
|
||||
time_to_stand--;
|
||||
if (time_to_stand != 0)
|
||||
return;
|
||||
|
||||
SetState(PEEP_STATE_WALKING);
|
||||
peep_update_sprite_type(this);
|
||||
// Send peep to the centre of current tile.
|
||||
destination_x = (x & 0xFFE0) + 16;
|
||||
destination_y = (y & 0xFFE0) + 16;
|
||||
destination_tolerance = 5;
|
||||
UpdateCurrentActionSpriteType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00691089
|
||||
*/
|
||||
void rct_peep::UpdateUsingBin()
|
||||
{
|
||||
if (sub_state == 0)
|
||||
{
|
||||
if (!CheckForPath())
|
||||
return;
|
||||
|
||||
uint8 pathingResult;
|
||||
PerformNextAction(pathingResult);
|
||||
if (!(pathingResult & PATHING_DESTINATION_REACHED))
|
||||
return;
|
||||
|
||||
sub_state = 1;
|
||||
}
|
||||
else if (sub_state == 1)
|
||||
{
|
||||
|
||||
if (action != PEEP_ACTION_NONE_2)
|
||||
{
|
||||
sint16 actionX, actionY, xy_distance;
|
||||
UpdateAction(&actionX, &actionY, &xy_distance);
|
||||
return;
|
||||
}
|
||||
|
||||
rct_tile_element * tile_element = map_get_first_element_at(next_x / 32, next_y / 32);
|
||||
|
||||
for (;; tile_element++)
|
||||
{
|
||||
if (tile_element->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tile_element->base_height == next_z)
|
||||
break;
|
||||
|
||||
if (tile_element_is_last_for_tile(tile_element))
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!footpath_element_has_path_scenery(tile_element))
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
rct_scenery_entry * sceneryEntry = get_footpath_item_entry(footpath_element_get_path_scenery_index(tile_element));
|
||||
if (!(sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN))
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tile_element->flags & TILE_ELEMENT_FLAG_BROKEN)
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (footpath_element_path_scenery_is_ghost(tile_element))
|
||||
{
|
||||
StateReset();
|
||||
return;
|
||||
}
|
||||
|
||||
// Bin selection is one of 4 corners
|
||||
uint8 selected_bin = var_37 * 2;
|
||||
|
||||
// This counts down 2 = No rubbish, 0 = full
|
||||
uint8 space_left_in_bin = 0x3 & (tile_element->properties.path.addition_status >> selected_bin);
|
||||
uint32 empty_containers = peep_empty_container_standard_flag(this);
|
||||
|
||||
for (uint8 cur_container = 0; cur_container < 32; cur_container++)
|
||||
{
|
||||
if (!(empty_containers & (1u << cur_container)))
|
||||
continue;
|
||||
|
||||
if (space_left_in_bin != 0)
|
||||
{
|
||||
// OpenRCT2 modification: This previously used
|
||||
// the tick count as a simple random function
|
||||
// switched to scenario_rand as it is more reliable
|
||||
if ((scenario_rand() & 7) == 0)
|
||||
space_left_in_bin--;
|
||||
item_standard_flags &= ~(1 << cur_container);
|
||||
window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||
peep_update_sprite_type(this);
|
||||
continue;
|
||||
}
|
||||
uint8 bp = item_standard_litter[cur_container];
|
||||
|
||||
sint32 litterX = x + (scenario_rand() & 7) - 3;
|
||||
sint32 litterY = y + (scenario_rand() & 7) - 3;
|
||||
|
||||
litter_create(litterX, litterY, z, scenario_rand() & 3, bp);
|
||||
item_standard_flags &= ~(1 << cur_container);
|
||||
window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||
|
||||
peep_update_sprite_type(this);
|
||||
}
|
||||
|
||||
// Original bug: This would clear any rubbish placed by the previous function
|
||||
// space_left_in_bin = 0x3 & (tile_element->properties.path.addition_status >> selected_bin);
|
||||
empty_containers = peep_empty_container_extra_flag(this);
|
||||
|
||||
for (uint8 cur_container = 0; cur_container < 32; cur_container++)
|
||||
{
|
||||
if (!(empty_containers & (1u << cur_container)))
|
||||
continue;
|
||||
|
||||
if (space_left_in_bin != 0)
|
||||
{
|
||||
// OpenRCT2 modification: This previously used
|
||||
// the tick count as a simple random function
|
||||
// switched to scenario_rand as it is more reliable
|
||||
if ((scenario_rand() & 7) == 0)
|
||||
space_left_in_bin--;
|
||||
item_extra_flags &= ~(1 << cur_container);
|
||||
window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||
|
||||
peep_update_sprite_type(this);
|
||||
continue;
|
||||
}
|
||||
uint8 bp = item_extra_litter[cur_container];
|
||||
|
||||
sint32 litterX = x + (scenario_rand() & 7) - 3;
|
||||
sint32 litterY = y + (scenario_rand() & 7) - 3;
|
||||
|
||||
litter_create(litterX, litterY, z, scenario_rand() & 3, bp);
|
||||
item_extra_flags &= ~(1 << cur_container);
|
||||
window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
|
||||
|
||||
peep_update_sprite_type(this);
|
||||
}
|
||||
|
||||
// Place new amount in bin by first clearing the value
|
||||
tile_element->properties.path.addition_status &= ~(3 << selected_bin);
|
||||
// Then placing the new value.
|
||||
tile_element->properties.path.addition_status |= space_left_in_bin << selected_bin;
|
||||
|
||||
map_invalidate_tile_zoom0(next_x, next_y, tile_element->base_height << 3,
|
||||
tile_element->clearance_height << 3);
|
||||
StateReset();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2357,3 +2357,801 @@ void rct_peep::UpdatePatrolling()
|
||||
|
||||
peep_update_patrolling_find_watering(this);
|
||||
}
|
||||
|
||||
enum {
|
||||
PEEP_FIXING_ENTER_STATION = 1 << 0,
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE = 1 << 1,
|
||||
PEEP_FIXING_FIX_VEHICLE_CLOSED_RESTRAINTS = 1 << 2,
|
||||
PEEP_FIXING_FIX_VEHICLE_CLOSED_DOORS = 1 << 3,
|
||||
PEEP_FIXING_FIX_VEHICLE_OPEN_RESTRAINTS = 1 << 4,
|
||||
PEEP_FIXING_FIX_VEHICLE_OPEN_DOORS = 1 << 5,
|
||||
PEEP_FIXING_FIX_VEHICLE_MALFUNCTION = 1 << 6,
|
||||
PEEP_FIXING_MOVE_TO_STATION_END = 1 << 7,
|
||||
PEEP_FIXING_FIX_STATION_END = 1 << 8,
|
||||
PEEP_FIXING_MOVE_TO_STATION_START = 1 << 9,
|
||||
PEEP_FIXING_FIX_STATION_START = 1 << 10,
|
||||
PEEP_FIXING_FIX_STATION_BRAKES = 1 << 11,
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT = 1 << 12,
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT = 1 << 13,
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT = 1 << 14,
|
||||
};
|
||||
|
||||
/**
|
||||
* peep_fixing_sub_state_mask[] defines the applicable peep sub_states for
|
||||
* mechanics fixing a ride. The array is indexed by breakdown_reason:
|
||||
* - indexes 0-7 are the 8 breakdown reasons (see BREAKDOWN_* in Ride.h)
|
||||
* when fixing a broken down ride;
|
||||
* - index 8 is for inspecting a ride.
|
||||
*/
|
||||
static constexpr const uint32 peep_fixing_sub_state_mask[9] = {
|
||||
( // BREAKDOWN_SAFETY_CUT_OUT
|
||||
PEEP_FIXING_MOVE_TO_STATION_END |
|
||||
PEEP_FIXING_FIX_STATION_END |
|
||||
PEEP_FIXING_MOVE_TO_STATION_START |
|
||||
PEEP_FIXING_FIX_STATION_START |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_RESTRAINTS_STUCK_CLOSED
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE |
|
||||
PEEP_FIXING_FIX_VEHICLE_CLOSED_RESTRAINTS |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_RESTRAINTS_STUCK_OPEN
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE |
|
||||
PEEP_FIXING_FIX_VEHICLE_OPEN_RESTRAINTS |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_DOORS_STUCK_CLOSED
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE |
|
||||
PEEP_FIXING_FIX_VEHICLE_CLOSED_DOORS |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_DOORS_STUCK_OPEN
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE |
|
||||
PEEP_FIXING_FIX_VEHICLE_OPEN_DOORS |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_VEHICLE_MALFUNCTION
|
||||
PEEP_FIXING_MOVE_TO_BROKEN_DOWN_VEHICLE |
|
||||
PEEP_FIXING_FIX_VEHICLE_MALFUNCTION |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_BRAKES_FAILURE
|
||||
PEEP_FIXING_MOVE_TO_STATION_START |
|
||||
PEEP_FIXING_FIX_STATION_BRAKES |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // BREAKDOWN_CONTROL_FAILURE
|
||||
PEEP_FIXING_MOVE_TO_STATION_END |
|
||||
PEEP_FIXING_FIX_STATION_END |
|
||||
PEEP_FIXING_MOVE_TO_STATION_START |
|
||||
PEEP_FIXING_FIX_STATION_START |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
),
|
||||
( // INSPECTION
|
||||
PEEP_FIXING_MOVE_TO_STATION_END |
|
||||
PEEP_FIXING_FIX_STATION_END |
|
||||
PEEP_FIXING_MOVE_TO_STATION_START |
|
||||
PEEP_FIXING_FIX_STATION_START |
|
||||
PEEP_FIXING_MOVE_TO_STATION_EXIT |
|
||||
PEEP_FIXING_FINISH_FIX_OR_INSPECT |
|
||||
PEEP_FIXING_LEAVE_BY_ENTRANCE_EXIT
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0E8B
|
||||
* Also used by inspecting.
|
||||
*/
|
||||
void rct_peep::UpdateFixing(sint32 steps)
|
||||
{
|
||||
Ride * ride = get_ride(current_ride);
|
||||
|
||||
if (ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
SetState(PEEP_STATE_FALLING);
|
||||
return;
|
||||
}
|
||||
|
||||
bool progressToNextSubstate = true;
|
||||
bool firstRun = true;
|
||||
|
||||
if ((state == PEEP_STATE_INSPECTING) &&
|
||||
(ride->lifecycle_flags & ( RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)))
|
||||
{
|
||||
// Ride has broken down since Mechanic was called to inspect it.
|
||||
// Mechanic identifies the breakdown and switches to fixing it.
|
||||
state = PEEP_STATE_FIXING;
|
||||
}
|
||||
|
||||
while (progressToNextSubstate)
|
||||
{
|
||||
switch (sub_state)
|
||||
{
|
||||
case 0:
|
||||
progressToNextSubstate = peep_update_fixing_enter_station(ride);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
progressToNextSubstate = peep_update_fixing_move_to_broken_down_vehicle(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
progressToNextSubstate = peep_update_fixing_fix_vehicle(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
progressToNextSubstate = peep_update_fixing_fix_vehicle_malfunction(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
progressToNextSubstate = peep_update_fixing_move_to_station_end(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
progressToNextSubstate = peep_update_fixing_fix_station_end(firstRun, this);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
progressToNextSubstate = peep_update_fixing_move_to_station_start(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
progressToNextSubstate = peep_update_fixing_fix_station_start(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
progressToNextSubstate = peep_update_fixing_fix_station_brakes(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
progressToNextSubstate = peep_update_fixing_move_to_station_exit(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
progressToNextSubstate = peep_update_fixing_finish_fix_or_inspect(firstRun, steps, this, ride);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
progressToNextSubstate = peep_update_fixing_leave_by_entrance_exit(firstRun, this, ride);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Invalid substate");
|
||||
progressToNextSubstate = false;
|
||||
}
|
||||
|
||||
firstRun = false;
|
||||
|
||||
if (!progressToNextSubstate)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sint32 subState = sub_state;
|
||||
uint32 sub_state_sequence_mask = peep_fixing_sub_state_mask[8];
|
||||
|
||||
if (state != PEEP_STATE_INSPECTING)
|
||||
{
|
||||
sub_state_sequence_mask = peep_fixing_sub_state_mask[ride->breakdown_reason_pending];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
subState++;
|
||||
} while ((sub_state_sequence_mask & (1 << subState)) == 0);
|
||||
|
||||
sub_state = subState & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C0EEC
|
||||
* fixing sub_state: enter_station - applies to fixing all break down reasons and ride inspections.
|
||||
*/
|
||||
static bool peep_update_fixing_enter_station(Ride * ride)
|
||||
{
|
||||
ride->mechanic_status = RIDE_MECHANIC_STATUS_FIXING;
|
||||
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C0F09
|
||||
* fixing sub_state: move_to_broken_down_vehicle - applies to fixing all vehicle specific breakdown reasons
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_move_to_broken_down_vehicle(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
sint16 x, y, tmp_xy_distance;
|
||||
|
||||
if (!firstRun)
|
||||
{
|
||||
rct_vehicle * vehicle = ride_get_broken_vehicle(ride);
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (vehicle->is_child == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
uint8 trackType = vehicle->track_type >> 2;
|
||||
if (trackType == TRACK_ELEM_END_STATION)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (trackType == TRACK_ELEM_BEGIN_STATION)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (trackType == TRACK_ELEM_MIDDLE_STATION)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
||||
}
|
||||
|
||||
LocationXY16 offset = word_981D6C[peep->direction];
|
||||
peep->destination_x = (offset.x * -12) + vehicle->x;
|
||||
peep->destination_y = (offset.y * -12) + vehicle->y;
|
||||
peep->destination_tolerance = 2;
|
||||
}
|
||||
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
if (peep->UpdateAction(&x, &y, &tmp_xy_distance))
|
||||
{
|
||||
sprite_move(x, y, peep->z, (rct_sprite *)peep);
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C0FD3
|
||||
* fixing sub_state: fix_vehicle - applies to fixing vehicle with:
|
||||
* 1. restraints stuck closed,
|
||||
* 2. doors stuck closed,
|
||||
* 3. restrains stuck open,
|
||||
* 4. doors stuck open.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_fix_vehicle(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
|
||||
peep->action = (scenario_rand() & 1) ? PEEP_ACTION_STAFF_FIX_2 : PEEP_ACTION_STAFF_FIX;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_frame = 0;
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action == PEEP_ACTION_NONE_2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->UpdateAction();
|
||||
|
||||
uint8 actionFrame = (peep->action == PEEP_ACTION_STAFF_FIX) ? 0x25 : 0x50;
|
||||
if (peep->action_frame != actionFrame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
rct_vehicle * vehicle = ride_get_broken_vehicle(ride);
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_BROKEN_CAR;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C107B
|
||||
* fixing sub_state: fix_vehicle_malfunction - applies fixing to vehicle malfunction.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_fix_vehicle_malfunction(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
peep->action = PEEP_ACTION_STAFF_FIX_3;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
peep->action_frame = 0;
|
||||
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action == PEEP_ACTION_NONE_2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->UpdateAction();
|
||||
if (peep->action_frame != 0x65)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
rct_vehicle * vehicle = ride_get_broken_vehicle(ride);
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_BROKEN_TRAIN;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** rct2: 0x00992A3C */
|
||||
static constexpr const CoordsXY _992A3C[] = {
|
||||
{ -12, 0 },
|
||||
{ 0, 12 },
|
||||
{ 12, 0 },
|
||||
{ 0, -12 },
|
||||
};
|
||||
|
||||
/**
|
||||
* rct2: 0x006C1114
|
||||
* fixing sub_state: move_to_station_end - applies to fixing station specific breakdowns: safety cut-out, control failure, inspection.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_move_to_station_end(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
sint16 x, y, tmp_distance;
|
||||
|
||||
if (!firstRun)
|
||||
{
|
||||
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_3 | RIDE_TYPE_FLAG_HAS_NO_TRACK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LocationXY8 stationPosition = ride->station_starts[peep->current_ride_station];
|
||||
if (stationPosition.xy == RCT_XY8_UNDEFINED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8 stationZ = ride->station_heights[peep->current_ride_station];
|
||||
uint16 stationX = stationPosition.x * 32;
|
||||
uint16 stationY = stationPosition.y * 32;
|
||||
|
||||
rct_tile_element * tileElement = map_get_track_element_at(stationX, stationY, stationZ);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
log_error("Couldn't find tile_element");
|
||||
return false;
|
||||
}
|
||||
|
||||
sint32 direction = tile_element_get_direction(tileElement);
|
||||
CoordsXY offset = _992A3C[direction];
|
||||
|
||||
stationX += 16 + offset.x;
|
||||
if (offset.x == 0)
|
||||
{
|
||||
stationX = peep->destination_x;
|
||||
}
|
||||
|
||||
stationY += 16 + offset.y;
|
||||
if (offset.y == 0)
|
||||
{
|
||||
stationY = peep->destination_y;
|
||||
}
|
||||
|
||||
peep->destination_x = stationX;
|
||||
peep->destination_y = stationY;
|
||||
peep->destination_tolerance = 2;
|
||||
}
|
||||
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
if (!peep->UpdateAction(&x, &y, &tmp_distance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
sprite_move(x, y, peep->z, (rct_sprite *)peep);
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C11F5
|
||||
* fixing sub_state: fix_station_end - applies to fixing station specific breakdowns: safety cut-out, control failure, inspection.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_fix_station_end(bool firstRun, rct_peep * peep)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
peep->action = PEEP_ACTION_STAFF_CHECKBOARD;
|
||||
peep->action_frame = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action == PEEP_ACTION_NONE_2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->UpdateAction();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C1239
|
||||
* fixing sub_state: move_to_station_start
|
||||
* 1. applies to fixing station specific breakdowns: safety cut-out, control failure,
|
||||
* 2. applies to fixing brake failure,
|
||||
* 3. applies to inspection.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_move_to_station_start(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
sint16 x, y, tmp_xy_distance;
|
||||
|
||||
if (!firstRun)
|
||||
{
|
||||
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_3 | RIDE_TYPE_FLAG_HAS_NO_TRACK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LocationXY8 stationPosition = ride->station_starts[peep->current_ride_station];
|
||||
if (stationPosition.xy == RCT_XY8_UNDEFINED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8 stationZ = ride->station_heights[peep->current_ride_station];
|
||||
|
||||
CoordsXYE input;
|
||||
input.x = stationPosition.x * 32;
|
||||
input.y = stationPosition.y * 32;
|
||||
input.element = map_get_track_element_at_from_ride(input.x, input.y, stationZ, peep->current_ride);
|
||||
if (input.element == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8 direction = 0;
|
||||
track_begin_end trackBeginEnd;
|
||||
while (track_block_get_previous(input.x, input.y, input.element, &trackBeginEnd))
|
||||
{
|
||||
if (track_element_is_station(trackBeginEnd.begin_element))
|
||||
{
|
||||
input.x = trackBeginEnd.begin_x;
|
||||
input.y = trackBeginEnd.begin_y;
|
||||
input.element = trackBeginEnd.begin_element;
|
||||
|
||||
direction = tile_element_get_direction(trackBeginEnd.begin_element);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// loc_6C12ED:
|
||||
uint16 destinationX = input.x + 16;
|
||||
uint16 destinationY = input.y + 16;
|
||||
|
||||
CoordsXY offset = _992A3C[direction];
|
||||
|
||||
destinationX -= offset.x;
|
||||
if (offset.x == 0)
|
||||
{
|
||||
destinationX = peep->destination_x;
|
||||
}
|
||||
|
||||
destinationY -= offset.y;
|
||||
if (offset.y == 0)
|
||||
{
|
||||
destinationY = peep->destination_y;
|
||||
}
|
||||
|
||||
peep->destination_x = destinationX;
|
||||
peep->destination_y = destinationY;
|
||||
peep->destination_tolerance = 2;
|
||||
}
|
||||
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
|
||||
if (!peep->UpdateAction(&x, &y, &tmp_xy_distance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
sprite_move(x, y, peep->z, (rct_sprite *)peep);
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C1368
|
||||
* fixing sub_state: fix_station_start
|
||||
* 1. applies to fixing station specific breakdowns: safety cut-out, control failure,
|
||||
* 2. applies to inspection.
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_fix_station_start(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_3 | RIDE_TYPE_FLAG_HAS_NO_TRACK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
|
||||
peep->action = PEEP_ACTION_STAFF_FIX;
|
||||
peep->action_frame = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action == PEEP_ACTION_NONE_2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->UpdateAction();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C13CE
|
||||
* fixing sub_state: fix_station_brakes - applies to fixing brake failure
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_fix_station_brakes(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
|
||||
peep->action = PEEP_ACTION_STAFF_FIX_GROUND;
|
||||
peep->action_frame = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action == PEEP_ACTION_NONE_2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->UpdateAction();
|
||||
if (peep->action_frame == 0x28)
|
||||
{
|
||||
ride->mechanic_status = RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES;
|
||||
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
||||
}
|
||||
|
||||
if (peep->action_frame == 0x13 || peep->action_frame == 0x19 || peep->action_frame == 0x1F || peep->action_frame == 0x25 ||
|
||||
peep->action_frame == 0x2B)
|
||||
{
|
||||
audio_play_sound_at_location(SOUND_MECHANIC_FIX, peep->x, peep->y, peep->z);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C1474
|
||||
* fixing sub_state: move_to_station_exit - applies to fixing all failures & inspections
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_move_to_station_exit(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
sint16 x, y, tmp_xy_distance;
|
||||
|
||||
if (!firstRun)
|
||||
{
|
||||
TileCoordsXYZD stationPosition = ride_get_exit_location(ride, peep->current_ride_station);
|
||||
if (stationPosition.isNull())
|
||||
{
|
||||
stationPosition = ride_get_entrance_location(ride, peep->current_ride_station);
|
||||
|
||||
if (stationPosition.isNull())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 stationX = stationPosition.x * 32;
|
||||
uint16 stationY = stationPosition.y * 32;
|
||||
|
||||
stationX += 16;
|
||||
stationY += 16;
|
||||
|
||||
LocationXY16 direction = word_981D6C[peep->direction];
|
||||
|
||||
stationX += direction.x * 20;
|
||||
stationY += direction.y * 20;
|
||||
|
||||
peep->destination_x = stationX;
|
||||
peep->destination_y = stationY;
|
||||
peep->destination_tolerance = 2;
|
||||
}
|
||||
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
if (!peep->UpdateAction(&x, &y, &tmp_xy_distance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_move(x, y, peep->z, (rct_sprite *)peep);
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C1504
|
||||
* fixing sub_state: finish_fix_or_inspect - applies to fixing all failures & inspections
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_finish_fix_or_inspect(bool firstRun, sint32 steps, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
if (!firstRun)
|
||||
{
|
||||
ride->mechanic_status = RIDE_MECHANIC_STATUS_UNDEFINED;
|
||||
|
||||
if (peep->state == PEEP_STATE_INSPECTING)
|
||||
{
|
||||
peep_update_ride_inspected(peep->current_ride);
|
||||
|
||||
peep->staff_rides_inspected++;
|
||||
peep->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME | RIDE_INVALIDATE_RIDE_LIST;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
peep->staff_rides_fixed++;
|
||||
peep->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME | RIDE_INVALIDATE_RIDE_LIST;
|
||||
|
||||
peep->sprite_direction = peep->direction << 3;
|
||||
peep->action = PEEP_ACTION_STAFF_ANSWER_CALL_2;
|
||||
peep->action_frame = 0;
|
||||
peep->action_sprite_image_offset = 0;
|
||||
|
||||
peep->UpdateCurrentActionSpriteType();
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
}
|
||||
|
||||
if (peep->action != 0xFF)
|
||||
{
|
||||
peep->UpdateAction();
|
||||
return false;
|
||||
}
|
||||
|
||||
ride_fix_breakdown(peep->current_ride, steps);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x006C157E
|
||||
* fixing sub_state: leave_by_entrance_exit - applies to fixing all failures & inspections
|
||||
* - see peep_fixing_sub_state_mask[]
|
||||
*/
|
||||
static bool peep_update_fixing_leave_by_entrance_exit(bool firstRun, rct_peep * peep, Ride * ride)
|
||||
{
|
||||
sint16 x, y, xy_distance;
|
||||
|
||||
if (!firstRun)
|
||||
{
|
||||
TileCoordsXYZD exitPosition = ride_get_exit_location(ride, peep->current_ride_station);
|
||||
if (exitPosition.isNull())
|
||||
{
|
||||
exitPosition = ride_get_entrance_location(ride, peep->current_ride_station);
|
||||
|
||||
if (exitPosition.isNull())
|
||||
{
|
||||
peep->SetState(PEEP_STATE_FALLING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 exitX = exitPosition.x * 32;
|
||||
uint16 exitY = exitPosition.y * 32;
|
||||
|
||||
exitX += 16;
|
||||
exitY += 16;
|
||||
|
||||
LocationXY16 ebx_direction = word_981D6C[peep->direction];
|
||||
exitX -= ebx_direction.x * 19;
|
||||
exitY -= ebx_direction.y * 19;
|
||||
|
||||
peep->destination_x = exitX;
|
||||
peep->destination_y = exitY;
|
||||
peep->destination_tolerance = 2;
|
||||
}
|
||||
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
if (!peep->UpdateAction(&x, &y, &xy_distance))
|
||||
{
|
||||
peep->SetState(PEEP_STATE_FALLING);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 z = ride->station_heights[peep->current_ride_station] * 8;
|
||||
|
||||
if (xy_distance >= 16)
|
||||
{
|
||||
z += RideData5[ride->type].z;
|
||||
}
|
||||
|
||||
sprite_move(x, y, z, (rct_sprite *)peep);
|
||||
invalidate_sprite_2((rct_sprite *)peep);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x6B7588
|
||||
*/
|
||||
static void peep_update_ride_inspected(sint32 rideIndex)
|
||||
{
|
||||
Ride * ride = get_ride(rideIndex);
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_DUE_INSPECTION;
|
||||
|
||||
ride->reliability += ((100 - ride->reliability_percentage) / 4) * (scenario_rand() & 0xFF);
|
||||
ride->last_inspection = 0;
|
||||
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE | RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user