From 195441e4f1b3849fc87809ca4087d18cf1b3ace6 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:18:56 -0400 Subject: [PATCH 1/9] Player snaps back if teleport fails --- src/game.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/game.cpp b/src/game.cpp index 1ca52e5da2dbf..5b96337824276 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -11399,6 +11399,8 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_play m.rebuild_vehicle_level_caches(); m.access_cache( m.get_abs_sub().z() ).map_memory_cache_dec.reset(); m.access_cache( m.get_abs_sub().z() ).map_memory_cache_ter.reset(); + // Set this now, if game::place_player fails we'll need it to recover. + const tripoint_abs_sm tele_from = u.global_sm_location(); // offset because load_map expects the coordinates of the top left corner, but the // player will be centered in the middle of the map. const tripoint_abs_sm map_sm_pos = @@ -11413,6 +11415,18 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_play if( move_player ) { place_player( player_pos ); } + tripoint_abs_sm tele_to = u.global_sm_location(); + if( tele_from != tele_to || !move_player ) { + return; + } // else tele_from == tele_to !!! + // We've failed to teleport for some reason (probably monsters occupying destination squares). + // Let's try to recover gracefully. But also throw a warning, this is bad! + debugmsg( "Failed to place player at destination. If you see this outside of debug teleporting it is a bug." ); + bool z_level_shifted = tele_from.z() != tele_to.z(); + update_map( u, z_level_shifted ); + // This recursive call safely calls map::load_map() again after making sure everything has been unloaded properly. + // Basically, its only purpose it to reset the z-level to the z-level you teleported *from*. Otherwise, it's redundant after update_map + place_player_overmap( project_to( tele_from ) ); } bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp ) From 04d735206083c219b45adbe5c070d1e50895024f Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 19 May 2024 08:09:01 -0400 Subject: [PATCH 2/9] Better OMT teleport handling Co-authored-by: PatrikLundell --- src/game.cpp | 43 ++++++++++++++++++++++++++++++++----------- src/game.h | 1 + 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 5b96337824276..640f2ff93bfda 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -11377,8 +11377,13 @@ point game::place_player( const tripoint &dest_loc, bool quick ) return submap_shift; } -void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_player ) +void game::place_player_overmap( const tripoint_abs_ms &ms_dest, bool move_player ) { + if( ms_dest == project_to( u.global_sm_location() - point( HALF_MAPSIZE, + HALF_MAPSIZE ) ) + u.pos() ) { + return; // Already there + } + // if player is teleporting around, they don't bring their horse with them if( u.is_mounted() ) { u.remove_effect( effect_riding ); @@ -11401,11 +11406,10 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_play m.access_cache( m.get_abs_sub().z() ).map_memory_cache_ter.reset(); // Set this now, if game::place_player fails we'll need it to recover. const tripoint_abs_sm tele_from = u.global_sm_location(); - // offset because load_map expects the coordinates of the top left corner, but the - // player will be centered in the middle of the map. + // The subtraction is to get the reality bubble NW corner from the center position. const tripoint_abs_sm map_sm_pos = - project_to( om_dest ) - point( HALF_MAPSIZE, HALF_MAPSIZE ); - const tripoint player_pos( u.pos().xy(), map_sm_pos.z() ); + project_to( ms_dest ) - point( HALF_MAPSIZE, HALF_MAPSIZE ); + const tripoint_bub_ms player_pos( u.pos_bub().xy(), map_sm_pos.z() ); load_map( map_sm_pos ); load_npcs(); m.spawn_monsters( true ); // Static monsters @@ -11413,20 +11417,37 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_play // update weather now as it could be different on the new location weather.nextweather = calendar::turn; if( move_player ) { - place_player( player_pos ); + place_player( player_pos.raw() ); } - tripoint_abs_sm tele_to = u.global_sm_location(); + const tripoint_abs_sm tele_to = u.global_sm_location(); if( tele_from != tele_to || !move_player ) { return; } // else tele_from == tele_to !!! // We've failed to teleport for some reason (probably monsters occupying destination squares). // Let's try to recover gracefully. But also throw a warning, this is bad! - debugmsg( "Failed to place player at destination. If you see this outside of debug teleporting it is a bug." ); - bool z_level_shifted = tele_from.z() != tele_to.z(); - update_map( u, z_level_shifted ); + debugmsg( "Failed to place player at destination. If you see this outside of debug teleporting it is a bug." ); + update_map( u, ms_dest.z() != tele_from.z() ); // This recursive call safely calls map::load_map() again after making sure everything has been unloaded properly. // Basically, its only purpose it to reset the z-level to the z-level you teleported *from*. Otherwise, it's redundant after update_map - place_player_overmap( project_to( tele_from ) ); + // Again, translate the reality bubble reference to a mapsquare one. + place_player_overmap( project_to( tele_from - point( HALF_MAPSIZE, + HALF_MAPSIZE ) ) + player_pos.raw() ); +} + +void game::place_player_overmap( const tripoint_abs_omt &om_dest, bool move_player ) +{ + // Project the bubble reference to a submap reference. + tripoint offset = u.pos() - point( 5 * SEEX, 5 * SEEY ); + + // And then on to an overmap one. + if( abs( u.global_sm_location().x() ) % 2 == 1 ) { + offset.x += SEEX; + } + if( abs( u.global_sm_location().y() ) % 2 == 1 ) { + offset.y += SEEY; + } + + place_player_overmap( project_to( om_dest ) + offset, move_player ); } bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp ) diff --git a/src/game.h b/src/game.h index 56ea6185b4a94..8e8d63defeb6e 100644 --- a/src/game.h +++ b/src/game.h @@ -948,6 +948,7 @@ class game void insert_item( drop_locations &targets ); // Places the player at the specified point; hurts feet, lists items etc. point place_player( const tripoint &dest, bool quick = false ); + void place_player_overmap( const tripoint_abs_ms &ms_dest, bool move_player = true ); void place_player_overmap( const tripoint_abs_omt &om_dest, bool move_player = true ); void perhaps_add_random_npc( bool ignore_spawn_timers_and_rates ); static void display_om_pathfinding_progress( size_t open_set, size_t known_size ); From 2ae568e8518ceb416aac85b27a0d0a14717f9969 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:47:30 -0400 Subject: [PATCH 3/9] Adjust swimming test to properly use fixed setpos --- tests/water_movement_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index 25da7932211b5..af45a4809dd6c 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -144,7 +144,7 @@ TEST_CASE( "avatar_diving", "[diving]" ) // Put us back at 0. We shouldn't have to do this but other tests are // making assumptions about what z-level they're on. - g->vertical_shift( 0 ); + dummy.setpos( test_origin ); } static const efftype_id effect_winded( "winded" ); @@ -905,6 +905,7 @@ static std::map expected_results = { TEST_CASE( "check_swim_move_cost_and_distance_values", "[swimming][slow]" ) { + clear_avatar(); setup_test_lake(); avatar &dummy = get_avatar(); From 7d111a41404e50f62c2e7a5f29d8457e2fde1d21 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sat, 10 Aug 2024 10:37:11 -0400 Subject: [PATCH 4/9] Back to vertical shift? --- tests/water_movement_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index af45a4809dd6c..afcdb2adc9e8d 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -144,7 +144,7 @@ TEST_CASE( "avatar_diving", "[diving]" ) // Put us back at 0. We shouldn't have to do this but other tests are // making assumptions about what z-level they're on. - dummy.setpos( test_origin ); + g->vertical_shift( 0 ); } static const efftype_id effect_winded( "winded" ); From 661fd45131ce8117fe243e0defc659d0047d1ee5 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:29:27 -0400 Subject: [PATCH 5/9] ??? --- tests/water_movement_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index afcdb2adc9e8d..8da014094bc28 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -144,6 +144,7 @@ TEST_CASE( "avatar_diving", "[diving]" ) // Put us back at 0. We shouldn't have to do this but other tests are // making assumptions about what z-level they're on. + dummy.setpos( test_origin ); g->vertical_shift( 0 ); } From 50dd2cc5e185d68589d4a85a9cda78a07b116da6 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:17:11 -0400 Subject: [PATCH 6/9] ???????????????????????? --- tests/water_movement_test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index 8da014094bc28..ad0c85f3fa912 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -118,7 +118,7 @@ TEST_CASE( "avatar_diving", "[diving]" ) GIVEN( "avatar is underwater at z-2" ) { dummy.set_underwater( true ); - dummy.setpos( test_origin + tripoint( 0, 0, -2 ) ); + dummy.setpos( test_origin ); g->vertical_shift( -2 ); WHEN( "avatar dives down" ) { @@ -144,7 +144,6 @@ TEST_CASE( "avatar_diving", "[diving]" ) // Put us back at 0. We shouldn't have to do this but other tests are // making assumptions about what z-level they're on. - dummy.setpos( test_origin ); g->vertical_shift( 0 ); } From 5fe1076300ec1458a9235a89da3978df60f7fec0 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Thu, 15 Aug 2024 22:20:21 -0400 Subject: [PATCH 7/9] This better not pass --- tests/water_movement_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index ad0c85f3fa912..7408a64a8379c 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -261,6 +261,8 @@ struct swim_scenario { static int swimming_steps( avatar &swimmer ) { map &here = get_map(); + // This shouldn't work. + avatar_action::move( swimmer, here, tripoint_west ); const tripoint left = swimmer.pos(); const tripoint right = left + tripoint_east; int steps = 0; From d91ec5f1c3e6e8926e75c7ef42e5bb252caf4b7f Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:28:27 -0400 Subject: [PATCH 8/9] Maybe?! --- tests/water_movement_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index 7408a64a8379c..f069458c51bcc 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -274,10 +274,10 @@ static int swimming_steps( avatar &swimmer ) while( swimmer.get_stamina() > 0 && !swimmer.has_effect( effect_winded ) && steps < STOP_STEPS ) { if( steps % 2 == 0 ) { REQUIRE( swimmer.pos() == left ); - REQUIRE( avatar_action::move( swimmer, here, tripoint_east ) ); + REQUIRE( avatar_action::move( swimmer, here, swimmer.pos() + tripoint_east ) ); } else { REQUIRE( swimmer.pos() == right ); - REQUIRE( avatar_action::move( swimmer, here, tripoint_west ) ); + REQUIRE( avatar_action::move( swimmer, here, swimmer.pos() + tripoint_west ) ); } ++steps; REQUIRE( swimmer.get_moves() < last_moves ); From f2f86d59c681b0b5796b480c3c6375711ec2eae1 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:52:18 -0400 Subject: [PATCH 9/9] Yet more testing by telephone with github's CI --- tests/water_movement_test.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/water_movement_test.cpp b/tests/water_movement_test.cpp index f069458c51bcc..a8e04186b14e3 100644 --- a/tests/water_movement_test.cpp +++ b/tests/water_movement_test.cpp @@ -262,9 +262,13 @@ static int swimming_steps( avatar &swimmer ) { map &here = get_map(); // This shouldn't work. - avatar_action::move( swimmer, here, tripoint_west ); + CAPTURE( swimmer.pos() ); + avatar_action::move( swimmer, here, swimmer.pos() + tripoint_west ); + CAPTURE( swimmer.pos() ); const tripoint left = swimmer.pos(); const tripoint right = left + tripoint_east; + CAPTURE( left ); + CAPTURE( right ); int steps = 0; constexpr int STOP_STEPS = 9000; int last_moves = swimmer.get_speed(); @@ -274,10 +278,10 @@ static int swimming_steps( avatar &swimmer ) while( swimmer.get_stamina() > 0 && !swimmer.has_effect( effect_winded ) && steps < STOP_STEPS ) { if( steps % 2 == 0 ) { REQUIRE( swimmer.pos() == left ); - REQUIRE( avatar_action::move( swimmer, here, swimmer.pos() + tripoint_east ) ); + REQUIRE( avatar_action::move( swimmer, here, right ) ); } else { REQUIRE( swimmer.pos() == right ); - REQUIRE( avatar_action::move( swimmer, here, swimmer.pos() + tripoint_west ) ); + REQUIRE( avatar_action::move( swimmer, here, left ) ); } ++steps; REQUIRE( swimmer.get_moves() < last_moves );