const mtype& string_id<mtype>::obj() const
{
    auto &factory = *MonsterGenerator::generator().mon_templates;

    // first do the look-up as it is most likely to succeed
    if( factory.is_valid( *this ) ) {
        return factory.obj( *this );
    }

    // second most likely are outdated ids from old saves, this compares against strings, not
    // mtype_ids because the old ids are not valid ids at all.
    if( str() == "mon_zombie_fast" ) {
        return mon_zombie_dog.obj();
    }
    if( str() == "mon_fungaloid_dormant" ) {
        return mon_fungaloid.obj();
    }

    // this is most unlikely and therefor checked last.
    debugmsg( "Could not find monster with type %s", c_str() );
    return factory.obj( mtype_id::NULL_ID );
}
bool MonsterGroupManager::monster_is_blacklisted( const mtype_id &m )
{
    if( monster_whitelist.count( m.str() ) > 0 ) {
        return false;
    }
    const mtype &mt = m.obj();
    for( const auto &elem : monster_categories_whitelist ) {
        if( mt.categories.count( elem ) > 0 ) {
            return false;
        }
    }
    for( const auto &elem : monster_categories_blacklist ) {
        if( mt.categories.count( elem ) > 0 ) {
            return true;
        }
    }
    if( monster_blacklist.count( m.str() ) > 0 ) {
        return true;
    }
    // Return true if the whitelist mode is exclusive and either whitelist is populated.
    return monster_whitelist_is_exclusive &&
           ( !monster_whitelist.empty() || !monster_categories_whitelist.empty() );
}
bool MonsterGroupManager::monster_is_blacklisted(const mtype_id& m)
{
    if(monster_whitelist.count(m.str()) > 0) {
        return false;
    }
    const mtype& mt = m.obj();
    for( const auto &elem : monster_categories_whitelist ) {
        if( mt.categories.count( elem ) > 0 ) {
            return false;
        }
    }
    for( const auto &elem : monster_categories_blacklist ) {
        if( mt.categories.count( elem ) > 0 ) {
            return true;
        }
    }
    if(monster_blacklist.count(m.str()) > 0) {
        return true;
    }
    // Empty whitelist: default to enable all,
    // Non-empty whitelist: default to disable all.
    return !(monster_whitelist.empty() && monster_categories_whitelist.empty());
}