diff --git a/src/game.c b/src/game.c index 3c4d6f3f48..5a56eefcfd 100644 --- a/src/game.c +++ b/src/game.c @@ -83,6 +83,8 @@ GAME_COMMAND_CALLBACK_POINTER* game_command_callback_table[] = { game_command_callback_place_banner, game_command_callback_place_ride_entrance_or_exit, game_command_callback_hire_new_staff_member, + game_command_callback_pickup_guest, + game_command_callback_pickup_staff, }; int game_command_playerid = -1; @@ -309,7 +311,6 @@ void game_update() // Always perform autosave check, even when paused scenario_autosave_check(); - network_update(); window_dispatch_update_all(); gGameCommandNestLevel = 0; @@ -1098,7 +1099,7 @@ void game_load_or_quit_no_save_prompt() } } -GAME_COMMAND_POINTER* new_game_command_table[68] = { +GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_set_ride_appearance, game_command_set_land_height, game_pause_toggle, @@ -1166,4 +1167,7 @@ GAME_COMMAND_POINTER* new_game_command_table[68] = { game_command_modify_groups, game_command_kick_player, game_command_cheat, + game_command_pickup_guest, + game_command_pickup_staff, + game_command_balloon_press, }; diff --git a/src/game.h b/src/game.h index c8733abe9a..c02a67835c 100644 --- a/src/game.h +++ b/src/game.h @@ -90,6 +90,10 @@ enum GAME_COMMAND { GAME_COMMAND_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, GAME_COMMAND_CHEAT, + GAME_COMMAND_PICKUP_GUEST, + GAME_COMMAND_PICKUP_STAFF, + GAME_COMMAND_BALLOON_PRESS, + GAME_COMMAND_COUNT }; enum { @@ -129,7 +133,7 @@ extern rct_string_id gGameCommandErrorText; extern uint8 gErrorType; extern rct_string_id gErrorStringId; -extern GAME_COMMAND_POINTER* new_game_command_table[68]; +extern GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT]; #ifndef NO_RCT2 #define gCurrentTicks RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 0655272b55..6f8f8a857e 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -135,7 +135,7 @@ int viewport_interaction_left_click(int x, int y) if (game_is_not_paused()) { switch (info.sprite->unknown.misc_identifier) { case SPRITE_MISC_BALLOON: - balloon_press(&info.sprite->balloon); + game_do_command(info.sprite->balloon.sprite_index, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_BALLOON_PRESS, 0, 0); break; case SPRITE_MISC_DUCK: duck_press(&info.sprite->duck); diff --git a/src/interface/window.h b/src/interface/window.h index c0587b3ef2..bd90a61630 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -734,6 +734,9 @@ void window_map_tooltip_update_visibility(); void window_staff_list_init_vars(); +void game_command_callback_pickup_guest(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +void game_command_callback_pickup_staff(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); + void window_event_close_call(rct_window* w); void window_event_mouse_up_call(rct_window* w, int widgetIndex); void window_event_resize_call(rct_window* w); diff --git a/src/network/NetworkAction.cpp b/src/network/NetworkAction.cpp index 5100549073..4ea911294d 100644 --- a/src/network/NetworkAction.cpp +++ b/src/network/NetworkAction.cpp @@ -158,7 +158,9 @@ const std::vector NetworkActions::Actions = }, { STR_ACTION_GUEST, "PERMISSION_GUEST", { - GAME_COMMAND_SET_GUEST_NAME + GAME_COMMAND_SET_GUEST_NAME, + GAME_COMMAND_PICKUP_GUEST, + GAME_COMMAND_BALLOON_PRESS } }, { STR_ACTION_STAFF, "PERMISSION_STAFF", @@ -168,7 +170,8 @@ const std::vector NetworkActions::Actions = GAME_COMMAND_FIRE_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_ORDER, GAME_COMMAND_SET_STAFF_COLOUR, - GAME_COMMAND_SET_STAFF_NAME + GAME_COMMAND_SET_STAFF_NAME, + GAME_COMMAND_PICKUP_STAFF } }, { STR_ACTION_PARK_PROPERTIES, "PERMISSION_PARK_PROPERTIES", diff --git a/src/network/NetworkPlayer.h b/src/network/NetworkPlayer.h index bb4dba194f..3f477edecb 100644 --- a/src/network/NetworkPlayer.h +++ b/src/network/NetworkPlayer.h @@ -21,7 +21,9 @@ extern "C" { + #include "../peep/peep.h" #include "../world/map.h" + #include "../world/sprite.h" } class NetworkPacket; @@ -39,6 +41,8 @@ public: int last_action = -999; uint32 last_action_time = 0; rct_xyz16 last_action_coord = { 0 }; + rct_peep* pickup_peep = 0; + int pickup_peep_old_x = SPRITE_LOCATION_NULL; std::string keyhash; NetworkPlayer() = default; diff --git a/src/network/network.cpp b/src/network/network.cpp index 26a80e51a1..cc9df35ad4 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -33,6 +33,9 @@ extern "C" { extern "C" { } +rct_peep* _pickup_peep = 0; +int _pickup_peep_old_x = SPRITE_LOCATION_NULL; + #ifndef DISABLE_NETWORK #include @@ -1222,6 +1225,11 @@ void Network::RemoveClient(std::unique_ptr& connection) } chat_history_add(text); + rct_peep* pickup_peep = network_get_pickup_peep(connection_player->id); + if(pickup_peep) { + game_command_playerid = connection_player->id; + game_do_command(0, GAME_COMMAND_FLAG_APPLY, 1, 0, pickup_peep->type == PEEP_TYPE_GUEST ? GAME_COMMAND_PICKUP_GUEST : GAME_COMMAND_PICKUP_STAFF, network_get_pickup_peep_old_x(connection_player->id), 0); + } gNetwork.Server_Send_EVENT_PLAYER_DISCONNECTED((char*)connection_player->name.c_str(), connection->GetLastDisconnectReason()); } player_list.erase(std::remove_if(player_list.begin(), player_list.end(), [connection_player](std::unique_ptr& player){ @@ -2280,6 +2288,26 @@ int network_can_perform_command(unsigned int groupindex, unsigned int index) return gNetwork.group_list[groupindex]->CanPerformCommand(index); } +void network_set_pickup_peep(uint8 playerid, rct_peep* peep) +{ + gNetwork.GetMode() == NETWORK_MODE_NONE ? _pickup_peep = peep : gNetwork.GetPlayerByID(playerid)->pickup_peep = peep; +} + +rct_peep* network_get_pickup_peep(uint8 playerid) +{ + return gNetwork.GetMode() == NETWORK_MODE_NONE ? _pickup_peep : gNetwork.GetPlayerByID(playerid)->pickup_peep; +} + +void network_set_pickup_peep_old_x(uint8 playerid, int x) +{ + gNetwork.GetMode() == NETWORK_MODE_NONE ? _pickup_peep_old_x = x : gNetwork.GetPlayerByID(playerid)->pickup_peep_old_x = x; +} + +int network_get_pickup_peep_old_x(uint8 playerid) +{ + return gNetwork.GetMode() == NETWORK_MODE_NONE ? _pickup_peep_old_x : gNetwork.GetPlayerByID(playerid)->pickup_peep_old_x; +} + int network_get_current_player_group_index() { return network_get_group_index(gNetwork.GetPlayerByID(gNetwork.GetPlayerID())->group); @@ -2417,6 +2445,10 @@ int network_get_num_actions() { return 0; } rct_string_id network_get_action_name_string_id(unsigned int index) { return -1; } int network_can_perform_action(unsigned int groupindex, unsigned int index) { return 0; } int network_can_perform_command(unsigned int groupindex, unsigned int index) { return 0; } +void network_set_pickup_peep(uint8 playerid, rct_peep* peep) { _pickup_peep = peep; } +rct_peep* network_get_pickup_peep(uint8 playerid) { return _pickup_peep; } +void network_set_pickup_peep_old_x(uint8 playerid, int x) { _pickup_peep_old_x = x; } +int network_get_pickup_peep_old_x(uint8 playerid) { return _pickup_peep_old_x; } void network_send_chat(const char* text) {} void network_send_password(const char* password) {} void network_close() {} diff --git a/src/network/network.h b/src/network/network.h index 9a641049f0..2ef7ee687a 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -292,6 +292,10 @@ int network_get_num_actions(); rct_string_id network_get_action_name_string_id(unsigned int index); int network_can_perform_action(unsigned int groupindex, unsigned int index); int network_can_perform_command(unsigned int groupindex, unsigned int index); +void network_set_pickup_peep(uint8 playerid, rct_peep* peep); +rct_peep* network_get_pickup_peep(uint8 playerid); +void network_set_pickup_peep_old_x(uint8 playerid, int x); +int network_get_pickup_peep_old_x(uint8 playerid); void network_send_map(); void network_send_chat(const char* text); diff --git a/src/peep/peep.c b/src/peep/peep.c index 0c49d94d88..62e1d01d3c 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -25,6 +25,7 @@ #include "../management/marketing.h" #include "../management/news_item.h" #include "../openrct2.h" +#include "../network/network.h" #include "../ride/ride.h" #include "../ride/ride_data.h" #include "../ride/track.h" @@ -1886,6 +1887,164 @@ void peep_window_state_update(rct_peep* peep) } } +void peep_pickup(rct_peep* peep) +{ + remove_peep_from_ride(peep); + invalidate_sprite_2((rct_sprite*)peep); + + sprite_move(SPRITE_LOCATION_NULL, peep->y, peep->z, (rct_sprite*)peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_PICKED; + peep->sub_state = 0; + peep_window_state_update(peep); +} + +void peep_pickup_abort(rct_peep* peep, int old_x) +{ + if (!peep) + return; + + if (peep->state != PEEP_STATE_PICKED) + return; + + sprite_move(old_x, peep->y, peep->z + 8, (rct_sprite*)peep); + invalidate_sprite_2((rct_sprite*)peep); + + if (peep->x != (sint16)SPRITE_LOCATION_NULL){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + peep->action = 0xFF; + peep->special_sprite = 0; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0; + peep->var_C4 = 0; + } + + gPickupPeepImage = UINT32_MAX; +} + +bool peep_pickup_place(rct_peep* peep, int x, int y, int z, bool apply) +{ + if (!peep) + return false; + + rct_map_element *mapElement = map_get_path_element_at(x / 32, y / 32, z); + + if (!mapElement) { + mapElement = map_get_surface_element_at(x / 32, y / 32); + } + + if (!mapElement) + return false; + + int dest_x = x & 0xFFE0; + int dest_y = y & 0xFFE0; + + // Set the coordinate of destination to be exactly + // in the middle of a tile. + dest_x += 16; + dest_y += 16; + // Set the tile coordinate to top left of tile + int tile_y = dest_y & 0xFFE0; + int tile_x = dest_x & 0xFFE0; + + int dest_z = mapElement->base_height * 8 + 16; + + if (!map_is_location_owned(tile_x, tile_y, dest_z)){ + gGameCommandErrorTitle = STR_ERR_CANT_PLACE_PERSON_HERE; + return false; + } + + if (!map_can_construct_at(tile_x, tile_y, dest_z / 8, (dest_z / 8) + 1, 15)){ + if (gGameCommandErrorText != STR_RAISE_OR_LOWER_LAND_FIRST) { + if (gGameCommandErrorText != STR_FOOTPATH_IN_THE_WAY) { + gGameCommandErrorTitle = STR_ERR_CANT_PLACE_PERSON_HERE; + return false; + } + } + } + + if (apply) { + sprite_move(dest_x, dest_y, dest_z, (rct_sprite*)peep); + invalidate_sprite_2((rct_sprite*)peep); + peep_decrement_num_riders(peep); + peep->state = 0; + peep_window_state_update(peep); + peep->action = 0xFF; + peep->special_sprite = 0; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0; + peep->var_C4 = 0; + openrct2_reset_object_tween_locations(); + + if (peep->type == PEEP_TYPE_GUEST) { + peep->action_sprite_type = 0xFF; + peep->happiness_growth_rate = max(peep->happiness_growth_rate - 10, 0); + sub_693B58(peep); + } + + network_set_pickup_peep(game_command_playerid, 0); + } + + return true; +} + +bool peep_pickup_command(int peepnum, int x, int y, int z, int action, bool apply) +{ + rct_peep* peep = GET_PEEP(peepnum); + switch (action) { + case 0: // pickup + if (!peep) { + return false; + } + if (!peep_can_be_picked_up(peep)) { + return false; + } + if (network_get_pickup_peep(game_command_playerid)) { + // already picking up a peep + return false; + } + if (apply) { + network_set_pickup_peep(game_command_playerid, peep); + network_set_pickup_peep_old_x(game_command_playerid, peep->x); + peep_pickup(peep); + } + break; + case 1: // cancel + if (apply) { + peep_pickup_abort(network_get_pickup_peep(game_command_playerid), x); + network_set_pickup_peep(game_command_playerid, 0); + } + break; + case 2: // place + if (network_get_pickup_peep(game_command_playerid) != peep) { + return false; + } + if (!peep_pickup_place(peep, x, y, z, apply)) { + return false; + } + break; + } + return true; +} + +void game_command_pickup_guest(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + int peepnum = *eax; + int x = *edi; + int y = *ebp; + int z = *edx; + int action = *ecx; + if (peep_pickup_command(peepnum, x, y, z, action, *ebx & GAME_COMMAND_FLAG_APPLY)) { + *ebx = 0; + } + else + { + *ebx = MONEY32_UNDEFINED; + } +} + /** * * rct2: 0x0069A535 diff --git a/src/peep/peep.h b/src/peep/peep.h index c8f85c5989..c1bd61d592 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -652,6 +652,11 @@ int peep_get_easteregg_name_id(rct_peep *peep); int peep_is_mechanic(rct_peep *peep); bool peep_has_item(rct_peep *peep, int peepItem); int peep_has_food(rct_peep* peep); +void peep_pickup(rct_peep* peep); +void peep_pickup_abort(rct_peep* peep, int old_x); +bool peep_pickup_place(rct_peep* peep, int x, int y, int z, bool apply); +bool peep_pickup_command(int peepnum, int x, int y, int z, int action, bool apply); +void game_command_pickup_guest(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void peep_sprite_remove(rct_peep* peep); void peep_remove(rct_peep* peep); void peep_update_sprite_type(rct_peep* peep); diff --git a/src/peep/staff.c b/src/peep/staff.c index 5da75b2e13..3f4399a25e 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -22,6 +22,7 @@ #include "../localisation/string_ids.h" #include "../localisation/localisation.h" #include "../management/finance.h" +#include "../network/network.h" #include "../util/util.h" #include "../world/sprite.h" #include "../world/footpath.h" @@ -268,7 +269,8 @@ static money32 staff_hire_new_staff_member(uint8 staff_type, uint8 flags, sint16 newPeep->sprite_height_negative = spriteBounds->sprite_height_negative; newPeep->sprite_height_positive = spriteBounds->sprite_height_positive; - if (gConfigGeneral.auto_staff_placement != ((SDL_GetModState() & KMOD_SHIFT) != 0)) { + // gConfigGeneral.auto_staff_placement is client specific so we need to force this + if (network_get_mode() == NETWORK_MODE_NONE && gConfigGeneral.auto_staff_placement != ((SDL_GetModState() & KMOD_SHIFT) != 0)) { staff_autoposition_new_staff_member(newPeep); } else { newPeep->state = PEEP_STATE_PICKED; @@ -472,6 +474,10 @@ void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *ebx = MONEY32_UNDEFINED; return; } + if (peep->state == PEEP_STATE_PICKED) { + *ebx = MONEY32_UNDEFINED; + return; + } remove_peep_from_ride(peep); peep_sprite_remove(peep); } @@ -1345,6 +1351,22 @@ void game_command_set_staff_name(int *eax, int *ebx, int *ecx, int *edx, int *es ); } +void game_command_pickup_staff(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + int peepnum = *eax; + int x = *edi; + int y = *ebp; + int z = *edx; + int action = *ecx; + if (peep_pickup_command(peepnum, x, y, z, action, *ebx & GAME_COMMAND_FLAG_APPLY)) { + *ebx = 0; + } + else + { + *ebx = MONEY32_UNDEFINED; + } +} + colour_t staff_get_colour(uint8 staffType) { switch (staffType) { diff --git a/src/peep/staff.h b/src/peep/staff.h index f6d64c9119..acf16bd10e 100644 --- a/src/peep/staff.h +++ b/src/peep/staff.h @@ -74,6 +74,7 @@ void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *e void game_command_set_staff_patrol(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_set_staff_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); +void game_command_pickup_staff(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void staff_reset_modes(); void update_staff_colour(uint8 staffType, uint16 colour); diff --git a/src/windows/guest.c b/src/windows/guest.c index 1acd8c98dc..17467cf82b 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -592,6 +592,25 @@ void window_guest_overview_resize(rct_window *w){ window_guest_viewport_init(w); } +void game_command_callback_pickup_guest(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) +{ + switch(ecx){ + case 0:{ + int peepnum = eax; + rct_window* w = window_find_by_number(WC_PEEP, peepnum); + if (w) { + tool_set(w, WIDX_PICKUP, 7); + } + }break; + case 2: + if (ebx == 0) { + tool_cancel(); + gPickupPeepImage = UINT32_MAX; + } + break; + } +} + /** * * rct2: 0x00696A06 @@ -613,32 +632,12 @@ void window_guest_overview_mouse_up(rct_window *w, int widgetIndex) window_guest_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_PICKUP: - { // remove this block when peep pick up is finally converted to a game command - int player = network_get_player_index(network_get_current_player_id()); - if (player != -1) { - if (!network_can_perform_action(network_get_group_index(network_get_player_group(player)), 11/*Guest action*/)) { - window_error_open(STR_CANT_DO_THIS, STR_PERMISSION_DENIED); - return; - } - } - } // if (!peep_can_be_picked_up(peep)) { return; } - if (tool_set(w, widgetIndex, 7)) { - return; - } - w->picked_peep_old_x = peep->x; - - remove_peep_from_ride(peep); - invalidate_sprite_2((rct_sprite*)peep); - - sprite_move(0x8000, peep->y, peep->z, (rct_sprite*)peep); - peep_decrement_num_riders(peep); - peep->state = PEEP_STATE_PICKED; - peep->sub_state = 0; - peep_window_state_update(peep); + game_command_callback = game_command_callback_pickup_guest; + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_PICKUP_GUEST, 0, 0); break; case WIDX_RENAME: window_text_input_open(w, widgetIndex, STR_GUEST_RENAME_TITLE, STR_GUEST_RENAME_PROMPT, peep->name_string_idx, peep->id, 32); @@ -1215,52 +1214,14 @@ void window_guest_overview_tool_down(rct_window* w, int widgetIndex, int x, int return; int dest_x, dest_y; - rct_map_element *mapElement; + rct_map_element* mapElement; footpath_get_coordinates_from_pos(x, y + 16, &dest_x, &dest_y, NULL, &mapElement); - if (dest_x == (sint16)0x8000)return; - - // Set the coordinate of destination to be exactly - // in the middle of a tile. - dest_x += 16; - dest_y += 16; - // Set the tile coordinate to top left of tile - int tile_y = dest_y & 0xFFE0; - int tile_x = dest_x & 0xFFE0; - - int dest_z = mapElement->base_height * 8 + 16; - - if (!map_is_location_owned(tile_x, tile_y, dest_z)){ - window_error_open(STR_ERR_CANT_PLACE_PERSON_HERE, STR_NONE); + if (x == (sint16)0x8000) return; - } - - if (!map_can_construct_at(tile_x, tile_y, dest_z / 8, (dest_z / 8) + 1, 15)){ - if (gGameCommandErrorText != STR_RAISE_OR_LOWER_LAND_FIRST) { - if (gGameCommandErrorText != STR_FOOTPATH_IN_THE_WAY) { - window_error_open(STR_ERR_CANT_PLACE_PERSON_HERE, STR_NONE); - return; - } - } - } - rct_peep* peep = GET_PEEP(w->number); - sprite_move(dest_x, dest_y, dest_z, (rct_sprite*)peep); - invalidate_sprite_2((rct_sprite*)peep); - peep_decrement_num_riders(peep); - peep->state = 0; - peep_window_state_update(peep); - peep->action = 0xFF; - peep->special_sprite = 0; - peep->action_sprite_image_offset = 0; - peep->action_sprite_type = 0xFF; - peep->var_C4 = 0; - - peep->happiness_growth_rate = max(peep->happiness_growth_rate - 10, 0); - - sub_693B58(peep); - tool_cancel(); - gPickupPeepImage = UINT32_MAX; + game_command_callback = game_command_callback_pickup_guest; + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 2, mapElement->base_height, GAME_COMMAND_PICKUP_GUEST, dest_x, dest_y); } /** @@ -1272,25 +1233,7 @@ void window_guest_overview_tool_abort(rct_window *w, int widgetIndex) if (widgetIndex != WIDX_PICKUP) return; - rct_peep* peep = GET_PEEP(w->number); - if (peep->state != PEEP_STATE_PICKED) - return; - - sprite_move(w->picked_peep_old_x, peep->y, peep->z + 8, (rct_sprite*)peep); - invalidate_sprite_2((rct_sprite*)peep); - - if (peep->x != (sint16)0x8000){ - peep_decrement_num_riders(peep); - peep->state = 0; - peep_window_state_update(peep); - peep->action = 0xFF; - peep->special_sprite = 0; - peep->action_sprite_image_offset = 0; - peep->action_sprite_type = 0; - peep->var_C4 = 0; - } - - gPickupPeepImage = UINT32_MAX; + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 1, 0, GAME_COMMAND_PICKUP_GUEST, w->picked_peep_old_x, 0); } /** diff --git a/src/windows/staff.c b/src/windows/staff.c index 2658071afa..5b54d8ffc2 100644 --- a/src/windows/staff.c +++ b/src/windows/staff.c @@ -433,6 +433,25 @@ void window_staff_set_page(rct_window* w, int page) if (listen && w->viewport) w->viewport->flags |= VIEWPORT_FLAG_SOUND_ON; } +void game_command_callback_pickup_staff(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) +{ + switch(ecx){ + case 0:{ + int peepnum = eax; + rct_window* w = window_find_by_number(WC_PEEP, peepnum); + if (w) { + tool_set(w, WIDX_PICKUP, 7); + } + }break; + case 2: + if (ebx == 0) { + tool_cancel(); + gPickupPeepImage = UINT32_MAX; + } + break; + } +} + /** * * rct2: 0x006BDF55 @@ -454,19 +473,15 @@ void window_staff_overview_mouseup(rct_window *w, int widgetIndex) window_scroll_to_viewport(w); break; case WIDX_PICKUP: - if (tool_set(w, widgetIndex, 7)) { - return; - } - + { + // this is called in callback when hiring staff, setting nestlevel to 0 so that command is sent separately + int oldNestLevel = gGameCommandNestLevel; + gGameCommandNestLevel = 0; + game_command_callback = game_command_callback_pickup_staff; w->picked_peep_old_x = peep->x; - - remove_peep_from_ride(peep); - invalidate_sprite_2((rct_sprite*)peep); - - sprite_move( 0x8000, peep->y, peep->z, (rct_sprite*)peep); - peep_decrement_num_riders(peep); - peep->state = PEEP_STATE_PICKED; - peep_window_state_update(peep); + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 0, 0, GAME_COMMAND_PICKUP_STAFF, 0, 0); + gGameCommandNestLevel = oldNestLevel; + } break; case WIDX_FIRE: window_staff_fire_prompt_open(peep); @@ -1144,49 +1159,14 @@ void window_staff_overview_tool_down(rct_window* w, int widgetIndex, int x, int { if (widgetIndex == WIDX_PICKUP) { int dest_x, dest_y; - rct_map_element *mapElement; + rct_map_element* mapElement; footpath_get_coordinates_from_pos(x, y + 16, &dest_x, &dest_y, NULL, &mapElement); - if (dest_x == (sint16)0x8000)return; - - // Set the coordinate of destination to be exactly - // in the middle of a tile. - dest_x += 16; - dest_y += 16; - // Set the tile coordinate to top left of tile - int tile_y = dest_y & 0xFFE0; - int tile_x = dest_x & 0xFFE0; - - int dest_z = mapElement->base_height * 8 + 16; - - if (!map_is_location_owned(tile_x, tile_y, dest_z)){ - window_error_open(STR_ERR_CANT_PLACE_PERSON_HERE, STR_NONE); + if (x == (sint16)0x8000) return; - } - if (!map_can_construct_at(tile_x, tile_y, dest_z / 8, (dest_z / 8) + 1, 15)){ - if (gGameCommandErrorText != STR_RAISE_OR_LOWER_LAND_FIRST){ - if (gGameCommandErrorText != STR_FOOTPATH_IN_THE_WAY){ - window_error_open(STR_ERR_CANT_PLACE_PERSON_HERE, STR_NONE); - return; - } - } - } - - rct_peep* peep = GET_PEEP(w->number); - sprite_move(dest_x, dest_y, dest_z, (rct_sprite*)peep); - invalidate_sprite_2((rct_sprite*)peep); - peep_decrement_num_riders(peep); - peep->state = PEEP_STATE_FALLING; - peep_window_state_update(peep); - peep->action = 0xFF; - peep->special_sprite = 0; - peep->action_sprite_image_offset = 0; - peep->action_sprite_type = 0; - peep->var_C4 = 0; - - tool_cancel(); - gPickupPeepImage = UINT32_MAX; + game_command_callback = game_command_callback_pickup_staff; + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 2, mapElement->base_height, GAME_COMMAND_PICKUP_STAFF, dest_x, dest_y); } else if (widgetIndex == WIDX_PATROL){ int dest_x, dest_y; @@ -1205,24 +1185,7 @@ void window_staff_overview_tool_down(rct_window* w, int widgetIndex, int x, int void window_staff_overview_tool_abort(rct_window *w, int widgetIndex) { if (widgetIndex == WIDX_PICKUP) { - rct_peep* peep = GET_PEEP(w->number); - if (peep->state != PEEP_STATE_PICKED) return; - - sprite_move(w->picked_peep_old_x, peep->y, peep->z + 8, (rct_sprite*)peep); - invalidate_sprite_2((rct_sprite*)peep); - - if (peep->x != (sint16)0x8000){ - peep_decrement_num_riders(peep); - peep->state = PEEP_STATE_FALLING; - peep_window_state_update(peep); - peep->action = 0xFF; - peep->special_sprite = 0; - peep->action_sprite_image_offset = 0; - peep->action_sprite_type = 0; - peep->var_C4 = 0; - } - - gPickupPeepImage = UINT32_MAX; + game_do_command(w->number, GAME_COMMAND_FLAG_APPLY, 1, 0, GAME_COMMAND_PICKUP_STAFF, w->picked_peep_old_x, 0); } else if (widgetIndex == WIDX_PATROL){ hide_gridlines(); diff --git a/src/world/balloon.c b/src/world/balloon.c index f4c0cdc8a8..0cff7ed7cb 100644 --- a/src/world/balloon.c +++ b/src/world/balloon.c @@ -81,15 +81,12 @@ void balloon_update(rct_balloon *balloon) * * rct2: 0x006E88ED */ -void balloon_press(rct_balloon *balloon) +static void balloon_press(rct_balloon *balloon) { - if (network_get_mode() != NETWORK_MODE_NONE) { - return; - } if (balloon->popped == 1) return; - uint32 random = util_rand(); + uint32 random = scenario_rand(); if ((balloon->sprite_index & 7) || (random & 0xFFFF) < 0x2000) { balloon_pop(balloon); return; @@ -102,3 +99,20 @@ void balloon_press(rct_balloon *balloon) (rct_sprite*)balloon ); } + +void game_command_balloon_press(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + int balloon_num = *eax; + int flags = *ebx; + *ebx = 0; + if (!(flags & GAME_COMMAND_FLAG_APPLY)) { + return; + } + rct_sprite* sprite = get_sprite(balloon_num); + if (!sprite) { + return; + } + if (sprite->balloon.sprite_identifier == SPRITE_IDENTIFIER_MISC && sprite->balloon.misc_identifier == SPRITE_MISC_BALLOON) { + balloon_press(&sprite->balloon); + } +} diff --git a/src/world/sprite.h b/src/world/sprite.h index e7d453d5c5..cf411c2bdb 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -438,7 +438,7 @@ uint16 sprite_get_first_in_quadrant(int x, int y); /////////////////////////////////////////////////////////////// void create_balloon(int x, int y, int z, int colour, uint8 bl); void balloon_update(rct_balloon *balloon); -void balloon_press(rct_balloon *balloon); +void game_command_balloon_press(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); /////////////////////////////////////////////////////////////// // Duck