diff --git a/data/json/furniture_and_terrain/terrain-liquids.json b/data/json/furniture_and_terrain/terrain-liquids.json
index 30ffa1ce5953a..3b8d3b46bb105 100644
--- a/data/json/furniture_and_terrain/terrain-liquids.json
+++ b/data/json/furniture_and_terrain/terrain-liquids.json
@@ -63,7 +63,7 @@
"color": "light_blue",
"looks_like": "t_water_sh",
"move_cost": 5,
- "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "FISHABLE", "SHALLOW_WATER" ],
+ "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "FISHABLE", "SHALLOW_WATER", "MURKY" ],
"connects_to": "WATER",
"examine_action": "water_source"
},
@@ -78,7 +78,7 @@
"looks_like": "t_water_sh",
"move_cost": 5,
"roof": "t_rock_roof",
- "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "FISHABLE", "INDOORS", "SHALLOW_WATER" ],
+ "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "FISHABLE", "INDOORS", "SHALLOW_WATER", "MURKY" ],
"connects_to": "WATER",
"examine_action": "water_source"
},
@@ -405,5 +405,17 @@
"flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "SHALLOW_WATER" ],
"connects_to": "WATER",
"examine_action": "water_source"
+ },
+ {
+ "type": "terrain",
+ "id": "t_puddle",
+ "name": "recess",
+ "description": "A shallow pit in the ground.",
+ "looks_like": "t_dirt",
+ "symbol": "~",
+ "color": "light_blue",
+ "move_cost": 3,
+ "flags": [ "TRANSPARENT", "LIQUIDCONT", "SPAWN_WITH_LIQUID", "FRESH_WATER", "MURKY" ],
+ "examine_action": "finite_water_source"
}
]
diff --git a/data/json/regional_map_settings.json b/data/json/regional_map_settings.json
index 186032911c161..73a379e32ddba 100644
--- a/data/json/regional_map_settings.json
+++ b/data/json/regional_map_settings.json
@@ -292,7 +292,7 @@
"t_pit_shallow": 1
}
},
- "water": { "sequence": 3, "chance": 512, "clear_types": false, "types": { "t_water_sh": 1 } }
+ "water": { "sequence": 3, "chance": 512, "clear_types": false, "types": { "t_puddle": 1 } }
},
"clear_terrain_furniture": false,
"terrain_furniture": { }
@@ -342,7 +342,7 @@
"t_pit_shallow": 1
}
},
- "water": { "sequence": 3, "chance": 512, "clear_types": false, "types": { "t_water_sh": 1 } }
+ "water": { "sequence": 3, "chance": 512, "clear_types": false, "types": { "t_puddle": 1 } }
},
"clear_terrain_furniture": false,
"terrain_furniture": { }
@@ -396,10 +396,15 @@
"clear_types": false,
"types": { "t_trunk": 1, "f_boulder_small": 2, "f_boulder_medium": 1 }
},
- "water": { "sequence": 3, "chance": 2, "clear_types": false, "types": { "t_swater_sh": 12, "t_swater_dp": 1, "t_water_sh": 6 } }
+ "water": {
+ "sequence": 3,
+ "chance": 2,
+ "clear_types": false,
+ "types": { "t_swater_sh": 6, "t_swater_dp": 1, "t_water_murky": 12 }
+ }
},
"clear_terrain_furniture": false,
- "terrain_furniture": { "t_water_sh": { "chance": 2, "clear_furniture": false, "furniture": { "f_region_water_plant": 1 } } }
+ "terrain_furniture": { "t_water_murky": { "chance": 2, "clear_furniture": false, "furniture": { "f_region_water_plant": 1 } } }
}
},
"forest_trail_settings": {
diff --git a/doc/EXAMINE.md b/doc/EXAMINE.md
index cd833b8b07919..522c846087efd 100644
--- a/doc/EXAMINE.md
+++ b/doc/EXAMINE.md
@@ -16,6 +16,7 @@ The examine actors are specified as JSON objects with a `type` corresponding to
- ```controls_gate``` Controls the attached gate.
- ```dirtmound``` Plant seeds and plants.
- ```elevator``` Use the elevator to change floors.
+- ```finite_water_source``` Drink or get water from a water source. Unlike ordinary `water_source`, terrain with this examine action will get liquid from a finite source (liquid is placed on that tile as an item during the mapgen) and will stop functioning if said liquid if exhausted on that tile.
- ```flower_poppy``` Pick the mutated poppy.
- ```fswitch``` Flip the switch and the rocks will shift.
- ```fungus``` Release spores as the terrain crumbles away.
diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md
index 5200ef576cf1f..1a50d22af6889 100644
--- a/doc/JSON_FLAGS.md
+++ b/doc/JSON_FLAGS.md
@@ -581,6 +581,7 @@ List of known flags, used in both `terrain.json` and `furniture.json`.
- ```FLAT``` Player can build and move furniture on.
- ```FORAGE_HALLU``` This item can be found with the `HIDDEN_HALLU` flag when found through foraging.
- ```FORAGE_POISION``` This item can be found with the `HIDDEN_POISON` flag when found through foraging.
+- ```FRESH_WATER``` Source of fresh water. Will spawn fresh water (once) on terrains with `SPAWN_WITH_LIQUID` flag.
- ```GOES_DOWN``` Can use > to go down a level.
- ```GOES_UP``` Can use < to go up a level.
- ```GROWTH_SEEDLING``` This plant is in its seedling stage of growth.
@@ -594,6 +595,7 @@ List of known flags, used in both `terrain.json` and `furniture.json`.
- ```LIQUID``` Blocks movement, but isn't a wall (lava, water, etc.)
- ```MINEABLE``` Can be mined with a pickaxe/jackhammer.
- ```MOUNTABLE``` Suitable for guns with the `MOUNTED_GUN` flag.
+- ```MURKY``` Water taker from tiles with this flag is badly poisoned (almost on par with sewage).
- ```NOCOLLIDE``` Feature that simply doesn't collide with vehicles at all.
- ```NOITEM``` Items cannot be added here but may overflow to adjacent tiles. See also `DESTROY_ITEM`
- ```NO_FLOOR``` Things should fall when placed on this tile
@@ -624,6 +626,7 @@ List of known flags, used in both `terrain.json` and `furniture.json`.
- ```SHORT``` Feature too short to collide with vehicle protrusions. (mirrors, blades).
- ```SIGN``` Show written message on examine.
- ```SMALL_PASSAGE``` This terrain or furniture is too small for large or huge creatures to pass through.
+- ```SPAWN_WITH_LIQUID``` This terrain will place liquid (once) on its own spawn. Type of liquid is defined by other flags. For example, it spawns fresh water via `FRESH_WATER` flag.
- ```SUN_ROOF_ABOVE``` This furniture (terrain is not supported currently) has a "fake roof" above, that blocks sunlight. Special hack for #44421, to be removed later.
- ```SUPPORTS_ROOF``` Used as a boundary for roof construction.
- ```SUPPRESS_SMOKE``` Prevents smoke from fires; used by ventilated wood stoves, etc.
diff --git a/src/iexamine.cpp b/src/iexamine.cpp
index bf42f8b948639..f0141e637927e 100644
--- a/src/iexamine.cpp
+++ b/src/iexamine.cpp
@@ -3934,6 +3934,17 @@ void iexamine::clean_water_source( Character &, const tripoint &examp )
liquid_handler::handle_liquid( water, nullptr, 0, &examp );
}
+void iexamine::finite_water_source( Character &, const tripoint &examp )
+{
+ map_stack items = get_map().i_at( examp );
+ for( auto item_it = items.begin(); item_it != items.end(); ++item_it ) {
+ if( item_it->made_of( phase_id::LIQUID ) ) {
+ liquid_handler::handle_liquid_from_ground( item_it, examp );
+ break;
+ }
+ }
+}
+
const itype *furn_t::crafting_pseudo_item_type() const
{
if( crafting_pseudo_item.is_empty() ) {
@@ -6325,6 +6336,7 @@ iexamine_functions iexamine_functions_from_string( const std::string &function_n
{ "shrub_wildveggies", &iexamine::shrub_wildveggies },
{ "water_source", &iexamine::water_source },
{ "clean_water_source", &iexamine::clean_water_source },
+ { "finite_water_source", &iexamine::finite_water_source },
{ "reload_furniture", &iexamine::reload_furniture },
{ "curtains", &iexamine::curtains },
{ "sign", &iexamine::sign },
diff --git a/src/iexamine.h b/src/iexamine.h
index 641b6ed6b620d..1f173a8c423a3 100644
--- a/src/iexamine.h
+++ b/src/iexamine.h
@@ -112,6 +112,7 @@ void tree_marloss( Character &you, const tripoint &examp );
void shrub_wildveggies( Character &you, const tripoint &examp );
void water_source( Character &, const tripoint &examp );
void clean_water_source( Character &, const tripoint &examp );
+void finite_water_source( Character &, const tripoint &examp );
void kiln_empty( Character &you, const tripoint &examp );
void kiln_full( Character &you, const tripoint &examp );
void arcfurnace_empty( Character &you, const tripoint &examp );
diff --git a/src/inventory.cpp b/src/inventory.cpp
index fddf807275a3c..51def36b835ff 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -540,7 +540,8 @@ void inventory::form_from_map( map &m, std::vector pts, const Characte
}
// keg-kludge
- if( m.furn( p )->has_examine( iexamine::keg ) ) {
+ if( m.furn( p )->has_examine( iexamine::keg ) ||
+ m.ter( p )->has_examine( iexamine::finite_water_source ) ) {
map_stack liq_contained = m.i_at( p );
for( auto &i : liq_contained ) {
if( i.made_of( phase_id::LIQUID ) ) {
diff --git a/src/map.cpp b/src/map.cpp
index 4a6d37db8df9b..67b20303fb0bc 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -103,6 +103,8 @@
static const ammotype ammo_battery( "battery" );
+static const diseasetype_id disease_bad_food( "bad_food" );
+
static const efftype_id effect_boomered( "boomered" );
static const efftype_id effect_crushed( "crushed" );
@@ -1748,6 +1750,21 @@ bool map::ter_set( const tripoint &p, const ter_id &new_terrain )
support_cache_dirty.insert( p );
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 );
+ }
+ }
+
invalidate_max_populated_zlev( p.z );
set_memory_seen_cache_dirty( p );
@@ -4526,6 +4543,16 @@ item map::water_from( const tripoint &p )
return ret;
}
+ if( has_flag( ter_furn_flag::TFLAG_MURKY, p ) ) {
+ item ret( "water", calendar::turn, item::INFINITE_CHARGES );
+ ret.set_item_temperature( temp_to_kelvin( 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;
+ }
+
const ter_id terrain_id = ter( p );
if( terrain_id == t_sewage ) {
item ret( "water_sewage", calendar::turn, item::INFINITE_CHARGES );
diff --git a/src/mapdata.cpp b/src/mapdata.cpp
index 101429816f17b..ffdd5e12253fb 100644
--- a/src/mapdata.cpp
+++ b/src/mapdata.cpp
@@ -249,6 +249,7 @@ std::string enum_to_string( ter_furn_flag data )
case ter_furn_flag::TFLAG_BLOCKSDOOR: return "BLOCKSDOOR";
case ter_furn_flag::TFLAG_NO_SELF_CONNECT: return "NO_SELF_CONNECT";
case ter_furn_flag::TFLAG_BURROWABLE: return "BURROWABLE";
+ case ter_furn_flag::TFLAG_MURKY: return "MURKY";
// *INDENT-ON*
case ter_furn_flag::NUM_TFLAG_FLAGS:
diff --git a/src/mapdata.h b/src/mapdata.h
index e73ec0507d452..87f26feb14e34 100644
--- a/src/mapdata.h
+++ b/src/mapdata.h
@@ -293,6 +293,7 @@ enum class ter_furn_flag : int {
TFLAG_BLOCKSDOOR,
TFLAG_NO_SELF_CONNECT,
TFLAG_BURROWABLE,
+ TFLAG_MURKY,
NUM_TFLAG_FLAGS
};