Ejemplo n.º 1
0
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 );
    }
}
Ejemplo n.º 2
0
void overmapbuffer::fix_mongroups(overmap &new_overmap)
{
    for( auto it = new_overmap.zg.begin(); it != new_overmap.zg.end(); ) {
        auto &mg = it->second;
        // spawn related code simply sets population to 0 when they have been
        // transformed into spawn points on a submap, the group can then be removed
        if( mg.population <= 0 ) {
            new_overmap.zg.erase( it++ );
            continue;
        }
        // Inside the bounds of the overmap?
        if( mg.posx >= 0 && mg.posy >= 0 && mg.posx < OMAPX * 2 && mg.posy < OMAPY * 2 ) {
            ++it;
            continue;
        }
        point smabs( mg.posx + new_overmap.pos().x * OMAPX * 2,
                     mg.posy + new_overmap.pos().y * OMAPY * 2 );
        point omp = sm_to_om_remain( smabs );
        if( !has( omp.x, omp.y ) ) {
            // Don't generate new overmaps, as this can be called from the
            // overmap-generating code.
            ++it;
            continue;
        }
        overmap &om = get( omp.x, omp.y );
        mg.posx = smabs.x;
        mg.posy = smabs.y;
        om.add_mon_group( mg );
        new_overmap.zg.erase( it++ );
    }
}
Ejemplo n.º 3
0
radio_tower_reference create_radio_tower_reference( overmap &om, radio_tower &t, const tripoint &center )
{
    // global submap coordinates, same as center is
    const point pos = point( t.x, t.y ) + overmapbuffer::om_to_sm_copy( om.pos() );
    const int strength = t.strength - rl_dist( tripoint( pos, 0 ), center );
    return radio_tower_reference{ &om, &t, pos, strength };
}