void mtype::add_special_attack( JsonArray inner, const std::string & )
{
    MonsterGenerator &gen = MonsterGenerator::generator();
    const std::string name = inner.get_string( 0 );
    const auto iter = gen.attack_map.find( name );
    if( iter == gen.attack_map.end() ) {
        inner.throw_error( "Invalid special_attacks" );
    }

    if( special_attacks.count( name ) > 0 ) {
        special_attacks.erase( name );
        const auto iter = std::find( special_attacks_names.begin(), special_attacks_names.end(), name );
        if( iter != special_attacks_names.end() ) {
            special_attacks_names.erase( iter );
        }
        if( test_mode ) {
            debugmsg( "%s specifies more than one attack of (sub)type %s, ignoring all but the last",
                      id.c_str(), name.c_str() );
        }
    }
    auto new_attack = mtype_special_attack( iter->second );
    new_attack.actor->cooldown = inner.get_int( 1 );
    special_attacks.emplace( name, new_attack );
    special_attacks_names.push_back( name );
}
예제 #2
0
void MonsterGenerator::load_special_attacks(mtype *m, JsonObject &jo, std::string member) {
    m->special_attacks.clear(); // make sure we're running with everything cleared

    if( !jo.has_array( member ) ) {
        return;
    }

    JsonArray outer = jo.get_array(member);
    while( outer.has_more() ) {
        if( outer.test_array() ) {
            JsonArray inner = outer.next_array();
            const auto &aname = inner.get_string(0);
            if ( attack_map.find(aname) != attack_map.end() ) {
                auto new_entry = mtype_special_attack(
                    attack_map[aname], inner.get_int(1) );
                m->special_attacks[aname] = new_entry;

                m->special_attacks_names.push_back(aname);
            } else {
                inner.throw_error("Invalid special_attacks");
            }
        } else if( outer.test_object() ) {
            set_attack_from_object(
                outer.next_object(), m->special_attacks, m->special_attacks_names );
        } else {
            outer.throw_error( "array element is neither array nor object." );
        }
    }
}
mtype_special_attack MonsterGenerator::create_actor( JsonObject obj, const std::string &src ) const
{
    // Legacy support: tolerate attack types being specified as the type
    const std::string type = obj.get_string( "type", "monster_attack" );
    const std::string attack_type = obj.get_string( "attack_type", type );

    if( type != "monster_attack" && attack_type != type ) {
        obj.throw_error( "Specifying \"attack_type\" is only allowed when \"type\" is \"monster_attack\" or not specified",
                         "type" );
    }

    mattack_actor *new_attack = nullptr;
    if( attack_type == "monster_attack" ) {
        const std::string id = obj.get_string( "id" );
        const auto &iter = attack_map.find( id );
        if( iter == attack_map.end() ) {
            obj.throw_error( "Monster attacks must specify type and/or id", "type" );
        }

        new_attack = iter->second->clone();
    } else if( attack_type == "leap" ) {
        new_attack = new leap_actor();
    } else if( attack_type == "melee" ) {
        new_attack = new melee_actor();
    } else if( attack_type == "bite" ) {
        new_attack = new bite_actor();
    } else if( attack_type == "gun" ) {
        new_attack = new gun_actor();
    } else {
        obj.throw_error( "unknown monster attack", "attack_type" );
    }

    new_attack->load( obj, src );
    return mtype_special_attack( new_attack );
}
예제 #4
0
void mtype::add_special_attack( JsonArray inner )
{
    MonsterGenerator &gen = MonsterGenerator::generator();
    const std::string name = inner.get_string( 0 );
    const auto iter = gen.attack_map.find( name );
    if( iter == gen.attack_map.end() ) {
        inner.throw_error( "Invalid special_attacks" );
    }
    special_attacks[name] = mtype_special_attack( iter->second, inner.get_int( 1 ) );
    special_attacks_names.push_back( name );
}
예제 #5
0
mtype_special_attack load_actor( JsonObject obj, int cooldown )
{
    std::unique_ptr<mattack_actor_type> actor( new mattack_actor_type() );
    actor->load( obj );
    return mtype_special_attack( actor.release(), cooldown );
}
void MonsterGenerator::add_attack( mattack_actor *ptr )
{
    add_attack( mtype_special_attack( ptr ) );
}
void MonsterGenerator::add_hardcoded_attack( const std::string &type, const mon_action_attack f )
{
    add_attack( mtype_special_attack( type, f ) );
}