Skip to content

Commit

Permalink
water rework part 1 (#72252)
Browse files Browse the repository at this point in the history
* water rework part 1

ref #72

* drop char_purifier for purifying murky water

* clang-tidy

* astyle

* json style

* double-space

* add slow-sand filter and update murky water filtering to use it

* use bucket_5gal instead of jerrycan for water_filter_sand

* Apply suggestions from code review

Co-authored-by: osuphobia <[email protected]>

* Update data/json/recipes/recipe_food.json

Co-authored-by: osuphobia <[email protected]>

* Update data/json/items/tool/cooking.json

Co-authored-by: osuphobia <[email protected]>

* Update data/json/items/comestibles/drink.json

Co-authored-by: osuphobia <[email protected]>

---------

Co-authored-by: osuphobia <[email protected]>
  • Loading branch information
nornagon and osuphobia authored Jun 4, 2024
1 parent ad47de5 commit c8164e3
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 97 deletions.
4 changes: 2 additions & 2 deletions data/json/furniture_and_terrain/terrain-liquids.json
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@
"symbol": "~",
"color": "light_blue",
"move_cost": 3,
"flags": [ "TRANSPARENT", "LIQUIDCONT", "SPAWN_WITH_LIQUID", "FRESH_WATER", "MURKY" ],
"flags": [ "TRANSPARENT", "LIQUIDCONT", "SPAWN_WITH_WATER", "MURKY" ],
"examine_action": "finite_water_source"
},
{
Expand All @@ -491,7 +491,7 @@
"color": "light_blue",
"move_cost": 3,
"connect_groups": "INDOORFLOOR",
"flags": [ "TRANSPARENT", "LIQUIDCONT", "SPAWN_WITH_LIQUID", "FRESH_WATER", "MURKY", "INDOORS" ],
"flags": [ "TRANSPARENT", "LIQUIDCONT", "SPAWN_WITH_WATER", "MURKY", "INDOORS" ],
"examine_action": "finite_water_source"
},
{
Expand Down
53 changes: 33 additions & 20 deletions data/json/items/comestibles/drink.json
Original file line number Diff line number Diff line change
Expand Up @@ -1485,49 +1485,62 @@
{
"id": "water",
"type": "COMESTIBLE",
"comestible_type": "DRINK",
"category": "food",
"copy-from": "water_clean",
"name": { "str_sp": "water" },
"description": "Water, the stuff of life, necessary for all kinds of crafting, cleaning, and avoiding an agonizing death by dehydration. You should boil or purify it before using it as drinking water.",
"color": "light_blue",
"container": "bottle_plastic",
"sealed": false,
"contamination": [ { "disease": "highly_contaminated_food", "probability": 0.1 }, { "disease": "bad_food", "probability": 1 } ]
},
{
"id": "water_murky",
"type": "COMESTIBLE",
"copy-from": "water",
"name": { "str_sp": "murky water" },
"description": "Water, the stuff of life. This water looks like it has quite a bit of life in it in fact, and not the good kind. You should filter and sterilize it if you want to drink it.",
"quench": 30,
"parasites": 5,
"contamination": [ { "disease": "highly_contaminated_food", "probability": 100 } ]
},
{
"id": "water_clean",
"type": "COMESTIBLE",
"comestible_type": "DRINK",
"category": "food",
"material": [ "water" ],
"weight": "250 g",
"volume": "250 ml",
"charges": 1,
"price": "50 cent",
"price_postapoc": "1 cent",
"symbol": "~",
"color": "light_blue",
"phase": "liquid",
"container": "bottle_plastic",
"sealed": false,
"quench": 50,
"ammo_data": { "ammo_type": "water" },
"flags": [ "EATEN_COLD" ],
"use_action": [ "BLECH_BECAUSE_UNCLEAN" ]
},
{
"id": "water_clean",
"copy-from": "water",
"type": "COMESTIBLE",
"flags": [ "EATEN_COLD", "NUTRIENT_OVERRIDE" ],
"name": { "str_sp": "clean water" },
"description": "Fresh, clean water. Truly the best thing to quench your thirst.",
"container": "bottle_plastic",
"sealed": true,
"color": "light_cyan",
"extend": { "flags": [ "NUTRIENT_OVERRIDE" ] },
"use_action": [ ]
"color": "light_cyan"
},
{
"id": "water_spring",
"copy-from": "water_clean",
"type": "COMESTIBLE",
"name": { "str_sp": "spring water" },
"description": "Natural alpine spring water, bottled at the source.",
"relative": { "fun": 1 }
},
{
"id": "water_mineral",
"copy-from": "water",
"copy-from": "water_clean",
"type": "COMESTIBLE",
"name": { "str_sp": "mineral water" },
"description": "Fancy mineral water, so fancy it makes you feel fancy just holding it.",
"container": "bottle_plastic",
"sealed": true,
"proportional": { "quench": 1.2 },
"relative": { "fun": 1 },
"use_action": [ ]
"relative": { "fun": 1 }
},
{
"type": "COMESTIBLE",
Expand Down
16 changes: 16 additions & 0 deletions data/json/items/tool/cooking.json
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,22 @@
],
"melee_damage": { "bash": 2 }
},
{
"id": "water_filter_sand",
"type": "TOOL",
"name": { "str": "slow-sand water filter" },
"//": "Slow sand biofilter: https://wwwnc.cdc.gov/travel/yellowbook/2024/preparing/water-disinfection#:~:text=Figure%202%2D02.%20Emergency%20gravel%20and%20sand%20filter",
"description": "An improvised water filter made from a plastic bucket filled with a layer of sand and a layer of gravel. It can be used to remove particulates and some pathogens from water, but it is not 100% effective.",
"//2": "Density of sand is around 1.6g/cm^3. Gravel is similar. pi * 5in * 5in * (10 in + 4 in) * 1.6 g/cm^3 ~= 29 kg. Add 1 kg for the bucket itself.",
"weight": "14800 g",
"volume": "21000 ml",
"price": 1000,
"price_postapoc": 150,
"to_hit": -3,
"material": [ "plastic", "sand" ],
"symbol": ";",
"color": "light_blue"
},
{
"id": "propane_cooker",
"type": "TOOL",
Expand Down
28 changes: 27 additions & 1 deletion data/json/recipes/recipe_food.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"category": "CC_FOOD",
"id_suffix": "using_water_purifier",
"subcategory": "CSC_FOOD_DRINKS",
"skill_used": "cooking",
"skill_used": "survival",
"time": "9 s",
"//": "https://www.netsolwater.com/how-much-energy-does-an-ro-system-use.php?blog=484",
"//1": "Unclear if this is a RO filter but basing it off that. 0.03 KwH per 2 liters in a RO filter = 14kJ for 1u of water",
Expand All @@ -85,6 +85,32 @@
"tools": [ [ [ "water_purifier", 14 ], [ "pur_tablets", 1 ], [ "char_purifier", 12 ], [ "char_purifier_clay", 12 ] ] ],
"components": [ [ [ "water", 1 ] ] ]
},
{
"type": "recipe",
"activity_level": "NO_EXERCISE",
"result": "water",
"category": "CC_FOOD",
"id_suffix": "using_water_purifier",
"subcategory": "CSC_FOOD_DRINKS",
"skill_used": "survival",
"time": "1 m",
"autolearn": true,
"components": [ [ [ "water_murky", 1 ] ], [ [ "pur_tablets", 1 ] ] ]
},
{
"type": "recipe",
"activity_level": "NO_EXERCISE",
"result": "water",
"charges": 10,
"category": "CC_FOOD",
"id_suffix": "using_water_filter_sand",
"subcategory": "CSC_FOOD_DRINKS",
"skill_used": "survival",
"time": "15 m",
"autolearn": true,
"tools": [ [ "water_filter_sand" ] ],
"components": [ [ [ "water_murky", 10 ] ] ]
},
{
"type": "recipe",
"activity_level": "NO_EXERCISE",
Expand Down
19 changes: 19 additions & 0 deletions data/json/recipes/tools/tools_primitive.json
Original file line number Diff line number Diff line change
Expand Up @@ -496,5 +496,24 @@
],
"using": [ [ "blacksmithing_standard", 13 ], [ "steel_standard", 1 ] ],
"components": [ [ [ "2x4", 2 ] ] ]
},
{
"type": "recipe",
"result": "water_filter_sand",
"activity_level": "MODERATE_EXERCISE",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_TOOLS",
"skill_used": "survival",
"skills_required": [ [ "survival", 2 ] ],
"difficulty": 2,
"time": "30 m",
"autolearn": true,
"reversible": true,
"components": [
[ [ "bucket_5gal", 1 ] ],
[ [ "material_sand", 1250 ] ],
[ [ "material_gravel", 500 ] ],
[ [ "cotton_patchwork", 4 ], [ "wire_mesh", 4 ] ]
]
}
]
4 changes: 2 additions & 2 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1208,8 +1208,8 @@ static bool eat( item &food, Character &you, bool force )
}
}

