void Creature_tracker::remove_dead() { // Can't use game::all_monsters() as it would not contain *dead* monsters. for( auto iter = monsters_list.begin(); iter != monsters_list.end(); ) { const monster &critter = **iter; if( critter.is_dead() ) { remove_from_location_map( critter ); iter = monsters_list.erase( iter ); } else { ++iter; } } }
void Creature_tracker::swap_positions( monster &first, monster &second ) { const int first_mdex = mon_at( first.pos() ); const int second_mdex = mon_at( second.pos() ); remove_from_location_map( first ); remove_from_location_map( second ); bool ok = true; if( first_mdex == -1 || second_mdex == -1 || first_mdex == second_mdex ) { debugmsg( "Tried to swap monsters with invalid positions" ); ok = false; } tripoint temp = second.pos(); second.spawn( first.pos() ); first.spawn( temp ); if( ok ) { monsters_by_location[first.pos()] = first_mdex; monsters_by_location[second.pos()] = second_mdex; } else { // Try to avoid spamming error messages if something weird happens rebuild_cache(); } }
void Creature_tracker::remove( const monster &critter ) { const auto iter = std::find_if( monsters_list.begin(), monsters_list.end(), [&]( const std::shared_ptr<monster> &ptr ) { return ptr.get() == &critter; } ); if( iter == monsters_list.end() ) { debugmsg( "Tried to remove invalid monster %s", critter.name() ); return; } remove_from_location_map( critter ); monsters_list.erase( iter ); }
bool Creature_tracker::update_pos( const monster &critter, const tripoint &new_pos ) { const auto old_pos = critter.pos(); if( critter.is_dead() ) { // mon_at ignores dead critters anyway, changing their position in the // monsters_by_location map is useless. remove_from_location_map( critter ); return true; } const int critter_id = mon_at( old_pos ); const int new_critter_id = mon_at( new_pos ); if( new_critter_id >= 0 ) { auto &othermon = *monsters_list[new_critter_id]; if( othermon.is_hallucination() ) { othermon.die( nullptr ); } else { debugmsg( "update_zombie_pos: wanted to move %s to %d,%d,%d, but new location already has %s", critter.disp_name().c_str(), new_pos.x, new_pos.y, new_pos.z, othermon.disp_name().c_str() ); return false; } } if( critter_id >= 0 ) { if( &critter == monsters_list[critter_id] ) { monsters_by_location.erase( old_pos ); monsters_by_location[new_pos] = critter_id; return true; } else { const auto &othermon = *monsters_list[critter_id]; debugmsg( "update_zombie_pos: wanted to move %s from old location %d,%d,%d, but it had %s instead", critter.disp_name().c_str(), old_pos.x, old_pos.y, old_pos.z, othermon.disp_name().c_str() ); return false; } } else { // We're changing the x/y/z coordinates of a zombie that hasn't been added // to the game yet. add_zombie() will update monsters_by_location for us. debugmsg( "update_zombie_pos: no %s at %d,%d,%d (moving to %d,%d,%d)", critter.disp_name().c_str(), old_pos.x, old_pos.y, old_pos.z, new_pos.x, new_pos.y, new_pos.z ); // Rebuild cache in case the monster actually IS in the game, just bugged rebuild_cache(); return false; } return false; }
bool Creature_tracker::update_pos( const monster &critter, const tripoint &new_pos ) { if( critter.is_dead() ) { // find ignores dead critters anyway, changing their position in the // monsters_by_location map is useless. remove_from_location_map( critter ); return true; } if( const std::shared_ptr<monster> new_critter_ptr = find( new_pos ) ) { auto &othermon = *new_critter_ptr; if( othermon.is_hallucination() ) { othermon.die( nullptr ); } else { debugmsg( "update_zombie_pos: wanted to move %s to %d,%d,%d, but new location already has %s", critter.disp_name(), new_pos.x, new_pos.y, new_pos.z, othermon.disp_name() ); return false; } } const auto iter = std::find_if( monsters_list.begin(), monsters_list.end(), [&]( const std::shared_ptr<monster> &ptr ) { return ptr.get() == &critter; } ); if( iter != monsters_list.end() ) { monsters_by_location.erase( critter.pos() ); monsters_by_location[new_pos] = *iter; return true; } else { const tripoint &old_pos = critter.pos(); // We're changing the x/y/z coordinates of a zombie that hasn't been added // to the game yet. add_zombie() will update monsters_by_location for us. debugmsg( "update_zombie_pos: no %s at %d,%d,%d (moving to %d,%d,%d)", critter.disp_name(), old_pos.x, old_pos.y, old_pos.z, new_pos.x, new_pos.y, new_pos.z ); // Rebuild cache in case the monster actually IS in the game, just bugged rebuild_cache(); return false; } }
void Creature_tracker::remove( const int idx ) { if( idx < 0 || idx >= ( int )monsters_list.size() ) { debugmsg( "Tried to remove monster with invalid index %d. Monster num: %d", idx, monsters_list.size() ); return; } monster &m = *monsters_list[idx]; remove_from_location_map( m ); delete monsters_list[idx]; monsters_list.erase( monsters_list.begin() + idx ); // Fix indices in monsters_by_location for any zombies that were just moved down 1 place. for( auto &elem : monsters_by_location ) { if( elem.second > ( size_t )idx ) { --elem.second; } } }
bool Creature_tracker::update_pos(const monster &critter, const tripoint &new_pos) { const auto old_pos = critter.pos3(); if( critter.is_dead() ) { // mon_at ignores dead critters anyway, changing their position in the // monsters_by_location map is useless. remove_from_location_map( critter ); return true; } bool success = false; const int critter_id = mon_at( old_pos ); const int new_critter_id = mon_at( new_pos ); if( new_critter_id >= 0 ) { debugmsg("update_zombie_pos: new location %d,%d,%d already has zombie %d", new_pos.x, new_pos.y, new_pos.z, new_critter_id); } else if( critter_id >= 0 ) { if( &critter == monsters_list[critter_id] ) { monsters_by_location.erase( old_pos ); monsters_by_location[new_pos] = critter_id; success = true; } else { debugmsg("update_zombie_pos: old location %d,%d had zombie %d instead", old_pos.x, old_pos.y, critter_id); } } else { // We're changing the x/y/z coordinates of a zombie that hasn't been added // to the game yet. add_zombie() will update monsters_by_location for us. debugmsg("update_zombie_pos: no such zombie at %d,%d,%d (moving to %d,%d,%d)", old_pos.x, old_pos.y, old_pos.z, new_pos.x, new_pos.y, new_pos.z ); // Rebuild cache in case the monster actually IS in the game, just bugged rebuild_cache(); } return success; }