Skip to content

Commit

Permalink
Better OMT teleport handling
Browse files Browse the repository at this point in the history
Co-authored-by: PatrikLundell
  • Loading branch information
RenechCDDA committed May 19, 2024
1 parent 94ce60d commit 1093b60
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
43 changes: 33 additions & 10 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11118,8 +11118,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<coords::ms>( 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 );
Expand All @@ -11142,32 +11147,50 @@ 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<coords::sm>( om_dest ) - point( HALF_MAPSIZE, HALF_MAPSIZE );
const tripoint player_pos( u.pos().xy(), map_sm_pos.z() );
project_to<coords::sm>( 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
update_overmap_seen();
// 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!
tripoint_abs_ms org = project_to<coords::ms>( tele_from - point( HALF_MAPSIZE,
HALF_MAPSIZE ) ) + player_pos.raw();
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 );
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<coords::omt>( tele_from ) );
// Again, translate the reality bubble reference to a mapsquare one.
place_player_overmap( project_to<coords::ms>( 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<coords::ms>( om_dest ) + offset );
}

bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp )
Expand Down
1 change: 1 addition & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,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 );
Expand Down

0 comments on commit 1093b60

Please sign in to comment.