diff --git a/data/json/items/containers.json b/data/json/items/containers.json index 3117ccf9e58ce..a981fccc4e0cf 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -389,6 +389,7 @@ "watertight": true, "rigid": true, "max_contains_volume": "2 L", + "max_item_volume": "17 ml", "max_contains_weight": "3 kg", "moves": 400 } diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 2a303c6f4a500..d39140eb73f28 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -44,6 +44,11 @@ void pocket_data::load( const JsonObject &jo ) // putting it in an if statement like this should allow for report_unvisited_member to work here if( ammo_restriction.empty() ) { optional( jo, was_loaded, "min_item_volume", min_item_volume, volume_reader(), 0_ml ); + units::volume temp = -1_ml; + optional( jo, was_loaded, "max_item_volume", temp, volume_reader(), temp ); + if( temp != -1_ml ) { + max_item_volume = temp; + } mandatory( jo, was_loaded, "max_contains_volume", max_contains_volume, volume_reader() ); mandatory( jo, was_loaded, "max_contains_weight", max_contains_weight, mass_reader() ); } @@ -600,6 +605,11 @@ void item_pocket::general_info( std::vector &info, int pocket_number, string_format( _( "Minimum volume of item allowed: %s" ), vol_to_string( data->min_item_volume ) ) ); } + if( data->max_item_volume ) { + info.emplace_back( "DESCRIPTION", + string_format( _( "Maximum volume of item allowed: %s" ), + vol_to_string( *data->max_item_volume ) ) ); + } info.emplace_back( "DESCRIPTION", string_format( _( "Volume Capacity: %s" ), vol_to_string( data->max_contains_volume ) ) ); @@ -793,6 +803,15 @@ ret_val item_pocket::can_contain( const item &it ) co return ret_val::make_success(); } + // liquids and gases avoid the size limit altogether + // soft items also avoid the size limit + if( !it.made_of( LIQUID ) && !it.made_of( GAS ) && + !it.is_soft() && data->max_item_volume && + it.volume() > *data->max_item_volume ) { + return ret_val::make_failure( + contain_code::ERR_TOO_BIG, _( "item too big" ) ); + } + if( it.volume() < data->min_item_volume ) { return ret_val::make_failure( contain_code::ERR_TOO_SMALL, _( "item is too small" ) ); diff --git a/src/item_pocket.h b/src/item_pocket.h index 0fb30b369c084..1e5b840a39950 100644 --- a/src/item_pocket.h +++ b/src/item_pocket.h @@ -257,6 +257,8 @@ class pocket_data item_pocket::pocket_type type = item_pocket::pocket_type::CONTAINER; // max volume of stuff the pocket can hold units::volume max_contains_volume = 0_ml; + // max volume of item that can be contained, otherwise it spills + cata::optional max_item_volume = cata::nullopt; // min volume of item that can be contained, otherwise it spills units::volume min_item_volume = 0_ml; // max weight of stuff the pocket can hold