From 5a05025fcb79d5bfd2eddb49d6a3c63d05c2580e Mon Sep 17 00:00:00 2001 From: BevapDin Date: Fri, 3 Jan 2020 23:08:38 +0100 Subject: [PATCH] Fix mapgen code accessing the main game map. Access the local map instance instead. Also use `random_point` instead of manual logic. --- src/map.cpp | 4 +++- src/map_extras.cpp | 34 +++++++++++++--------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 0fc4fe6f20b3c..b89d8fe45a970 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -7237,7 +7237,9 @@ void map::spawn_monsters_submap( const tripoint &gp, bool ignore_sight ) } const auto valid_location = [&]( const tripoint & p ) { - return g->is_empty( p ) && tmp.can_move_to( p ); + // Checking for creatures via g is only meaningful if this is the main game map. + // If it's some local map instance, the coordinates will most likely not even match. + return ( !g || &g->m != this || g->critter_at( p ) ) && tmp.can_move_to( p ); }; const auto place_it = [&]( const tripoint & p ) { diff --git a/src/map_extras.cpp b/src/map_extras.cpp index 38e9ea12278c2..e4a7ce5854eeb 100644 --- a/src/map_extras.cpp +++ b/src/map_extras.cpp @@ -665,15 +665,14 @@ static void mx_marloss_pilgrimage( map &m, const tripoint &abs_sub ) const tripoint leader_pos( rng( 4, 19 ), rng( 4, 19 ), abs_sub.z ); const int max_followers = rng( 3, 12 ); const int rad = 3; - tripoint_range spawnzone = m.points_in_radius( leader_pos, rad ); + const tripoint_range spawnzone = m.points_in_radius( leader_pos, rad ); m.place_npc( leader_pos.xy(), string_id( "marloss_voice" ) ); for( int spawned = 0 ; spawned <= max_followers ; spawned++ ) { - tripoint where = random_entry( spawnzone ); - /// @todo wrong: this access the main game map, not m. Also accesses creatures currently loaded. - if( g->is_empty( where ) ) { - one_in( 2 ) ? m.add_spawn( mon_marloss_zealot_f, 1, where ) : - m.add_spawn( mon_marloss_zealot_m, 1, where ); + if( const cata::optional where_ = random_point( spawnzone, [&]( const tripoint & p ) { + return m.passable( p ); + } ) ) { + m.add_spawn( one_in( 2 ) ? mon_marloss_zealot_f : mon_marloss_zealot_m, 1, *where_ ); } } } @@ -2629,27 +2628,21 @@ static void mx_looters( map &m, const tripoint &abs_sub ) { const tripoint center( rng( 5, SEEX * 2 - 5 ), rng( 5, SEEY * 2 - 5 ), abs_sub.z ); //25% chance to spawn a corpse with some blood around it - /// @todo wrong: this access the main game map, not m. Also accesses creatures currently loaded. - if( one_in( 4 ) && g->is_empty( center ) ) { - const auto &loc = m.points_in_radius( center, 1 ); + if( one_in( 4 ) && m.passable( center ) ) { m.add_corpse( center ); for( int i = 0; i < rng( 1, 3 ); i++ ) { - const tripoint where = random_entry( loc ); - m.add_field( where, fd_blood, rng( 1, 3 ) ); + m.add_field( random_entry( m.points_in_radius( center, 1 ) ), fd_blood, rng( 1, 3 ) ); } } //Spawn up to 5 hostile bandits with equal chance to be ranged or melee type const int num_looters = rng( 1, 5 ); for( int i = 0; i < num_looters; i++ ) { - const tripoint pos = random_entry( m.points_in_radius( center, rng( 1, 4 ) ) ); - /// @todo wrong: this access the main game map, not m. Also accesses creatures currently loaded. - if( g->is_empty( pos ) ) { - if( one_in( 2 ) ) { - m.place_npc( pos.xy(), string_id( "bandit" ) ); - } else { - m.place_npc( pos.xy(), string_id( "thug" ) ); - } + if( const cata::optional pos_ = random_point( m.points_in_radius( center, rng( 1, + 4 ) ), [&]( const tripoint & p ) { + return m.passable( p ); + } ) ) { + m.place_npc( pos_->xy(), string_id( one_in( 2 ) ? "thug" : "bandit" ) ); } } } @@ -2661,8 +2654,7 @@ static void mx_corpses( map &m, const tripoint &abs_sub ) //Spawn up to 5 human corpses in random places for( int i = 0; i < num_corpses; i++ ) { const tripoint corpse_location = { rng( 1, SEEX * 2 - 1 ), rng( 1, SEEY * 2 - 1 ), abs_sub.z }; - /// @todo wrong: this access the main game map, not m. Also accesses creatures currently loaded. - if( g->is_empty( corpse_location ) ) { + if( m.passable( corpse_location ) ) { m.add_field( corpse_location, fd_blood, rng( 1, 3 ) ); m.put_items_from_loc( "everyday_corpse", corpse_location ); //50% chance to spawn blood in every tile around every corpse in 1-tile radius