Skip to content

Commit

Permalink
Cattail can be planted in shallow water (#68664)
Browse files Browse the repository at this point in the history
* commit

* Make examine action not able to plant incorrect seed

* Update seed.json

* retrigger checks
  • Loading branch information
Light-Wave authored Oct 16, 2023
1 parent f83877a commit 43d4862
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 12 deletions.
12 changes: 9 additions & 3 deletions data/json/items/comestibles/seed.json
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,15 @@
"copy-from": "seed",
"name": { "str_sp": "cattail seeds" },
"color": "green",
"description": "Some cattail seeds.",
"flags": [ "NUTRIENT_OVERRIDE", "INEDIBLE" ],
"seed_data": { "plant_name": "cattail", "fruit": "cattail_stalk", "byproducts": [ "cattail_rhizome" ], "grow": "91 days" }
"description": "Some cattail seeds. Must be planted in shallow water.",
"flags": [ "PLANTABLE_SEED", "NUTRIENT_OVERRIDE", "INEDIBLE" ],
"seed_data": {
"plant_name": "cattail",
"fruit": "cattail_stalk",
"byproducts": [ "cattail_rhizome" ],
"grow": "91 days",
"required_terrain_flag": "SHALLOW_WATER"
}
},
{
"type": "COMESTIBLE",
Expand Down
5 changes: 4 additions & 1 deletion doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4034,9 +4034,12 @@ Every item type can have optional seed data, if the item has seed data, it's con
"fruit_div": 2, // (optional, default is 1). Final amount of fruit charges produced is divided by this number. Works only if fruit item is counted by charges.
"byproducts": ["withered", "straw_pile"], // A list of further items that should spawn upon harvest.
"plant_name": "sunflower", // The name of the plant that grows from this seed. This is only used as information displayed to the user.
"grow" : 91 // A time duration: how long it takes for a plant to fully mature. Based around a 91 day season length (roughly a real world season) to give better accuracy for longer season lengths
"grow" : 91, // A time duration: how long it takes for a plant to fully mature. Based around a 91 day season length (roughly a real world season) to give better accuracy for longer season lengths
// Note that growing time is later converted based upon the season_length option, basing it around 91 is just for accuracy purposes
// A value 91 means 3 full seasons, a value of 30 would mean 1 season.
"required_terrain_flag": "PLANTABLE" // A tag that terrain and furniture would need to have in order for the seed to be plantable there.
// Default is "PLANTABLE", and using this will cause any terain the plant is wrown on to turn into dirt once the plant is planted, unless furniture is used.
// Using any other tag will not turn the terrain into dirt.
}
```

Expand Down
6 changes: 4 additions & 2 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3217,10 +3217,12 @@ void activity_handlers::plant_seed_finish( player_activity *act, Character *you
}
used_seed.front().set_flag( json_flag_HIDDEN_ITEM );
here.add_item_or_charges( examp, used_seed.front() );
if( here.has_flag_furn( ter_furn_flag::TFLAG_PLANTABLE, examp ) ) {
if( here.has_flag_furn( seed_id->seed->required_terrain_flag, examp ) ) {
here.furn_set( examp, furn_str_id( here.furn( examp )->plant->transform ) );
} else {
} else if( seed_id->seed->required_terrain_flag == ter_furn_flag::TFLAG_PLANTABLE ) {
here.set( examp, t_dirt, f_plant_seed );
} else {
here.furn_set( examp, f_plant_seed );
}
you->add_msg_player_or_npc( _( "You plant some %s." ), _( "<npcname> plants some %s." ),
item::nname( seed_id ) );
Expand Down
13 changes: 8 additions & 5 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,9 @@ static activity_reason_info can_do_activity_there( const activity_id &act, Chara
} else if( act == ACT_MULTIPLE_FARM ) {
zones = mgr.get_zones( zone_type_FARM_PLOT, here.getglobal( src_loc ), _fac_id( you ) );
for( const zone_data &zone : zones ) {
const plot_options &options = dynamic_cast<const plot_options &>( zone.get_options() );
const itype_id seed = options.get_seed();

if( here.has_flag_furn( ter_furn_flag::TFLAG_GROWTH_HARVEST, src_loc ) ) {
map_stack items = here.i_at( src_loc );
const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
Expand All @@ -1309,15 +1312,13 @@ static activity_reason_info can_do_activity_there( const activity_id &act, Chara
// we need a shovel/hoe
return activity_reason_info::fail( do_activity_reason::NEEDS_TILLING );
}
} else if( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_PLANTABLE, src_loc ) &&
} else if( here.has_flag_ter_or_furn( seed->seed->required_terrain_flag, src_loc ) &&
// TODO: fix point types
warm_enough_to_plant( src_loc.raw() ) ) {
if( here.has_items( src_loc ) ) {
return activity_reason_info::fail( do_activity_reason::BLOCKING_TILE );
} else {
// do we have the required seed on our person?
const plot_options &options = dynamic_cast<const plot_options &>( zone.get_options() );
const itype_id seed = options.get_seed();
// If its a farm zone with no specified seed, and we've checked for tilling and harvesting.
// then it means no further work can be done here
if( seed.is_empty() ) {
Expand Down Expand Up @@ -2942,8 +2943,7 @@ static bool generic_multi_activity_do(
you.backlog.emplace_front( act_id );
you.activity.placement = src;
return false;
} else if( reason == do_activity_reason::NEEDS_PLANTING &&
here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_PLANTABLE, src_loc ) ) {
} else if( reason == do_activity_reason::NEEDS_PLANTING ) {
std::vector<zone_data> zones = mgr.get_zones( zone_type_FARM_PLOT, src, _fac_id( you ) );
for( const zone_data &zone : zones ) {
const itype_id seed =
Expand All @@ -2955,6 +2955,9 @@ static bool generic_multi_activity_do(
// move onto the next tile, and if need be that will prompt a fetch seeds activity.
continue;
}
if( !here.has_flag_ter_or_furn( seed->seed->required_terrain_flag, src_loc ) ) {
continue;
}
// TODO: fix point types
iexamine::plant_seed( you, src_loc.raw(), itype_id( seed ) );
you.backlog.emplace_front( act_id );
Expand Down
5 changes: 5 additions & 0 deletions src/iexamine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2558,6 +2558,11 @@ void iexamine::dirtmound( Character &you, const tripoint &examp )
}
const auto &seed_id = std::get<0>( seed_entries[seed_index] );

if( !here.has_flag_ter_or_furn( seed_id->seed->required_terrain_flag, examp ) ) {
add_msg( _( "This type of seed can not be planted in this location." ) );
return;
}

plant_seed( you, examp, seed_id );
}

Expand Down
2 changes: 2 additions & 0 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3369,6 +3369,8 @@ void islot_seed::load( const JsonObject &jo )
mandatory( jo, was_loaded, "fruit", fruit_id );
optional( jo, was_loaded, "seeds", spawn_seeds, true );
optional( jo, was_loaded, "byproducts", byproducts );
optional( jo, was_loaded, "required_terrain_flag", required_terrain_flag,
ter_furn_flag::TFLAG_PLANTABLE );
}

void islot_seed::deserialize( const JsonObject &jo )
Expand Down
6 changes: 5 additions & 1 deletion src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "game_constants.h"
#include "item_pocket.h"
#include "iuse.h" // use_function
#include "mapdata.h"
#include "proficiency.h"
#include "relic.h"
#include "stomach.h"
Expand Down Expand Up @@ -1065,7 +1066,10 @@ struct islot_seed {
* Additionally items (a list of their item ids) that will spawn when harvesting the plant.
*/
std::vector<itype_id> byproducts;

/**
* Terrain tag required to plant the seed.
*/
ter_furn_flag required_terrain_flag = ter_furn_flag::TFLAG_PLANTABLE;
islot_seed() = default;
};

Expand Down

0 comments on commit 43d4862

Please sign in to comment.