for( const std::pair<const diseasetype_id, int> &elem : food.get_comestible()->contamination ) {
if( rng( 1, 100 ) <= elem.second ) {
for( const std::pair<const diseasetype_id, float> &elem : food.get_comestible()->contamination ) {
if( rng_float( 0, 100 ) < elem.second ) {
you.expose_to_disease( elem.first );
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ void Item_factory::finalize_post( itype &obj )
}

if( obj.comestible ) {
for( const std::pair<const diseasetype_id, int> &elem : obj.comestible->contamination ) {
for( const std::pair<const diseasetype_id, float> &elem : obj.comestible->contamination ) {
const diseasetype_id dtype = elem.first;
if( !dtype.is_valid() ) {
debugmsg( "contamination in %s contains invalid diseasetype_id %s.",
Expand Down Expand Up @@ -3308,7 +3308,7 @@ void Item_factory::load( islot_comestible &slot, const JsonObject &jo, const std

for( const JsonObject jsobj : jo.get_array( "contamination" ) ) {
slot.contamination.emplace( diseasetype_id( jsobj.get_string( "disease" ) ),
jsobj.get_int( "probability" ) );
jsobj.get_float( "probability" ) );
}

if( jo.has_member( "primary_material" ) ) {
Expand Down
2 changes: 1 addition & 1 deletion src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ struct islot_comestible {
std::vector<effect_on_condition_id> consumption_eocs;

/**List of diseases carried by this comestible and their associated probability*/
std::map<diseasetype_id, int> contamination;
std::map<diseasetype_id, float> contamination;

// Materials to generate the below
std::map<material_id, int> materials;
Expand Down
78 changes: 15 additions & 63 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ static const ammotype ammo_battery( "battery" );

static const damage_type_id damage_bash( "bash" );

static const diseasetype_id disease_bad_food( "bad_food" );

static const efftype_id effect_boomered( "boomered" );
static const efftype_id effect_crushed( "crushed" );
static const efftype_id effect_fake_common_cold( "fake_common_cold" );
Expand All @@ -141,6 +139,8 @@ static const item_group_id Item_spawn_data_default_zombie_items( "default_zombie

static const itype_id itype_battery( "battery" );
static const itype_id itype_nail( "nail" );
static const itype_id itype_water( "water" );
static const itype_id itype_water_murky( "water_murky" );

static const material_id material_glass( "glass" );

Expand Down Expand Up @@ -2302,18 +2302,13 @@ bool map::ter_set( const tripoint &p, const ter_id &new_terrain, bool avoid_crea
set_seen_cache_dirty( p );
}

if( new_t.has_flag( "SPAWN_WITH_LIQUID" ) ) {
if( new_t.has_flag( "FRESH_WATER" ) ) {
item water( "water", calendar::start_of_cataclysm );
// TODO: Move all numeric values to json
water.charges = rng( 40, 240 );
if( new_t.has_flag( ter_furn_flag::TFLAG_MURKY ) ) {
water.poison = rng( 1, 6 );
water.get_comestible()->parasites = 5;
water.get_comestible()->contamination = { { disease_bad_food, 5 } };
}
add_item( p, water );
}
if( new_t.has_flag( "SPAWN_WITH_WATER" ) ) {
itype_id water_type = new_t.has_flag( ter_furn_flag::TFLAG_MURKY ) ? itype_water_murky :
itype_water;
item water( water_type, calendar::start_of_cataclysm );
// TODO: Move all numeric values to json
water.charges = rng( 40, 240 );
add_item( p, water );
}

invalidate_max_populated_zlev( p.z );
Expand Down Expand Up @@ -5493,64 +5488,21 @@ item map::water_from( const tripoint &p )
return ret;
}

if( has_flag( ter_furn_flag::TFLAG_MURKY, p ) ) {
for( item &ret : get_map().i_at( p ) ) {
if( ret.made_of( phase_id::LIQUID ) ) {
ret.set_item_temperature( std::max( weather.get_temperature( p ),
temperatures::cold ) );
ret.poison = rng( 1, 6 );
ret.get_comestible()->parasites = 5;
ret.get_comestible()->contamination = { { disease_bad_food, 5 } };
return ret;
}
}
}

if( has_flag( ter_furn_flag::TFLAG_TOILET_WATER, p ) ) {
for( item &ret : get_map().i_at( p ) ) {
if( ret.made_of( phase_id::LIQUID ) ) {
ret.set_item_temperature( std::max( weather.get_temperature( p ),
temperatures::cold ) );
ret.poison = one_in( 3 ) ? 0 : rng( 1, 3 );
return ret;
}
}
}

const ter_id terrain_id = ter( p );
if( terrain_id == ter_t_sewage ) {
item ret( "water_sewage", calendar::turn, item::INFINITE_CHARGES );
ret.set_item_temperature( std::max( weather.get_temperature( p ),
temperatures::cold ) );
ret.poison = rng( 1, 7 );
return ret;
}

item ret( "water", calendar::turn, item::INFINITE_CHARGES );
ret.set_item_temperature( std::max( weather.get_temperature( p ),
temperatures::cold ) );
// iexamine::water_source requires a valid liquid from this function.
if( terrain_id->has_examine( iexamine::water_source ) ) {
int poison_chance = 0;
if( terrain_id.obj().has_flag( ter_furn_flag::TFLAG_DEEP_WATER ) ) {
if( terrain_id.obj().has_flag( ter_furn_flag::TFLAG_CURRENT ) ) {
poison_chance = 20;
} else {
poison_chance = 4;
}
} else {
if( terrain_id.obj().has_flag( ter_furn_flag::TFLAG_CURRENT ) ) {
poison_chance = 10;
} else {
poison_chance = 3;
}
}
if( one_in( poison_chance ) ) {
ret.poison = rng( 1, 4 );
}
return ret;
}
if( furn( p )->has_examine( iexamine::water_source ) ) {
if( terrain_id->has_examine( iexamine::water_source ) ||
furn( p )->has_examine( iexamine::water_source ) ) {
itype_id liquid_id = has_flag( ter_furn_flag::TFLAG_MURKY, p ) ? itype_water_murky : itype_water;
item ret( liquid_id, calendar::turn, item::INFINITE_CHARGES );
ret.set_item_temperature( std::max( weather.get_temperature( p ),
temperatures::cold ) );
return ret;
}
return item();
Expand Down
7 changes: 1 addition & 6 deletions src/weather.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,15 +246,10 @@ void item::add_rain_to_container( int charges )
ret.charges = std::min( charges, capa );
if( contents.can_contain( ret ).success() ) {
// This is easy. Just add 1 charge of the rain liquid to the container.
// Funnels aren't always clean enough for water. // TODO: disinfectant squeegie->funnel
ret.poison = one_in( 10 ) ? 1 : 0;
put_in( ret, pocket_type::CONTAINER );
} else {
static const std::set<itype_id> allowed_liquid_types{
itype_water
};
item *found_liq = contents.get_item_with( [&]( const item & liquid ) {
return allowed_liquid_types.count( liquid.typeId() );
return liquid.typeId() == itype_water;
} );
if( found_liq == nullptr ) {
debugmsg( "Rainwater failed to add to container" );
Expand Down

0 comments on commit c8164e3

Please sign in to comment.