Skip to content

Commit 09f9bdc

Browse files
authored
Merge pull request #82978 from RenechCDDA/planting_window_search
More improvements to planting
2 parents fd182d1 + 73b162e commit 09f9bdc

File tree

5 files changed

+43
-12
lines changed

5 files changed

+43
-12
lines changed

doc/JSON/ITEM.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,7 @@ Gun mods can be defined like this:
982982
{ "GROWTH_HARVEST": "2 days" }, // will want at least 91 days (the length of winter) in between some stages. This example would overwinter in the GROWTH_MATURE form.
983983
{ "GROWTH_OVERGROWN": "1 hour" } // NOTE: GROWTH_OVERGROWN is optional, but if used should be a short duration. Or else it may fail to plant because the overgrown(dead) crops would not 'grow'!
984984
],
985+
"growth_temp": "7 C", // (optional, default 10 C). Celsius (C) or milli-Celsius(mC). Temperature required on the days this seed is planted and for every day with a growth stage. If below the required temperature it simply won't be plantable.
985986
"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.
986987
"required_terrain_flag": "PLANTABLE" // A tag that terrain and furniture would need to have in order for the seed to be plantable there.
987988
// 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.

src/item_factory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,6 +3440,7 @@ void islot_seed::deserialize( const JsonObject &jo )
34403440
mandatory( jo, was_loaded, "fruit", fruit_id );
34413441
mandatory( jo, was_loaded, "growth_stages", growth_stages,
34423442
pair_reader<flag_id, time_duration> {} );
3443+
optional( jo, was_loaded, "growth_temp", growth_temp, 10_C );
34433444
optional( jo, was_loaded, "seeds", spawn_seeds, true );
34443445
optional( jo, was_loaded, "byproducts", byproducts );
34453446
optional( jo, was_loaded, "required_terrain_flag", required_terrain_flag,

src/itype.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ const std::vector<std::pair<flag_id, time_duration>> &islot_seed::get_growth_sta
290290
return growth_stages;
291291
}
292292

293+
units::temperature islot_seed::get_growth_temp() const
294+
{
295+
return growth_temp;
296+
}
297+
293298
int islot_armor::avg_env_resist() const
294299
{
295300
int acc = 0;

src/itype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,11 +1192,14 @@ struct islot_seed {
11921192
islot_seed() = default;
11931193

11941194
const std::vector<std::pair<flag_id, time_duration>> &get_growth_stages() const;
1195+
units::temperature get_growth_temp() const;
11951196
private:
11961197
/**
11971198
* What stages of growth does this plant have? How long does each stage of growth last?
11981199
*/
11991200
std::vector<std::pair<flag_id, time_duration>> growth_stages;
1201+
// Temperature needs to be at or above this temp for the plant to be planted/grow.
1202+
units::temperature growth_temp;
12001203
};
12011204

12021205
enum condition_type {

src/weather.cpp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,28 @@ rl_vec2d convert_wind_to_coord( const int angle )
873873
return rl_vec2d( 0, 0 );
874874
}
875875

876+
static units::temperature highest_temp_on_day( time_point &base_date, const tripoint_abs_omt &pos,
877+
const weather_generator &weather_gen )
878+
{
879+
units::temperature highest_temp = 0_C;
880+
// we search a 24 hour period around the base_date, the base_date is exactly in the center
881+
const time_duration search_radius = 12_hours;
882+
// how long between each check. The performance on this shouldn't be a problem, but if we want more/less granularity this is a simple lever.
883+
const time_duration check_interval = 15_minutes;
884+
885+
// Iterate through the search window, checking temp each check_interval. Highest found value in the entire range is what ends up being returned.
886+
time_point check_date = base_date - search_radius;
887+
while( check_date <= base_date + search_radius ) {
888+
const w_point &w = weather_gen.get_weather( project_to<coords::ms>( pos ), check_date,
889+
g->get_seed() );
890+
const units::temperature checked_temp = w.temperature;
891+
highest_temp = std::max( highest_temp, checked_temp );
892+
check_date = check_date + check_interval;
893+
}
894+
895+
return highest_temp;
896+
}
897+
876898
bool warm_enough_to_plant( const tripoint_bub_ms &pos, const itype_id &it )
877899
{
878900
const tripoint_abs_ms abs = get_map().get_abs( pos );
@@ -883,29 +905,28 @@ bool warm_enough_to_plant( const tripoint_bub_ms &pos, const itype_id &it )
883905
bool warm_enough_to_plant( const tripoint_abs_omt &pos, const itype_id &it )
884906
{
885907
std::map<time_point, units::temperature> planting_times;
886-
// initialize the first...
887-
time_point check_date = calendar::turn;
888-
planting_times[check_date] = get_weather().get_area_temperature( pos );
889908
bool okay_to_plant = true;
890909
const std::vector<std::pair<flag_id, time_duration>> &growth_stages = it->seed->get_growth_stages();
891-
// and now iterate a copy of the weather into the future to see if they'll be plantable then as well.
910+
// we will iterate a copy of the weather into the future to see if they'll be plantable then as well.
892911
const weather_generator weather_gen = get_weather().get_cur_weather_gen();
912+
// initialize the first...
913+
time_point check_date = calendar::turn;
914+
planting_times[check_date] = highest_temp_on_day( check_date, pos, weather_gen );
893915
for( const auto &pair : growth_stages ) {
894916
// TODO: Replace epoch checks with data from a farmer's almanac
895917
check_date = check_date + pair.second;
896-
const w_point &w = weather_gen.get_weather( project_to<coords::ms>( pos ), check_date,
897-
g->get_seed() );
898-
planting_times[check_date] = w.temperature;
918+
planting_times[check_date] = highest_temp_on_day( check_date, pos, weather_gen );
899919
}
900920
for( const std::pair<const time_point, units::temperature> &pair : planting_times ) {
901921
// This absolutely needs to be a time point.
902922
add_msg_debug( debugmode::DF_MAP,
903-
"Checking plant time %s, temperature %s F",
923+
"Checking plant time %s, highest temperature %s…",
904924
//NOLINTNEXTLINE(cata-translations-in-debug-messages)
905-
to_string( pair.first ), units::to_fahrenheit( pair.second ) );
906-
// semi-appropriate temperature for most plants
907-
if( pair.second < units::from_fahrenheit( 50 ) ) {
908-
add_msg_debug( debugmode::DF_MAP, "Planting failure!" );
925+
to_string( pair.first ), print_temperature( pair.second, 2 ) );
926+
if( pair.second < it->seed->get_growth_temp() ) {
927+
add_msg_debug( debugmode::DF_MAP, "Planting failure! %s needs temperature of %s but found only %s",
928+
it->nname( 1 ), print_temperature( it->seed->get_growth_temp(), 2 ),
929+
print_temperature( pair.second, 2 ) );
909930
okay_to_plant = false;
910931
break;
911932
}

0 commit comments

Comments
 (0)