void overmapbuffer::fix_npcs( overmap &new_overmap ) { // First step: move all npcs that are located outside of the given overmap // into a separate container. After that loop, new_overmap.npcs is no // accessed anymore! decltype( overmap::npcs ) to_relocate; for( auto it = new_overmap.npcs.begin(); it != new_overmap.npcs.end(); ) { npc &np = **it; const tripoint npc_omt_pos = np.global_omt_location(); const point npc_om_pos = omt_to_om_copy( npc_omt_pos.x, npc_omt_pos.y ); const point &loc = new_overmap.pos(); if( npc_om_pos == loc ) { // Nothing to do ++it; continue; } to_relocate.push_back( *it ); it = new_overmap.npcs.erase( it ); } // Second step: put them back where they belong. This step involves loading // new overmaps (via `get`), which does in turn call this function for the // newly loaded overmaps. This in turn may move NPCs from the second overmap // back into the first overmap. This messes up the iteration of it. The // iteration is therefore done in a separate step above (which does *not* // involve loading new overmaps). for( auto &ptr : to_relocate ) { npc &np = *ptr; const tripoint npc_omt_pos = np.global_omt_location(); const point npc_om_pos = omt_to_om_copy( npc_omt_pos.x, npc_omt_pos.y ); const point &loc = new_overmap.pos(); if( !has( npc_om_pos.x, npc_om_pos.y ) ) { // This can't really happen without save editing // We have no sane option here, just place the NPC on the edge debugmsg( "NPC %s is out of bounds, on non-generated overmap %d,%d", np.name.c_str(), loc.x, loc.y ); point npc_sm = om_to_sm_copy( npc_om_pos ); point min = om_to_sm_copy( loc ); point max = om_to_sm_copy( loc + point( 1, 1 ) ) - point( 1, 1 ); npc_sm.x = clamp( npc_sm.x, min.x, max.x ); npc_sm.y = clamp( npc_sm.y, min.y, max.y ); np.spawn_at_sm( npc_sm.x, npc_sm.y, np.posz() ); new_overmap.npcs.push_back( ptr ); continue; } // Simplest case: just move the pointer get( npc_om_pos.x, npc_om_pos.y ).insert_npc( ptr ); } }
void overmapbuffer::insert_npc( const std::shared_ptr<npc> who ) { assert( who ); const tripoint npc_omt_pos = who->global_omt_location(); const point npc_om_pos = omt_to_om_copy( npc_omt_pos.x, npc_omt_pos.y ); get( npc_om_pos.x, npc_om_pos.y ).insert_npc( who ); }
overmap &overmapbuffer::get_om_global(const point& p) { const point om_pos = omt_to_om_copy(p); return get(om_pos.x, om_pos.y); }
const overmap *overmapbuffer::get_existing_om_global(const point& p) const { const point om_pos = omt_to_om_copy(p); return get_existing(om_pos.x, om_pos.y); }