12
12
#include < unordered_set>
13
13
14
14
#include " ammo.h"
15
- #include " assign.h"
16
15
#include " cata_assert.h"
17
16
#include " catacharset.h"
18
17
#include " character.h"
@@ -240,10 +239,8 @@ void vpart_info::handle_inheritance( const vpart_info ©_from,
240
239
}
241
240
}
242
241
243
- void vpart_info::load ( const JsonObject &jo, const std::string & src )
242
+ void vpart_info::load ( const JsonObject &jo, const std::string_view src )
244
243
{
245
- const bool strict = src == " dda" ;
246
-
247
244
optional ( jo, was_loaded, " name" , name_ );
248
245
optional ( jo, was_loaded, " item" , base_item );
249
246
optional ( jo, was_loaded, " remove_as" , removed_item );
@@ -267,12 +264,8 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
267
264
optional ( jo, was_loaded, " color" , color, nc_color_reader{}, c_light_gray );
268
265
optional ( jo, was_loaded, " broken_color" , color_broken, nc_color_reader{}, c_light_gray );
269
266
optional ( jo, was_loaded, " comfort" , comfort, 0 );
270
- int legacy_floor_bedding_warmth = units::to_legacy_bodypart_temp_delta ( floor_bedding_warmth );
271
- assign ( jo, " floor_bedding_warmth" , legacy_floor_bedding_warmth, strict );
272
- floor_bedding_warmth = units::from_legacy_bodypart_temp_delta ( legacy_floor_bedding_warmth );
273
- int legacy_bonus_fire_warmth_feet = units::to_legacy_bodypart_temp_delta ( bonus_fire_warmth_feet );
274
- assign ( jo, " bonus_fire_warmth_feet" , legacy_bonus_fire_warmth_feet, strict );
275
- bonus_fire_warmth_feet = units::from_legacy_bodypart_temp_delta ( legacy_bonus_fire_warmth_feet );
267
+ optional ( jo, was_loaded, " floor_bedding_warmth" , floor_bedding_warmth, 0_C_delta );
268
+ optional ( jo, was_loaded, " bonus_fire_warmth_feet" , bonus_fire_warmth_feet, 0 .6_C_delta );
276
269
277
270
int enchant_num = 0 ;
278
271
for ( JsonValue jv : jo.get_array ( " enchantments" ) ) {
@@ -1297,116 +1290,95 @@ static std::pair<std::string, std::string> get_vpart_str_variant( const std::str
1297
1290
: std::make_pair ( vpid.substr ( 0 , loc ), vpid.substr ( loc + 1 ) );
1298
1291
}
1299
1292
1300
- void vehicle_prototype::load ( const JsonObject &jo, std::string_view )
1293
+ struct veh_proto_part_def_reader : generic_typed_reader<veh_proto_part_def_reader> {
1294
+ point_rel_ms pos;
1295
+
1296
+ explicit veh_proto_part_def_reader ( const point_rel_ms &p ) : pos( p ) {}
1297
+
1298
+ vehicle_prototype::part_def get_next ( const JsonValue &jv ) const {
1299
+ vehicle_prototype::part_def ret;
1300
+ if ( jv.test_string () ) {
1301
+ const auto [id, variant] = get_vpart_str_variant ( jv.get_string () );
1302
+ ret.part = vpart_id ( id );
1303
+ ret.variant = variant;
1304
+ ret.pos = pos;
1305
+ return ret;
1306
+ }
1307
+ JsonObject jo = jv.get_object ();
1308
+ const auto [id, variant] = get_vpart_str_variant ( jo.get_string ( " part" ) );
1309
+ ret.part = vpart_id ( id );
1310
+ ret.variant = variant;
1311
+ ret.pos = pos;
1312
+
1313
+ optional ( jo, false , " ammo" , ret.with_ammo , numeric_bound_reader{0 , 100 }, 0 );
1314
+ optional ( jo, false , " ammo_types" , ret.ammo_types , string_id_reader<itype> {} );
1315
+ optional ( jo, false , " ammo_qty" , ret.ammo_qty , { -1 , -1 } );
1316
+ optional ( jo, false , " fuel" , ret.fuel , itype_id::NULL_ID () );
1317
+ optional ( jo, false , " tools" , ret.tools , string_id_reader<itype> {} );
1318
+ return ret;
1319
+ }
1320
+
1321
+ };
1322
+
1323
+ struct veh_spawn_item_reader : generic_typed_reader<veh_spawn_item_reader> {
1324
+ std::pair<itype_id, std::string> get_next ( const JsonValue &jv ) const {
1325
+ if ( jv.test_string () ) {
1326
+ return std::make_pair ( itype_id ( jv.get_string () ), " " );
1327
+ }
1328
+ JsonObject jo = jv.get_object ();
1329
+ std::pair<itype_id, std::string> ret;
1330
+ mandatory ( jo, false , " id" , ret.first );
1331
+ optional ( jo, false , " variant" , ret.second );
1332
+ return ret;
1333
+ }
1334
+ };
1335
+
1336
+ void vehicle_item_spawn::deserialize ( const JsonObject &jo )
1301
1337
{
1302
- vgroups[ vgroup_id ( id. str () )]. add_vehicle ( id, 100 );
1303
- optional ( jo, was_loaded , " name " , name );
1338
+ mandatory ( jo, false , " x " , pos. x () );
1339
+ mandatory ( jo, false , " y " , pos. y () );
1304
1340
1305
- const auto add_part_obj = [&]( const JsonObject & part, point_rel_ms pos ) {
1306
- const auto [id, variant] = get_vpart_str_variant ( part.get_string ( " part" ) );
1307
- part_def pt;
1308
- pt.part = vpart_id ( id );
1309
- pt.variant = variant;
1310
- pt.pos = pos;
1341
+ mandatory ( jo, false , " chance" , chance, numeric_bound_reader{ 0 , 100 } );
1311
1342
1312
- assign ( part, " ammo" , pt.with_ammo , true , 0 , 100 );
1313
- assign ( part, " ammo_types" , pt.ammo_types , true );
1314
- assign ( part, " ammo_qty" , pt.ammo_qty , true , 0 );
1315
- assign ( part, " fuel" , pt.fuel , true );
1316
- assign ( part, " tools" , pt.tools , true );
1343
+ // constrain both with_magazine and with_ammo to [0-100]
1344
+ optional ( jo, false , " magazine" , with_magazine, numeric_bound_reader{ 0 , 100 }, 0 );
1345
+ optional ( jo, false , " ammo" , with_ammo, numeric_bound_reader{ 0 , 100 }, 0 );
1317
1346
1318
- parts.emplace_back ( pt );
1319
- };
1347
+ optional ( jo, false , " items" , item_ids, veh_spawn_item_reader{} );
1348
+ optional ( jo, false , " item_groups" , item_groups, string_id_reader<Item_spawn_data> {} );
1349
+ }
1320
1350
1321
- const auto add_part_string = [&]( const std::string & part, point_rel_ms pos ) {
1322
- const auto [id, variant] = get_vpart_str_variant ( part );
1323
- part_def pt;
1324
- pt.part = vpart_id ( id );
1325
- pt.variant = variant;
1326
- pt.pos = pos;
1327
- parts.emplace_back ( pt );
1328
- };
1351
+ void vehicle_prototype::zone_def::deserialize ( const JsonObject &jo )
1352
+ {
1353
+ mandatory ( jo, false , " type" , zone_type );
1354
+ mandatory ( jo, false , " x" , pt.x () );
1355
+ mandatory ( jo, false , " y" , pt.y () );
1356
+ optional ( jo, false , " name" , name );
1357
+ optional ( jo, false , " filter" , filter );
1358
+ }
1359
+
1360
+ void vehicle_prototype::load ( const JsonObject &jo, std::string_view )
1361
+ {
1362
+ vgroups[vgroup_id ( id.str () )].add_vehicle ( id, 100 );
1363
+ optional ( jo, was_loaded, " name" , name );
1329
1364
1330
1365
if ( jo.has_member ( " blueprint" ) ) {
1331
1366
// currently unused, read to suppress unvisited members warning
1332
1367
jo.get_array ( " blueprint" );
1333
1368
}
1334
1369
1370
+ std::vector<part_def> tmp;
1335
1371
for ( JsonObject part : jo.get_array ( " parts" ) ) {
1336
- point_rel_ms pos{ part.get_int ( " x" ), part.get_int ( " y" ) };
1337
-
1338
- if ( part.has_string ( " part" ) ) {
1339
- add_part_obj ( part, pos );
1340
- debugmsg ( " vehicle prototype '%s' uses deprecated string definition for part"
1341
- " '%s', use 'parts' array instead" , id.str (), part.get_string ( " part" ) );
1342
- } else if ( part.has_array ( " parts" ) ) {
1343
- for ( const JsonValue entry : part.get_array ( " parts" ) ) {
1344
- if ( entry.test_string () ) {
1345
- std::string part_name = entry.get_string ();
1346
- add_part_string ( part_name, pos );
1347
- } else {
1348
- JsonObject subpart = entry.get_object ();
1349
- add_part_obj ( subpart, pos );
1350
- }
1351
- }
1352
- }
1372
+ point_rel_ms pos;
1373
+ mandatory ( part, false , " x" , pos.x () );
1374
+ mandatory ( part, false , " y" , pos.y () );
1375
+ mandatory ( part, false , " parts" , tmp, veh_proto_part_def_reader{ pos } );
1376
+ // gross
1377
+ parts.insert ( parts.end (), tmp.begin (), tmp.end () );
1353
1378
}
1354
1379
1355
- for ( JsonObject spawn_info : jo.get_array ( " items" ) ) {
1356
- vehicle_item_spawn next_spawn;
1357
- next_spawn.pos .x () = spawn_info.get_int ( " x" );
1358
- next_spawn.pos .y () = spawn_info.get_int ( " y" );
1359
-
1360
- next_spawn.chance = spawn_info.get_int ( " chance" );
1361
- if ( next_spawn.chance <= 0 || next_spawn.chance > 100 ) {
1362
- debugmsg ( " Invalid spawn chance in %s (%d, %d): %d%%" ,
1363
- name, next_spawn.pos .x (), next_spawn.pos .y (), next_spawn.chance );
1364
- }
1365
-
1366
- // constrain both with_magazine and with_ammo to [0-100]
1367
- next_spawn.with_magazine = std::max ( std::min ( spawn_info.get_int ( " magazine" ,
1368
- next_spawn.with_magazine ), 100 ), 0 );
1369
- next_spawn.with_ammo = std::max ( std::min ( spawn_info.get_int ( " ammo" ,
1370
- next_spawn.with_ammo ), 100 ), 0 );
1371
-
1372
- if ( spawn_info.has_array ( " items" ) ) {
1373
- // Array of items that all spawn together (i.e. jack+tire)
1374
- spawn_info.read ( " items" , next_spawn.item_ids , true );
1375
- } else if ( spawn_info.has_string ( " items" ) ) {
1376
- // Treat single item as array
1377
- // And read the gun variant (if it exists)
1378
- if ( spawn_info.has_string ( " variant" ) ) {
1379
- const std::string variant = spawn_info.get_string ( " variant" );
1380
- next_spawn.variant_ids .emplace_back ( itype_id ( spawn_info.get_string ( " items" ) ), variant );
1381
- } else {
1382
- next_spawn.item_ids .emplace_back ( spawn_info.get_string ( " items" ) );
1383
- }
1384
- }
1385
- if ( spawn_info.has_array ( " item_groups" ) ) {
1386
- // Pick from a group of items, just like map::place_items
1387
- for ( const std::string line : spawn_info.get_array ( " item_groups" ) ) {
1388
- next_spawn.item_groups .emplace_back ( line );
1389
- }
1390
- } else if ( spawn_info.has_string ( " item_groups" ) ) {
1391
- next_spawn.item_groups .emplace_back ( spawn_info.get_string ( " item_groups" ) );
1392
- }
1393
- item_spawns.push_back ( std::move ( next_spawn ) );
1394
- }
1395
-
1396
- for ( JsonObject jzi : jo.get_array ( " zones" ) ) {
1397
- zone_type_id zone_type ( jzi.get_member ( " type" ).get_string () );
1398
- std::string name;
1399
- std::string filter;
1400
- point_rel_ms pt ( jzi.get_member ( " x" ).get_int (), jzi.get_member ( " y" ).get_int () );
1401
-
1402
- if ( jzi.has_string ( " name" ) ) {
1403
- name = jzi.get_string ( " name" );
1404
- }
1405
- if ( jzi.has_string ( " filter" ) ) {
1406
- filter = jzi.get_string ( " filter" );
1407
- }
1408
- zone_defs.emplace_back ( zone_def{ zone_type, name, filter, pt } );
1409
- }
1380
+ optional ( jo, was_loaded, " items" , item_spawns );
1381
+ optional ( jo, was_loaded, " zones" , zone_defs, json_read_reader<zone_def> {} );
1410
1382
}
1411
1383
1412
1384
void vehicle_prototype::save_vehicle_as_prototype ( const vehicle &veh,
@@ -1688,8 +1660,8 @@ void vehicles::finalize_prototypes()
1688
1660
proto.name , i.pos .x (), i.pos .y (), i.chance );
1689
1661
}
1690
1662
for ( auto &j : i.item_ids ) {
1691
- if ( !item::type_is_defined ( j ) ) {
1692
- debugmsg ( " unknown item %s in spawn list of %s" , j.c_str (), proto.id .str () );
1663
+ if ( !item::type_is_defined ( j. first ) ) {
1664
+ debugmsg ( " unknown item %s in spawn list of %s" , j.first . c_str (), proto.id .str () );
1693
1665
}
1694
1666
}
1695
1667
for ( auto &j : i.item_groups ) {
@@ -1708,19 +1680,22 @@ const std::vector<vpart_category> &vpart_category::all()
1708
1680
return vpart_categories_all;
1709
1681
}
1710
1682
1711
- void vpart_category::load ( const JsonObject &jo )
1683
+ void vpart_category::load_all ( const JsonObject &jo )
1712
1684
{
1713
1685
vpart_category def;
1714
-
1715
- assign ( jo, " id" , def.id_ );
1716
- assign ( jo, " name" , def.name_ );
1717
- assign ( jo, " short_name" , def.short_name_ );
1718
- assign ( jo, " priority" , def.priority_ );
1719
-
1686
+ def.load ( jo );
1720
1687
vpart_categories_all.push_back ( def );
1721
1688
}
1722
1689
1723
- void vpart_category::finalize ()
1690
+ void vpart_category::load ( const JsonObject &jo )
1691
+ {
1692
+ mandatory ( jo, false , " id" , id_ );
1693
+ mandatory ( jo, false , " name" , name_ );
1694
+ mandatory ( jo, false , " short_name" , short_name_ );
1695
+ mandatory ( jo, false , " priority" , priority_ );
1696
+ }
1697
+
1698
+ void vpart_category::finalize_all ()
1724
1699
{
1725
1700
std::sort ( vpart_categories_all.begin (), vpart_categories_all.end () );
1726
1701
}
0 commit comments