Skip to content

Commit 4e2a144

Browse files
authored
Merge pull request #82741 from ehughsbaird/most-veh-optional
Replace assign with optional/mandatory in veh_type
2 parents 9cf0e65 + 3e1142b commit 4e2a144

File tree

8 files changed

+135
-151
lines changed

8 files changed

+135
-151
lines changed

doc/JSON/VEHICLES_JSON.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,13 @@ and describes the items that may spawn at that location.
116116
TYPE and DATA may be one of:
117117
```jsonc
118118
"items": "itemid" // single item of that type
119-
"items": [ "itemid1", "itemid2", /* ... */ ] // all the items in the array
119+
"items": [ "itemid1", { "id": "itemid2", "variant": "foo" }, /* ... */ ] // all the items in the array
120120
"item_groups": "groupid" // one or more items in the group, depending on
121121
// whether the group is a collection or distribution
122122
"item_groups": [ "groupid1", "groupid2" /* ... */ ] // one or more items for each group
123123
```
124124
the optional keyword "chance" provides an X in 100 chance that a particular item definition will spawn.
125125

126-
If a single item is specified through `"items"`, an itype variant for it can be specified through `"variant"`.
127-
128126
Multiple lines of items may share the same X and Y values.
129127

130128
### Zones list

src/init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ void DynamicDataLoader::initialize()
337337
} );
338338

339339
add( "vehicle_part", &vehicles::parts::load );
340-
add( "vehicle_part_category", &vpart_category::load );
340+
add( "vehicle_part_category", &vpart_category::load_all );
341341
add( "vehicle_part_migration", &vpart_migration::load );
342342
add( "vehicle", &vehicles::load_prototype );
343343
add( "vehicle_group", &VehicleGroup::load );
@@ -782,7 +782,7 @@ void DynamicDataLoader::finalize_loaded_data()
782782
requirement_data::finalize();
783783
}
784784
},
785-
{ _( "Vehicle part categories" ), &vpart_category::finalize },
785+
{ _( "Vehicle part categories" ), &vpart_category::finalize_all },
786786
{ _( "Vehicle parts" ), &vehicles::parts::finalize },
787787
{ _( "Traps" ), &trap::finalize_all },
788788
{ _( "Terrain" ), &set_ter_ids },

src/item_factory.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,10 @@ void Item_factory::finalize_item_blacklist()
16141614
vehicle_prototype &prototype = const_cast<vehicle_prototype &>( const_prototype );
16151615
for( vehicle_item_spawn &vis : prototype.item_spawns ) {
16161616
auto &vec = vis.item_ids;
1617-
const auto iter = std::remove_if( vec.begin(), vec.end(), item_is_blacklisted );
1617+
auto is_blacklisted = []( const std::pair<itype_id, std::string> &pair ) {
1618+
return item_is_blacklisted( pair.first );
1619+
};
1620+
const auto iter = std::remove_if( vec.begin(), vec.end(), is_blacklisted );
16181621
vec.erase( iter, vec.end() );
16191622
}
16201623
}
@@ -1716,7 +1719,8 @@ void Item_factory::finalize_item_blacklist()
17161719
for( const vehicle_prototype &const_prototype : vehicles::get_all_prototypes() ) {
17171720
vehicle_prototype &prototype = const_cast<vehicle_prototype &>( const_prototype );
17181721
for( vehicle_item_spawn &vis : prototype.item_spawns ) {
1719-
for( itype_id &type_to_spawn : vis.item_ids ) {
1722+
for( std::pair<itype_id, std::string> &spawn_pair : vis.item_ids ) {
1723+
itype_id &type_to_spawn = spawn_pair.first;
17201724
std::map<itype_id, std::vector<migration>>::iterator replacement =
17211725
migrations.find( type_to_spawn );
17221726
if( replacement == migrations.end() ) {

src/units.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ void temperature::deserialize( const JsonValue &jv )
7979
*this = from_kelvin( std::stof( jv.get_string() ) );
8080
}
8181

82+
template<>
83+
void temperature_delta::deserialize( const JsonValue &jv )
84+
{
85+
if( jv.test_int() ) {
86+
*this = from_legacy_bodypart_temp_delta( jv.get_int() );
87+
} else {
88+
// super gross
89+
*this = from_kelvin_delta( std::stof( jv.get_string() ) );
90+
}
91+
}
92+
8293
template<>
8394
void energy::serialize( JsonOut &jsout ) const
8495
{

src/veh_type.cpp

Lines changed: 91 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <unordered_set>
1313

1414
#include "ammo.h"
15-
#include "assign.h"
1615
#include "cata_assert.h"
1716
#include "catacharset.h"
1817
#include "character.h"
@@ -240,10 +239,8 @@ void vpart_info::handle_inheritance( const vpart_info &copy_from,
240239
}
241240
}
242241

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 )
244243
{
245-
const bool strict = src == "dda";
246-
247244
optional( jo, was_loaded, "name", name_ );
248245
optional( jo, was_loaded, "item", base_item );
249246
optional( jo, was_loaded, "remove_as", removed_item );
@@ -267,12 +264,8 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
267264
optional( jo, was_loaded, "color", color, nc_color_reader{}, c_light_gray );
268265
optional( jo, was_loaded, "broken_color", color_broken, nc_color_reader{}, c_light_gray );
269266
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 );
276269

277270
int enchant_num = 0;
278271
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
12971290
: std::make_pair( vpid.substr( 0, loc ), vpid.substr( loc + 1 ) );
12981291
}
12991292

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 )
13011337
{
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() );
13041340

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

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

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+
}
13201350

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

13301365
if( jo.has_member( "blueprint" ) ) {
13311366
// currently unused, read to suppress unvisited members warning
13321367
jo.get_array( "blueprint" );
13331368
}
13341369

1370+
std::vector<part_def> tmp;
13351371
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() );
13531378
}
13541379

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> {} );
14101382
}
14111383

14121384
void vehicle_prototype::save_vehicle_as_prototype( const vehicle &veh,
@@ -1688,8 +1660,8 @@ void vehicles::finalize_prototypes()
16881660
proto.name, i.pos.x(), i.pos.y(), i.chance );
16891661
}
16901662
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() );
16931665
}
16941666
}
16951667
for( auto &j : i.item_groups ) {
@@ -1708,19 +1680,22 @@ const std::vector<vpart_category> &vpart_category::all()
17081680
return vpart_categories_all;
17091681
}
17101682

1711-
void vpart_category::load( const JsonObject &jo )
1683+
void vpart_category::load_all( const JsonObject &jo )
17121684
{
17131685
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 );
17201687
vpart_categories_all.push_back( def );
17211688
}
17221689

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()
17241699
{
17251700
std::sort( vpart_categories_all.begin(), vpart_categories_all.end() );
17261701
}

0 commit comments

Comments
 (0)