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 ); }
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 ); }
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 ); }
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 ) ); }