|
50 | 50 | #include "wcwidth.h"
|
51 | 51 |
|
52 | 52 | class emit;
|
| 53 | +class proficiency; |
53 | 54 |
|
54 | 55 | namespace
|
55 | 56 | {
|
@@ -204,28 +205,10 @@ static void parse_vp_reqs( const JsonObject &obj, const vpart_id &id, const std:
|
204 | 205 | }
|
205 | 206 | }
|
206 | 207 |
|
207 |
| -static void parse_vp_control_reqs( const JsonObject &obj, const vpart_id &id, |
208 |
| - std::string_view key, |
209 |
| - vp_control_req &req ) |
| 208 | +void vp_control_req::deserialize( const JsonObject &jo ) |
210 | 209 | {
|
211 |
| - if( !obj.has_object( key ) ) { |
212 |
| - return; |
213 |
| - } |
214 |
| - JsonObject src = obj.get_object( key ); |
215 |
| - |
216 |
| - JsonArray sk = src.get_array( "skills" ); |
217 |
| - if( !sk.empty() ) { |
218 |
| - req.skills.clear(); |
219 |
| - for( JsonArray cur : sk ) { |
220 |
| - if( cur.size() != 2 ) { |
221 |
| - debugmsg( "vpart '%s' has requirement with invalid skill entry", id.str() ); |
222 |
| - continue; |
223 |
| - } |
224 |
| - req.skills.emplace( skill_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); |
225 |
| - } |
226 |
| - } |
227 |
| - |
228 |
| - optional( src, false, "proficiencies", req.proficiencies ); |
| 210 | + optional( jo, false, "skills", skills, weighted_string_id_reader<skill_id, int> { std::nullopt} ); |
| 211 | + optional( jo, false, "proficiencies", proficiencies, string_id_reader<proficiency> {} ); |
229 | 212 | }
|
230 | 213 |
|
231 | 214 | void vehicles::parts::load( const JsonObject &jo, const std::string &src )
|
@@ -327,8 +310,8 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
|
327 | 310 | if( jo.has_member( "control_requirements" ) ) {
|
328 | 311 | JsonObject reqs = jo.get_object( "control_requirements" );
|
329 | 312 |
|
330 |
| - parse_vp_control_reqs( reqs, id, "air", control_air ); |
331 |
| - parse_vp_control_reqs( reqs, id, "land", control_land ); |
| 313 | + optional( reqs, false, "air", control_air ); |
| 314 | + optional( reqs, false, "land", control_land ); |
332 | 315 | }
|
333 | 316 |
|
334 | 317 | optional( jo, was_loaded, "looks_like", looks_like, looks_like );
|
@@ -363,77 +346,116 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
|
363 | 346 | damage_reduction = load_damage_map( dred );
|
364 | 347 | }
|
365 | 348 |
|
| 349 | + // TODO?: move this into an object? |
366 | 350 | if( has_flag( "ENGINE" ) ) {
|
367 | 351 | if( !engine_info ) {
|
368 | 352 | engine_info.emplace();
|
369 | 353 | }
|
370 |
| - assign( jo, "backfire_threshold", engine_info->backfire_threshold, strict ); |
371 |
| - assign( jo, "backfire_freq", engine_info->backfire_freq, strict ); |
372 |
| - assign( jo, "noise_factor", engine_info->noise_factor, strict ); |
373 |
| - assign( jo, "damaged_power_factor", engine_info->damaged_power_factor, strict ); |
374 |
| - assign( jo, "m2c", engine_info->m2c, strict ); |
375 |
| - assign( jo, "muscle_power_factor", engine_info->muscle_power_factor, strict ); |
376 |
| - assign( jo, "exclusions", engine_info->exclusions, strict ); |
377 |
| - assign( jo, "fuel_options", engine_info->fuel_opts, strict ); |
| 354 | + engine_info->deserialize( jo ); |
378 | 355 | }
|
379 | 356 |
|
380 | 357 | if( has_flag( "WHEEL" ) ) {
|
381 | 358 | if( !wheel_info ) {
|
382 | 359 | wheel_info.emplace();
|
383 | 360 | }
|
384 |
| - |
385 |
| - assign( jo, "rolling_resistance", wheel_info->rolling_resistance, strict ); |
386 |
| - assign( jo, "contact_area", wheel_info->contact_area, strict ); |
387 |
| - assign( jo, "wheel_offroad_rating", wheel_info->offroad_rating, strict ); |
388 |
| - if( const std::optional<JsonValue> jo_termod = jo.get_member_opt( "wheel_terrain_modifiers" ) ) { |
389 |
| - wheel_info->terrain_modifiers.clear(); |
390 |
| - for( const JsonMember jo_mod : static_cast<JsonObject>( *jo_termod ) ) { |
391 |
| - const JsonArray jo_mod_values = jo_mod.get_array(); |
392 |
| - veh_ter_mod mod { jo_mod.name(), jo_mod_values.get_int( 0 ), jo_mod_values.get_int( 1 ) }; |
393 |
| - wheel_info->terrain_modifiers.emplace_back( std::move( mod ) ); |
394 |
| - } |
395 |
| - } |
| 361 | + wheel_info->deserialize( jo ); |
396 | 362 | }
|
397 | 363 |
|
398 | 364 | if( has_flag( "ROTOR" ) ) {
|
399 | 365 | if( !rotor_info ) {
|
400 | 366 | rotor_info.emplace();
|
401 | 367 | }
|
402 |
| - assign( jo, "rotor_diameter", rotor_info->rotor_diameter, strict ); |
| 368 | + rotor_info->deserialize( jo ); |
403 | 369 | }
|
404 | 370 |
|
405 | 371 | if( has_flag( "WORKBENCH" ) ) {
|
406 |
| - if( !workbench_info ) { |
407 |
| - workbench_info.emplace(); |
408 |
| - } |
409 |
| - |
410 |
| - JsonObject wb_jo = jo.get_object( "workbench" ); |
411 |
| - assign( wb_jo, "multiplier", workbench_info->multiplier, strict ); |
412 |
| - assign( wb_jo, "mass", workbench_info->allowed_mass, strict ); |
413 |
| - assign( wb_jo, "volume", workbench_info->allowed_volume, strict ); |
| 372 | + mandatory( jo, was_loaded, "workbench", workbench_info ); |
414 | 373 | }
|
415 | 374 |
|
416 | 375 | if( has_flag( "VEH_TOOLS" ) ) {
|
417 | 376 | if( !toolkit_info ) {
|
418 | 377 | toolkit_info.emplace();
|
419 | 378 | }
|
420 |
| - assign( jo, "allowed_tools", toolkit_info->allowed_types, strict ); |
| 379 | + toolkit_info->deserialize( jo ); |
421 | 380 | }
|
422 | 381 |
|
423 | 382 | if( has_flag( "TRANSFORM_TERRAIN" ) || has_flag( "CRASH_TERRAIN_AROUND" ) ) {
|
424 | 383 | if( !transform_terrain_info ) {
|
425 | 384 | transform_terrain_info.emplace();
|
426 | 385 | }
|
427 |
| - JsonObject jttd = jo.get_object( "transform_terrain" ); |
428 |
| - vpslot_terrain_transform &vtt = *transform_terrain_info; |
429 |
| - optional( jttd, was_loaded, "pre_flags", vtt.pre_flags, {} ); |
430 |
| - optional( jttd, was_loaded, "post_terrain", vtt.post_terrain ); |
431 |
| - optional( jttd, was_loaded, "post_furniture", vtt.post_furniture ); |
432 |
| - if( jttd.has_string( "post_field" ) ) { |
433 |
| - mandatory( jttd, was_loaded, "post_field", vtt.post_field ); |
434 |
| - mandatory( jttd, was_loaded, "post_field_intensity", vtt.post_field_intensity ); |
435 |
| - mandatory( jttd, was_loaded, "post_field_age", vtt.post_field_age ); |
436 |
| - } |
| 386 | + mandatory( jo, was_loaded, "transform_terrain", transform_terrain_info ); |
| 387 | + } |
| 388 | +} |
| 389 | + |
| 390 | +void vpslot_engine::deserialize( const JsonObject &jo ) |
| 391 | +{ |
| 392 | + optional( jo, was_loaded, "backfire_threshold", backfire_threshold, 0.f ); |
| 393 | + optional( jo, was_loaded, "backfire_freq", backfire_freq, 1 ); |
| 394 | + optional( jo, was_loaded, "noise_factor", noise_factor, 0 ); |
| 395 | + optional( jo, was_loaded, "damaged_power_factor", damaged_power_factor, 0.f ); |
| 396 | + optional( jo, was_loaded, "m2c", m2c, 100 ); |
| 397 | + optional( jo, was_loaded, "muscle_power_factor", muscle_power_factor, 0 ); |
| 398 | + optional( jo, was_loaded, "exclusions", exclusions, string_reader{} ); |
| 399 | + optional( jo, was_loaded, "fuel_options", fuel_opts, string_id_reader<itype> {} ); |
| 400 | + |
| 401 | + was_loaded = true; |
| 402 | +} |
| 403 | + |
| 404 | +void veh_ter_mod::deserialize( const JsonValue &jv ) |
| 405 | +{ |
| 406 | + if( !jv.is_member() ) { |
| 407 | + jv.throw_error( "Invalid format" ); |
| 408 | + } |
| 409 | + |
| 410 | + const JsonMember &jm = dynamic_cast<const JsonMember &>( jv ); |
| 411 | + JsonArray ja = jm.get_array(); |
| 412 | + |
| 413 | + terrain_flag = jm.name(); |
| 414 | + move_override = ja.get_int( 0 ); |
| 415 | + move_penalty = ja.get_int( 1 ); |
| 416 | +} |
| 417 | + |
| 418 | +void vpslot_wheel::deserialize( const JsonObject &jo ) |
| 419 | +{ |
| 420 | + optional( jo, was_loaded, "rolling_resistance", rolling_resistance, 1.f ); |
| 421 | + optional( jo, was_loaded, "contact_area", contact_area, 1 ); |
| 422 | + optional( jo, was_loaded, "wheel_offroad_rating", offroad_rating, 0.5f ); |
| 423 | + optional( jo, was_loaded, "wheel_terrain_modifiers", terrain_modifiers, |
| 424 | + json_read_reader<veh_ter_mod> {} ); |
| 425 | + |
| 426 | + was_loaded = true; |
| 427 | +} |
| 428 | + |
| 429 | +void vpslot_rotor::deserialize( const JsonObject &jo ) |
| 430 | +{ |
| 431 | + optional( jo, was_loaded, "rotor_diameter", rotor_diameter, 1 ); |
| 432 | + |
| 433 | + was_loaded = true; |
| 434 | +} |
| 435 | + |
| 436 | +void vpslot_workbench::deserialize( const JsonObject &jo ) |
| 437 | +{ |
| 438 | + optional( jo, false, "multiplier", multiplier, 1.f ); |
| 439 | + optional( jo, false, "mass", allowed_mass, 0_gram ); |
| 440 | + optional( jo, false, "volume", allowed_volume, 0_ml ); |
| 441 | +} |
| 442 | + |
| 443 | +void vpslot_toolkit::deserialize( const JsonObject &jo ) |
| 444 | +{ |
| 445 | + optional( jo, was_loaded, "allowed_tools", allowed_types, string_id_reader<itype> {} ); |
| 446 | + |
| 447 | + was_loaded = true; |
| 448 | +} |
| 449 | + |
| 450 | +void vpslot_terrain_transform::deserialize( const JsonObject &jo ) |
| 451 | +{ |
| 452 | + optional( jo, false, "pre_flags", pre_flags, {} ); |
| 453 | + optional( jo, false, "post_terrain", post_terrain ); |
| 454 | + optional( jo, false, "post_furniture", post_furniture ); |
| 455 | + if( jo.has_string( "post_field" ) ) { |
| 456 | + mandatory( jo, false, "post_field", post_field ); |
| 457 | + mandatory( jo, false, "post_field_intensity", post_field_intensity ); |
| 458 | + mandatory( jo, false, "post_field_age", post_field_age ); |
437 | 459 | }
|
438 | 460 | }
|
439 | 461 |
|
|
0 commit comments