Start implementing sub_693C9E

This commit is contained in:
Duncan Frost 2015-07-21 19:17:25 +01:00
parent 04dcca5468
commit 9cf5240c90
2 changed files with 459 additions and 4 deletions

View File

@ -33,6 +33,7 @@
#include "../sprites.h"
#include "../world/sprite.h"
#include "../world/scenery.h"
#include "../world/footpath.h"
#include "../management/marketing.h"
#include "peep.h"
#include "staff.h"
@ -48,7 +49,7 @@ static int peep_empty_container_extra_flag(rct_peep* peep);
static int peep_should_find_bench(rct_peep* peep);
static void peep_stop_purchase_thought(rct_peep* peep, uint8 ride_type);
static void sub_693BAB(rct_peep* peep);
static void sub_693C9E(rct_peep *peep);
static int sub_693C9E(rct_peep *peep);
static void peep_spend_money(rct_peep *peep, money16 *peep_expend_type, money32 amount);
static void peep_set_has_ridden(rct_peep *peep, int rideIndex);
static bool peep_has_ridden(rct_peep *peep, int rideIndex);
@ -57,6 +58,7 @@ static bool peep_has_ridden_ride_type(rct_peep *peep, int rideType);
static void peep_on_enter_or_exit_ride(rct_peep *peep, int rideIndex, int flags);
static bool sub_69AF1E(rct_peep *peep, int rideIndex, int shopItem, money32 price);
static bool peep_should_use_cash_machine(rct_peep *peep, int rideIndex);
static bool sub_6960AB(rct_peep *peep, int rideIndex, int dh, int bp);
static void sub_69A98C(rct_peep *peep);
static void sub_68FD3A(rct_peep *peep);
static bool sub_690B99(rct_peep *peep, int edge, uint8 *rideToView, uint8 *rideSeatToView);
@ -5955,12 +5957,465 @@ void sub_693BAB(rct_peep* peep) {
}
}
/**
*
* rct2: 0x00693CBB
*/
static int peep_update_queue_position(rct_peep* peep){
peep->time_in_queue++;
if (peep->next_in_queue == 0xFFFF)
return 0;
rct_peep* peep_next = GET_PEEP(peep->next_in_queue);
sint16 x_diff = abs(peep_next->x - peep->x);
sint16 y_diff = abs(peep_next->y - peep->y);
sint16 z_diff = abs(peep_next->z - peep->z);
if (z_diff > 10)
return 0;
if (x_diff < y_diff){
sint16 temp_x = x_diff;
x_diff = y_diff;
y_diff = temp_x;
}
x_diff += y_diff / 2;
if (x_diff > 7){
if (x_diff > 13){
if ((peep->x & 0xFFE0) != (peep_next->x & 0xFFE0) ||
(peep->y & 0xFFE0) != (peep_next->y & 0xFFE0))
return 0;
}
if (peep->sprite_direction != peep_next->sprite_direction)
return 0;
switch (peep->sprite_direction / 8){
case 0:
if (peep->x >= peep_next->x)
return 0;
break;
case 1:
if (peep->y <= peep_next->y)
return 0;
break;
case 2:
if (peep->x <= peep_next->x)
return 0;
break;
case 3:
if (peep->y >= peep_next->y)
return 0;
break;
}
}
sint16 xy_dist, x, y;
if (peep->action < PEEP_ACTION_NONE_1)
peep_update_action(&x, &y, &xy_dist, peep);
if (peep->action != PEEP_ACTION_NONE_2)
return 1;
peep->action = PEEP_ACTION_NONE_1;
peep->var_6F = 2;
if (RCT2_GLOBAL(0x00F1AEF1, uint8) != 0xFE)
invalidate_sprite((rct_sprite*)peep);
return 1;
}
/* rct2: 0x00693EF2 */
static int peep_return_to_center_of_tile(rct_peep* peep){
peep->var_78 ^= (1 << 1);
peep->destination_x = peep->x & 0xFFE0 + 16;
peep->destination_y = peep->y & 0xFFE0 + 16;
peep->destination_tolerence = 5;
return 1;
}
/* rct2: 0x00693f2C*/
static int peep_interact_with_entrance(rct_peep* peep, sint16 x, sint16 y, rct_map_element* map_element){
uint8 entranceType = map_element->properties.entrance.type;
uint8 rideIndex = map_element->properties.entrance.ride_index;
if (entranceType == ENTRANCE_TYPE_RIDE_EXIT){
RCT2_GLOBAL(0x00F1EE18, uint8) |= (1 << 2);
RCT2_GLOBAL(0x00F1EE1A, rct_map_element*) = map_element;
}
else if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE){
RCT2_GLOBAL(0x00F1EE18, uint8) |= (1 << 3);
RCT2_GLOBAL(0x00F1EE1A, rct_map_element*) = map_element;
}
if (entranceType == ENTRANCE_TYPE_RIDE_EXIT){
peep->var_79 = 0xFF;
return peep_return_to_center_of_tile(peep);
}
if (entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE){
if (peep->type == PEEP_TYPE_STAFF){
peep->var_79 = 0xFF;
return peep_return_to_center_of_tile(peep);
}
if (peep->state = PEEP_STATE_QUEUING){
peep->sub_state = 11;
peep->action_sprite_image_offset = RCT2_GLOBAL(0x00F1AEF0, uint8);
return 1;
}
if (peep->var_79 == rideIndex)
return peep_return_to_center_of_tile(peep);
peep->var_F4 = 0;
uint8 stationNum = (map_element->properties.entrance.index >> 4) & 0x7;
if (!sub_6960AB(peep, rideIndex, stationNum, 0)){
peep->var_79 = rideIndex;
return peep_return_to_center_of_tile(peep);
}
peep->action_sprite_image_offset = RCT2_GLOBAL(0x00F1AEF0, uint8);
peep->var_79 = rideIndex;
rct_ride* ride = GET_RIDE(rideIndex);
uint16 previous_first = ride->first_peep_in_queue[stationNum];
ride->first_peep_in_queue[stationNum] = peep->sprite_index;
peep->next_in_queue = previous_first;
ride->queue_length[stationNum]++;
peep_decrement_num_riders(peep);
peep->current_ride = rideIndex;
peep->current_ride_station = stationNum;
peep->state = PEEP_STATE_QUEUING;
peep->days_in_queue = 0;
peep_window_state_update(peep);
peep->sub_state = 11;
peep->time_in_queue = 0;
if (peep->flags & PEEP_FLAGS_TRACKING){
RCT2_GLOBAL(0x0013CE952, rct_string_id) = peep->name_string_idx;
RCT2_GLOBAL(0x0013CE954, uint32) = peep->id;
RCT2_GLOBAL(0x0013CE958, rct_string_id) = ride->name;
RCT2_GLOBAL(0x0013CE95A, uint32) = ride->name_arguments;
news_item_add_to_queue(NEWS_ITEM_PEEP_ON_RIDE, 1931, peep->sprite_index);
}
return 1;
}
else{
// PARK_ENTRANCE
if (peep->type == PEEP_TYPE_STAFF)
return peep_return_to_center_of_tile(peep);
// If not the center of the entrance arch
if (map_element->properties.entrance.index & 0xF)
return peep_return_to_center_of_tile(peep);
uint8 entranceDirection = map_element->type & MAP_ELEMENT_DIRECTION_MASK;
if (entranceDirection != peep->var_78){
if ((entranceDirection ^ (1 << 1)) != peep->var_78)
return peep_return_to_center_of_tile(peep);
// Peep is leaving the park.
if (peep->state != PEEP_STATE_WALKING)
return peep_return_to_center_of_tile(peep);
if (!(peep->flags & PEEP_FLAGS_LEAVING_PARK)){
// If the park is open and leaving flag isnt set return to center
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN)
return peep_return_to_center_of_tile(peep);
}
peep->destination_x += RCT2_ADDRESS(0x00993CCC, sint16)[peep->var_78 * 2];
peep->destination_y += RCT2_ADDRESS(0x00993CCE, sint16)[peep->var_78 * 2];
peep->destination_tolerence = 9;
invalidate_sprite((rct_sprite*)peep);
sprite_move(peep->destination_x, peep->destination_y, peep->z, (rct_sprite*)peep);
invalidate_sprite((rct_sprite*)peep);
peep_decrement_num_riders(peep);
peep->state = PEEP_STATE_LEAVING_PARK;
peep_window_state_update(peep);
peep->var_37 = 0;
if (peep->flags & PEEP_FLAGS_TRACKING){
RCT2_GLOBAL(0x0013CE952, rct_string_id) = peep->name_string_idx;
RCT2_GLOBAL(0x0013CE954, uint32) = peep->id;
news_item_add_to_queue(NEWS_ITEM_PEEP_ON_RIDE, 1935, peep->sprite_index);
}
return 1;
}
// Peep is entering the park.
if (peep->state != PEEP_STATE_ENTERING_PARK)
return peep_return_to_center_of_tile(peep);
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN)){
peep->state = PEEP_STATE_LEAVING_PARK;
peep->var_37 = 1;
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--;
peep_window_state_update(peep);
return peep_return_to_center_of_tile(peep);
}
uint8 entranceIndex = 0;
while (1){
if (RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_X, sint16)[entranceIndex] == (x & 0xFFE0) &&
RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_Y, sint16)[entranceIndex] == (y & 0xFFE0))
break;
entranceIndex++;
}
sint16 z = RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_Z, sint16)[entranceIndex] / 8;
entranceDirection = RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_DIRECTION, uint8)[entranceIndex];
sint16 next_x = (x & 0xFFE0) + RCT2_ADDRESS(0x00993CCC, sint16)[entranceDirection * 2];
sint16 next_y = (y & 0xFFE0) + RCT2_ADDRESS(0x00993CCE, sint16)[entranceDirection * 2];
uint8 found = 0;
rct_map_element* nextMapElement = map_get_first_element_at(next_x / 32, next_y / 32);
do{
if (map_element_get_type(nextMapElement) != MAP_ELEMENT_TYPE_PATH)
continue;
if (nextMapElement->type & 1)
continue;
if (footpath_element_is_sloped(nextMapElement)){
uint8 slopeDirection = footpath_element_get_slope_direction(nextMapElement);
if (slopeDirection == entranceDirection){
if (z != nextMapElement->base_height){
continue;
}
found = 1;
break;
}
if ((slopeDirection ^ (1 << 1)) != entranceDirection)
continue;
if (z - 2 != nextMapElement->base_height)
continue;
found = 1;
break;
}
else{
if (z != nextMapElement->base_height){
continue;
}
found = 1;
break;
}
} while (!map_element_is_last_for_tile(nextMapElement++));
if (!found){
peep->state = PEEP_STATE_LEAVING_PARK;
peep->var_37 = 1;
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--;
peep_window_state_update(peep);
return peep_return_to_center_of_tile(peep);
}
money16 entranceFee = RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16);
if (entranceFee != 0){
if (peep->item_standard_flags & PEEP_ITEM_VOUCHER){
if (peep->voucher_type == VOUCHER_TYPE_PARK_ENTRY_HALF_PRICE){
entranceFee /= 2;
peep->item_standard_flags &= ~PEEP_ITEM_VOUCHER;
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
}
else if (peep->voucher_type == VOUCHER_TYPE_PARK_ENTRY_FREE){
entranceFee = 0;
peep->item_standard_flags &= ~PEEP_ITEM_VOUCHER;
peep->window_invalidate_flags |= PEEP_INVALIDATE_PEEP_INVENTORY;
}
}
if (entranceFee > peep->cash_in_pocket){
peep->state = PEEP_STATE_LEAVING_PARK;
peep->var_37 = 1;
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--;
peep_window_state_update(peep);
return peep_return_to_center_of_tile(peep);
}
RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, money32) += entranceFee;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_PARK_ENTRANCE_TICKETS * 4;
peep_spend_money(peep, &peep->paid_to_enter, entranceFee);
peep->flags |= PEEP_FLAGS_5;
}
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_ADMISSIONS, uint32)++;
window_invalidate_by_number(WC_PARK_INFORMATION, 0);
peep->var_37 = 1;
peep->destination_x += RCT2_ADDRESS(0x00993CCC, sint16)[peep->var_78 * 2];
peep->destination_y += RCT2_ADDRESS(0x00993CCE, sint16)[peep->var_78 * 2];
peep->destination_tolerence = 7;
invalidate_sprite((rct_sprite*)peep);
sprite_move(peep->destination_x, peep->destination_y, peep->z, (rct_sprite*)peep);
invalidate_sprite((rct_sprite*)peep);
return 1;
}
}
/* rct2: 0x00693F70 */
static int peep_interact_with_shop(rct_peep* peep, sint16 x, sint16 y, rct_map_element* map_element){
uint8 rideIndex = map_element->properties.track.ride_index;
rct_ride* ride = GET_RIDE(rideIndex);
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP))
return 0;
if (peep->type == PEEP_TYPE_STAFF)
return peep_return_to_center_of_tile(peep);
peep->var_F4 = 0;
if (ride->status != RIDE_STATUS_OPEN)
return peep_return_to_center_of_tile(peep);
if (peep->var_79 == rideIndex)
return peep_return_to_center_of_tile(peep);
if (peep->flags & PEEP_FLAGS_LEAVING_PARK)
return peep_return_to_center_of_tile(peep);
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_21)){
peep->var_F4 = 0;
if (!sub_6960AB(peep, rideIndex, 0, 0))
return peep_return_to_center_of_tile(peep);
money16 cost = ride->price;
if (cost != 0){
ride->total_profit += cost;
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME;
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_PARK_RIDE_TICKETS * 4;
peep_spend_money(peep, NULL, cost);
}
peep->destination_x = x + 16;
peep->destination_y = y + 16;
peep->destination_tolerence = 3;
peep_decrement_num_riders(peep);
peep->current_ride = rideIndex;
peep->state = PEEP_STATE_ENTERING_RIDE;
peep->sub_state = 19;
peep_window_state_update(peep);
peep->time_on_ride = 0;
ride->var_120++;
if (peep->flags & PEEP_FLAGS_TRACKING){
RCT2_GLOBAL(0x0013CE952, rct_string_id) = peep->name_string_idx;
RCT2_GLOBAL(0x0013CE954, uint32) = peep->id;
RCT2_GLOBAL(0x0013CE958, rct_string_id) = ride->name;
RCT2_GLOBAL(0x0013CE95A, uint32) = ride->name_arguments;
rct_string_id string_id = ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IN_RIDE) ? 1933 : 1932;
news_item_add_to_queue(NEWS_ITEM_PEEP_ON_RIDE, string_id, peep->sprite_index);
}
return 1;
}
else{
if (peep->guest_heading_to_ride_id == rideIndex)
peep->guest_heading_to_ride_id = 0xFF;
peep->action_sprite_image_offset = RCT2_GLOBAL(0x00F1AEF0, uint8);
peep_decrement_num_riders(peep);
peep->current_ride = rideIndex;
peep->state = PEEP_STATE_BUYING;
peep->sub_state = 0;
peep_window_state_update(peep);
return 1;
}
}
/**
*
* rct2: 0x00693C9E
*/
static void sub_693C9E(rct_peep *peep)
static int sub_693C9E(rct_peep *peep)
{
RCT2_GLOBAL(0x00F1EE18, uint16) = 0;
RCT2_GLOBAL(0x00F1AEF1, uint8) = peep->action;
if (peep->action == PEEP_ACTION_NONE_1)
peep->action = PEEP_ACTION_NONE_2;
if (peep->state == PEEP_STATE_QUEUING){
if (peep_update_queue_position(peep))
return 1;
}
//693dc1
sint16 x, y, xy_dist;
if (!peep_update_action(&x, &y, &xy_dist, peep)){
RCT2_GLOBAL(0x00F1EE18, uint16) |= 1;
uint8 result = 0;
if (peep->type == PEEP_TYPE_GUEST){
result = RCT2_CALLPROC_X(0x00694C35, x, 0, y, 0, (int)peep, 0, 0) & 0x100;
}
else{
result = RCT2_CALLPROC_X(0x006BF926, x, 0, y, 0, (int)peep, 0, 0) & 0x100;
}
if (result != 0)
return 1;
if (peep_update_action(&x, &y, &xy_dist, peep))
return 1;
}
if ((x & 0xFFE0) == peep->next_x && (y & 0xFFE0) == peep->next_y){
sint16 z = peep_get_height_on_slope(peep, x, y);
invalidate_sprite((rct_sprite*)peep);
sprite_move(x, y, z, (rct_sprite*)peep);
invalidate_sprite((rct_sprite*)peep);
return 1;
}
//693e16
if (x < 32 || y >= 32 || x < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) || y < RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16)){
if (peep->type == PEEP_TYPE_STAFF){
RCT2_GLOBAL(0x00F1EE18, uint16) |= (1 << 1);
}
return peep_return_to_center_of_tile(peep);
}
rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32);
sint16 base_z = max(0, (peep->z / 8) - 2);
sint16 top_z = (peep->z / 8) + 1;
do{
if (base_z > mapElement->base_height)
continue;
if (top_z < mapElement->base_height)
continue;
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH){
if ((mapElement->flags & MAP_ELEMENT_FLAG_GHOST))
continue;
//goto 69455e
}
else if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK){
if (peep_interact_with_shop(peep, x, y, mapElement))
return 1;
}
else if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE){
if (peep_interact_with_entrance(peep, x, y, mapElement))
return 1;
}
} while (!map_element_is_last_for_tile(mapElement++));
if (peep->type == PEEP_TYPE_STAFF || (peep->next_var_29 & 0x18)){
sint16 z = abs(map_element_height(x, y) - peep->z);
if (z <= 3 || (peep->type == PEEP_TYPE_STAFF && z <= 32)){
//goto 6944d9
}
}
return peep_return_to_center_of_tile(peep);
RCT2_CALLPROC_X(0x00693C9E, 0, 0, 0, 0, (int)peep, 0, 0);
}

View File

@ -252,7 +252,7 @@ enum PEEP_FLAGS {
PEEP_FLAGS_TRACKING = (1 << 3),
PEEP_FLAGS_WAVING = (1 << 4), // Makes the peep wave
PEEP_FLAGS_5 = (1 << 5),
PEEP_FLAGS_5 = (1 << 5), // Set on paying to enter park?
PEEP_FLAGS_PHOTO = (1 << 6), // Makes the peep take a picture
PEEP_FLAGS_PAINTING = (1 << 7),
PEEP_FLAGS_WOW = (1 << 8), // Makes a peep WOW2
@ -451,7 +451,7 @@ typedef struct {
uint8 pad_77;
union{
uint8 maze_last_edge; // 0x78
uint8 var_78;
uint8 var_78; //Direction ?
};
uint8 var_79;
uint16 time_in_queue; // 0x7A