From 10568093c8e7c9a55f5659d024ac6d0eecf634a7 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 13 Jul 2018 12:47:37 +0300 Subject: [PATCH 01/35] Add temperature dependence to the plant grow time. --- src/map.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 05285a19414f3..aafe98db63a41 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -6832,17 +6832,33 @@ void map::grow_plant( const tripoint &p ) furn_set( p, f_null ); return; } + const time_duration plantEpoch = seed.get_plant_epoch(); + const time_point since = seed.birthday(); + const time_point until = calendar::turn; + const time_duration seed_age = get_crops_grow_since( since, until, p ); furn_id cur_furn = this->furn(p).id(); - if( seed.age() >= plantEpoch && cur_furn != furn_str_id( "f_plant_harvest" ) ){ - if( seed.age() < plantEpoch * 2 ) { + + // The plant have died + if( seed_age < 0 ) { + i_clear( p ); + furn_set( p, f_null ); + if( rng( 0, 1 ) > 0 ) { + spawn_item( p, "withered" ); + } + return; + } + + // Normal grow + if( seed_age >= plantEpoch && cur_furn != furn_str_id( "f_plant_harvest" ) ){ + if( seed_age < plantEpoch * 2 ) { if( cur_furn == furn_str_id( "f_plant_seedling" ) ){ return; } i_rem( p, 1 ); rotten_item_spawn( seed, p ); furn_set(p, furn_str_id( "f_plant_seedling" ) ); - } else if( seed.age() < plantEpoch * 3 ) { + } else if( seed_age < plantEpoch * 3 ) { if( cur_furn == furn_str_id( "f_plant_mature" ) ){ return; } From 29d3cdcffce6bcde83ff31876a13f76cdc75e0d4 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 13 Jul 2018 12:48:06 +0300 Subject: [PATCH 02/35] Add function to calculate effective plant grow time. --- src/weather.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/weather.h b/src/weather.h index 3bb512169f332..5c9627de1fbae 100644 --- a/src/weather.h +++ b/src/weather.h @@ -166,6 +166,13 @@ double funnel_charges_per_turn( double surface_area_mm2, double rain_depth_mm_pe */ time_duration get_rot_since( const time_point &start, const time_point &end, const tripoint &pos ); +/** + * Get effective grow time based on the temperature, similar to get_rot_since() above. + * Return negative value if the plant was frozen to death. + */ +time_duration get_crops_grow_since( const time_point &start, const time_point &end, + const tripoint &pos ); + /** * Is it warm enough to plant seeds? */ From 5e3372cc03721d8b5dc110639c5b086e378df90d Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 13 Jul 2018 12:48:59 +0300 Subject: [PATCH 03/35] Add function to calculate effective plant grow time. Change minimal planting temperature. --- src/weather.cpp | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/weather.cpp b/src/weather.cpp index 4ab24fb1ab6ac..6bcf545bc905a 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -91,6 +91,33 @@ time_duration get_rot_since( const time_point &start, const time_point &end, con return ret; } +time_duration get_crops_grow_since( const time_point &start, const time_point &end, + const tripoint &location ) +{ + time_duration eff_grow_time = 0; + if( location.z < 0 ) { + return 0; + } + const auto &wgen = g->get_cur_weather_gen(); + for( time_point i = start; i < end; i += 1_hours ) { + w_point w = wgen.get_weather( location, i, g->get_seed() ); + int temperature = w.temperature; + float temperature_coeff = 0.0f; + if( temperature > 70 ) { + temperature_coeff = 1.0f; + } else if( temperature > 32 ) { + temperature_coeff = ( temperature - 32 ) / 38.0f; + } else { + // Freezing can kill the plants + if( one_in( 20 ) ) { + return -1_turns; + } + } + eff_grow_time += 1_hours * temperature_coeff; + } + return eff_grow_time; +} + inline void proc_weather_sum( const weather_type wtype, weather_sum &data, const time_point &t, const time_duration &tick_size ) { @@ -538,13 +565,13 @@ static std::string print_time_just_hour( const time_point &p ) // MONDAY...MOSTLY SUNNY. HIGHS IN THE LOWER 60S. NORTHEAST WINDS 10 TO 15 MPH. // MONDAY NIGHT...PARTLY CLOUDY. LOWS AROUND 40. NORTHEAST WINDS 5 TO 10 MPH. -// 0% – No mention of precipitation -// 10% – No mention of precipitation, or isolated/slight chance -// 20% – Isolated/slight chance -// 30% – (Widely) scattered/chance -// 40% or 50% – Scattered/chance -// 60% or 70% – Numerous/likely -// 80%, 90% or 100% – No additional modifiers (i.e. "showers and thunderstorms") +// 0% – No mention of precipitation +// 10% – No mention of precipitation, or isolated/slight chance +// 20% – Isolated/slight chance +// 30% – (Widely) scattered/chance +// 40% or 50% – Scattered/chance +// 60% or 70% – Numerous/likely +// 80%, 90% or 100% – No additional modifiers (i.e. "showers and thunderstorms") /** * Generate textual weather forecast for the specified radio tower. */ @@ -728,7 +755,8 @@ int get_local_windpower(double windpower, const oter_id &omter, bool sheltered) } bool warm_enough_to_plant() { - return g->get_temperature( g-> u.pos() ) >= 50; // semi-appropriate temperature for most plants + // It is possible but not recommended to plant at the temperature of the ice melting + return g->get_temperature( g-> u.pos() ) >= 32; } ///@} From 46d2678eb2fff48e48962112835e00f1588b860c Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 13 Jul 2018 20:13:33 +0300 Subject: [PATCH 04/35] Add warm_enough_to_safe_plant() function. --- src/weather.cpp | 4 ++++ src/weather.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/weather.cpp b/src/weather.cpp index 6bcf545bc905a..4d57112b89fd7 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -759,4 +759,8 @@ bool warm_enough_to_plant() { return g->get_temperature( g-> u.pos() ) >= 32; } +bool warm_enough_to_safe_plant() { + return g->get_temperature( g-> u.pos() ) >= 50; +} + ///@} diff --git a/src/weather.h b/src/weather.h index 5c9627de1fbae..151aec2ec16c2 100644 --- a/src/weather.h +++ b/src/weather.h @@ -178,4 +178,9 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e */ bool warm_enough_to_plant(); +/** + * Is it (mostly) safe from night frost? Just a placeholder for now. + */ +bool warm_enough_to_safe_plant(); + #endif From 90e8c89ce7b050fdf5656ba56e6bde282e48751d Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 13 Jul 2018 20:15:12 +0300 Subject: [PATCH 05/35] Change menu header if it can be too cold. --- src/iexamine.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 878a85eb0fff7..a5492035d50a0 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1445,7 +1445,7 @@ void iexamine::flower_poppy(player &p, const tripoint &examp) auto recentWeather = sum_conditions( calendar::turn-10_minutes, calendar::turn, p.pos() ); - // If it has been raining recently, then this event is twice less likely. + // If it has been raining recently, then this event is twice less likely. if( ( ( recentWeather.rain_amount > 1 ) ? one_in( 6 ) : one_in( 3 ) ) && resist < 5 ) { // Should user player::infect, but can't! // player::infect needs to be restructured to return a bool indicating success. @@ -1720,7 +1720,11 @@ void iexamine::dirtmound(player &p, const tripoint &examp) // Don't use y/n prompt, stick with one kind of menu uimenu smenu; smenu.return_invalid = true; - smenu.text = _("Use which seed?"); + std::string planing_text = "Use which seed?"; + if( !warm_enough_to_safe_plant() ) { + planing_text = "Use which seed?. Plants can be damaged by cold weather."; + } + smenu.text = _( planing_text ); int count = 0; for( const auto &entry : seed_entries ) { smenu.addentry( count++, true, MENU_AUTOASSIGN, _("%s (%d)"), @@ -2017,10 +2021,10 @@ void iexamine::kiln_full(player &, const tripoint &examp) hours ), hours ); } else if( minutes > 30 ) { add_msg( _( "It will finish burning in less than an hour." ) ); - } else { + } else { add_msg( _("It should take about %d minutes to finish burning."), minutes ); - } - return; + } + return; } units::volume total_volume = 0; From 509a800eacbe307325863f1339c0dff669f4b2a1 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 14 Jul 2018 07:21:23 +0300 Subject: [PATCH 06/35] Add double spacing. --- src/iexamine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index a5492035d50a0..8216d1626027d 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1722,7 +1722,7 @@ void iexamine::dirtmound(player &p, const tripoint &examp) smenu.return_invalid = true; std::string planing_text = "Use which seed?"; if( !warm_enough_to_safe_plant() ) { - planing_text = "Use which seed?. Plants can be damaged by cold weather."; + planing_text = "Use which seed?. Plants can be damaged by cold weather."; } smenu.text = _( planing_text ); int count = 0; From 52b71952807c8d2d5efb6c6ebc62417462bbdbff Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 14 Jul 2018 16:26:16 +0300 Subject: [PATCH 07/35] Remove excessive period. --- src/iexamine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 8216d1626027d..ec7548841caa2 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1722,7 +1722,7 @@ void iexamine::dirtmound(player &p, const tripoint &examp) smenu.return_invalid = true; std::string planing_text = "Use which seed?"; if( !warm_enough_to_safe_plant() ) { - planing_text = "Use which seed?. Plants can be damaged by cold weather."; + planing_text = "Use which seed? Plants can be damaged by cold weather."; } smenu.text = _( planing_text ); int count = 0; From c94219f8d4baef51fa8d2eab942e3dd2701382b3 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Tue, 31 Jul 2018 13:31:23 +0300 Subject: [PATCH 08/35] Edit plant grow. --- src/iexamine.cpp | 266 +++++++++++++++++++++++++------------- src/iexamine.h | 4 +- src/item.cpp | 27 ++-- src/item.h | 4 + src/item_factory.cpp | 6 +- src/itype.h | 16 ++- src/map.cpp | 16 ++- src/mission_companion.cpp | 4 +- src/vehicle.cpp | 7 +- src/weather.cpp | 99 +++++++++++++- src/weather.h | 6 - 11 files changed, 320 insertions(+), 135 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index ec7548841caa2..fa3906b1555b2 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1698,16 +1698,20 @@ void iexamine::dirtmound(player &p, const tripoint &examp) } // Make lists of unique seed types and names for the menu(no multiple hemp seeds etc) - std::map seed_map; + std::map> seed_map; + std::vector seed_info; for( auto &seed : seed_inv ) { - seed_map[seed->typeId()] += (seed->charges > 0 ? seed->charges : 1); + int seed_count = ( seed->charges > 0 ? seed->charges : 1 ); + seed_info = { seed_count, seed->is_warm_enought() }; + seed_map.insert( std::pair>( seed->typeId() , seed_info ) ); } - using seed_tuple = std::tuple; + using seed_tuple = std::tuple>; std::vector seed_entries; for( const auto &pr : seed_map ) { + seed_info = pr.second; seed_entries.emplace_back( - pr.first, item::nname( pr.first, pr.second ), pr.second ); + pr.first, item::nname( pr.first, seed_info[0] ), pr.second ); } // Sort by name @@ -1720,15 +1724,22 @@ void iexamine::dirtmound(player &p, const tripoint &examp) // Don't use y/n prompt, stick with one kind of menu uimenu smenu; smenu.return_invalid = true; - std::string planing_text = "Use which seed?"; - if( !warm_enough_to_safe_plant() ) { - planing_text = "Use which seed? Plants can be damaged by cold weather."; - } - smenu.text = _( planing_text ); + smenu.text = _( "Use which seed? | Temperature" ); int count = 0; + std::string temp; for( const auto &entry : seed_entries ) { - smenu.addentry( count++, true, MENU_AUTOASSIGN, _("%s (%d)"), - std::get<1>( entry ).c_str(), std::get<2>( entry ) ); + itype_id seedid = std::get<1>( entry ); + seed_info = std::get<2>( entry ); + int seed_count = seed_info[0]; + + if( p.get_skill_level( skill_survival ) >= 2 ){ + temp = ( seed_info[1] ? _( "Comfortable" ) : _( "Too cold" ) ); + } else { + temp = _( "Looks fine" ); + } + + smenu.addentry( count++, true, MENU_AUTOASSIGN, ("%-20s (%s) | %s"), + std::get<1>( entry ).c_str(), seed_count, temp ); } smenu.query(); @@ -1749,6 +1760,10 @@ void iexamine::dirtmound(player &p, const tripoint &examp) used_seed = p.use_amount( seed_id, 1 ); } used_seed.front().set_age( 0 ); + used_seed.front().set_var( "health", 0 ); + used_seed.front().set_var( "water", 0 ); + used_seed.front().set_var( "fertilizer", 0 ); + used_seed.front().set_var( "weed", 0 ); g->m.add_item_or_charges( examp, used_seed.front() ); g->m.set( examp, t_dirt, f_plant_seed ); p.moves -= 500; @@ -1756,31 +1771,20 @@ void iexamine::dirtmound(player &p, const tripoint &examp) } /** - * Items that appear when a generic plant is harvested. Seed @ref islot_seed. - * @param type The seed type, must have a @ref itype::seed slot. - * @param plant_count Number of fruits to generate. For charge-based items, this - * specifies multiples of the default charge. - * @param seed_count Number of seeds to generate. - * @param byproducts If true, byproducts (like straw, withered plants, see - * @ref islot_seed::byproducts) are included. + * Items that appear when a generic plant is harvested. + * @param seed is used to get plant health and all products. */ -std::list iexamine::get_harvest_items( const itype &type, const int plant_count, - const int seed_count, const bool byproducts ) +std::list iexamine::get_harvest_items( item &seed ) { std::list result; - if( !type.seed ) { + if( !seed.is_seed() ) { return result; } - const islot_seed &seed_data = *type.seed; - // This is a temporary measure, itype should instead provide appropriate accessors - // to expose data about the seed item to allow harvesting to function. - const itype_id &seed_type = type.get_id(); const auto add = [&]( const itype_id &id, const int count ) { item new_item( id, calendar::turn ); if( new_item.count_by_charges() && count > 0 ) { new_item.charges *= count; - new_item.charges /= seed_data.fruit_div; if(new_item.charges <= 0) { new_item.charges = 1; } @@ -1790,16 +1794,31 @@ std::list iexamine::get_harvest_items( const itype &type, const int plant_ } }; - if( seed_data.spawn_seeds ) { - add( seed_type, seed_count ); - } + int health = seed.get_var( "health", 0 ); - add( seed_data.fruit_id, plant_count ); + // Multiplier for fruit yield. + // Should be in range (0, 2), equal to 1 if plant has default health (0). + const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + float fruit_multiplier = ( 3.0f * to_hours( seed_grow_time ) + health ) / ( 3.0f * to_hours( seed_grow_time ) ); + fruit_multiplier *= calendar::season_ratio(); + fruit_multiplier = std::max( fruit_multiplier, 0.0f ); - if( byproducts ) { - for( auto &b : seed_data.byproducts ) { - add( b, 1 ); - } + std::string fruit_id; + fruit_id = seed.type->seed->fruit_id; + int fruit_count = seed.type->seed->fruit_count; + fruit_count = roll_remainder( fruit_count * fruit_multiplier ); + add( fruit_id, fruit_count ); + + int seed_count = seed.type->seed->seed_count; + seed_count = roll_remainder( seed_count * fruit_multiplier ); + if( seed_count ) { + std::string seed_id; + seed_id = seed.type->seed->seed_id; + add( seed_id, seed_count ); + } + + for( auto &b : seed.type->seed->byproducts ) { + add( b, 1 ); } return result; @@ -1813,7 +1832,7 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) debugmsg( "Missing seed in plant furniture!" ); return; } - const item &seed = g->m.i_at( examp ).front(); + item &seed = g->m.i_at( examp ).front(); if( !seed.is_seed() ) { debugmsg( "The seed item %s is not a seed!", seed.tname().c_str() ); return; @@ -1844,79 +1863,142 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) add_msg(m_info, _("The seed blossoms into a flower-looking fungus.")); } } else { // Generic seed, use the seed item data - const itype &type = *seed.type; g->m.i_clear(examp); g->m.furn_set(examp, f_null); - int skillLevel = p.get_skill_level( skill_survival ); - ///\EFFECT_SURVIVAL increases number of plants harvested from a seed - int plantCount = rng(skillLevel / 2, skillLevel); - if (plantCount >= 12) { - plantCount = 12; - } else if( plantCount <= 0 ) { - plantCount = 1; - } - const int seedCount = std::max( 1l, rng( plantCount / 4, plantCount / 2 ) ); - for( auto &i : get_harvest_items( type, plantCount, seedCount, true ) ) { + for( auto &i : get_harvest_items( seed ) ) { g->m.add_item_or_charges( examp, i ); } p.moves -= 500; } } else if (g->m.furn(examp) != f_plant_harvest) { - if (g->m.i_at(examp).size() > 1) { - add_msg(m_info, _("This %s has already been fertilized."), pname.c_str() ); - return; - } - std::vector f_inv = p.all_items_with_flag( "FERTILIZER" ); - if( f_inv.empty() ) { - add_msg(m_info, _("You have no fertilizer for the %s."), pname.c_str()); - return; + int health = seed.get_var( "health", 0 ); + int water = seed.get_var( "water", 0 ); + int fertilizer = seed.get_var( "fertilizer", 0 ); + int weed = seed.get_var( "weed", 0 ); + + const time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); + int seed_age_days = to_days( seed_age ); + const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + int seed_grow_time_days = to_days( seed_grow_time ); + + uimenu pmenu; + pmenu.return_invalid = true; + + std::stringstream data; + // data << string_format( _( "Plant info - %-15s" ), pname ) << string_format( _( "Plant info - %-15s" ), pname ) << std::endl; + data << string_format( _( "%-15s" ), pname ) << std::endl; + // pmenu.text = data.str(); + pmenu.text = pname; + + //pmenu.text = _( "Plant info - %s", seedType ); + pmenu.addentry( 1, false, MENU_AUTOASSIGN, _("health %s"), health ); + pmenu.addentry( 2, false, MENU_AUTOASSIGN, _("grow %s / %s"), seed_age_days, seed_grow_time_days ); + pmenu.addentry( 3, true, MENU_AUTOASSIGN, _("water %s"), water ); + pmenu.addentry( 4, true, MENU_AUTOASSIGN, _("fertilizer %s"), fertilizer ); + pmenu.addentry( 5, true, MENU_AUTOASSIGN, _("weed %s"), weed ); + pmenu.query(); + + int action_index = pmenu.ret; + + // Watering + if( action_index == 3 ) { + const inventory &crafting_inv = p.crafting_inventory(); + int water_charges = crafting_inv.charges_of( "water" ); + if ( water_charges == 0) { + add_msg( _("You don't have water.")); + return; + } else if ( water > 400 ) { + add_msg( _("There is no need to water this plant.")); + return; + } else { + // Up to 50L of water can be used per plant + int water_use = std::min( water_charges * 5, ( 500 - water ) ); + water += water_use; + seed.set_var( "water", water ); + float water_used = water_use / 5.0f; + std::vector comps; + comps.push_back( item_comp( "water", std::max ( static_cast( water_used ), 1 ) ) ); + p.consume_items( comps ); + add_msg( _("You watered the plant.")); + p.moves -= 500; + return; + } } - if (query_yn(_("Fertilize the %s"), pname.c_str() )) { - std::vector f_types; - std::vector f_names; - for( auto &f : f_inv ) { - if( std::find( f_types.begin(), f_types.end(), f->typeId() ) == f_types.end() ) { - f_types.push_back( f->typeId() ); - f_names.push_back( f->tname() ); + + // Use fertilizer + if( action_index == 4 ) { + if ( water > 400 ){ + add_msg(_("There is no need to fertilize this plant.")); + return; + } else { + std::vector f_inv = p.all_items_with_flag( "FERTILIZER" ); + if( f_inv.empty() ) { + add_msg(m_info, _("You have no fertilizer for the %s."), pname.c_str()); + return; } - } - // Choose fertilizer from list - int f_index = 0; - if (f_types.size() > 1) { - f_names.push_back(_("Cancel")); - f_index = menu_vec(false, _("Use which fertilizer?"), f_names) - 1; - if (f_index == (int)f_names.size() - 1) { - f_index = -1; + + if (query_yn(_("Fertilize the %s"), pname.c_str() )) { + std::vector f_types; + std::vector f_names; + for( auto &f : f_inv ) { + if( std::find( f_types.begin(), f_types.end(), f->typeId() ) == f_types.end() ) { + f_types.push_back( f->typeId() ); + f_names.push_back( f->tname() ); + } + } + // Choose fertilizer from list + int f_index = 0; + if (f_types.size() > 1) { + f_names.push_back(_("Cancel")); + f_index = menu_vec(false, _("Use which fertilizer?"), f_names) - 1; + if (f_index == (int)f_names.size() - 1) { + f_index = -1; + } + } else { + f_index = 0; + } + if (f_index < 0) { + return; + } + std::list planted = p.use_charges( f_types[f_index], 1 ); + if (planted.empty()) { // nothing was removed from inv => weapon is the SEED + if (p.weapon.charges > 1) { + p.weapon.charges--; + } else { + p.remove_weapon(); + } + } + add_msg(_("You fertilized the plant.")); + p.moves -= 500; + const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + int seed_grow_time_hours = to_hours( seed_grow_time ); + seed.set_var( "fertilizer", fertilizer + seed_grow_time_hours ); } - } else { - f_index = 0; - } - if (f_index < 0) { return; } - std::list planted = p.use_charges( f_types[f_index], 1 ); - if (planted.empty()) { // nothing was removed from inv => weapon is the SEED - if (p.weapon.charges > 1) { - p.weapon.charges--; + } + + // Weed control + if( action_index == 5 ) { + if ( weed == 0 ){ + add_msg(_("There are no weeds here.")); + return; + } else { + p.moves -= 10 * weed; + int survival = p.get_skill_level( skill_survival ); + if( survival >= 2 ){ + seed.set_var( "weed", 0 ); + add_msg(_("You removed all weeds.")); } else { - p.remove_weapon(); + weed *= rng( survival * 50, 100 ) / 100.0f; + seed.set_var( "weed", weed ); + health -= rng( 0, 20 - survival * 10 ); + seed.set_var( "health", health ); + add_msg(_("You removed some weeds.")); } + return; } - // Reduce the amount of time it takes until the next stage of the plant by - // 20% of a seasons length. (default 2.8 days). - const time_duration fertilizerEpoch = calendar::season_length() * 0.2; - - item &seed = g->m.i_at( examp ).front(); - //@todo: item should probably clamp the value on its own - seed.set_birthday( std::max( calendar::time_of_cataclysm, seed.birthday() - fertilizerEpoch ) ); - // The plant furniture has the NOITEM token which prevents adding items on that square, - // spawned items are moved to an adjacent field instead, but the fertilizer token - // must be on the square of the plant, therefore this hack: - const auto old_furn = g->m.furn( examp ); - g->m.furn_set( examp, f_null ); - g->m.spawn_item( examp, "fertilizer", 1, 1, calendar::turn ); - g->m.furn_set( examp, old_furn ); } } } diff --git a/src/iexamine.h b/src/iexamine.h index 4c23e378f5d1c..d2fab310af300 100644 --- a/src/iexamine.h +++ b/src/iexamine.h @@ -106,8 +106,8 @@ bool pour_into_keg( const tripoint &pos, item &liquid ); bool has_keg( const tripoint &pos ); -std::list get_harvest_items( const itype &type, int plant_count, - int seed_count, bool byproducts ); +std::list get_harvest_items( item &seed ); + } //namespace iexamine using iexamine_function = void ( * )( player &, const tripoint & ); diff --git a/src/item.cpp b/src/item.cpp index 5b5315928ac22..44e6b842ed33a 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -896,7 +896,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, info.push_back( iteminfo( "FOOD", _( "Portions: " ), "", abs( int( food_item->charges ) * batch ) ) ); if( food_item->corpse != NULL && ( debug == true || ( g != NULL && ( g->u.has_bionic( bionic_id( "bio_scent_vision" ) ) || g->u.has_trait( trait_id( "CARNIVORE" ) ) || - g->u.has_artifact_with( AEP_SUPER_CLAIRVOYANCE ) ) ) ) + g->u.has_artifact_with( AEP_SUPER_CLAIRVOYANCE ) ) ) ) && parts->test(iteminfo_parts::FOOD_SMELL) ) { info.push_back( iteminfo( "FOOD", _( "Smells like: " ) + food_item->corpse->nname() ) ); } @@ -1133,7 +1133,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, info.push_back( iteminfo( "GUN", "sum_of_damage", _( " = " ), mod->gun_damage( true ).total_damage(), true, "", false, false, false ) ); } - + if (parts->test(iteminfo_parts::GUN_ARMORPIERCE)) info.push_back( iteminfo( "GUN", space + _( "Armor-pierce: " ), "", get_ranged_pierce( gun ), true, "", !has_ammo, false ) ); @@ -1149,7 +1149,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, get_ranged_pierce( gun ) + ammo_pierce, true, "", true, false, false ) ); } - + if (parts->test(iteminfo_parts::GUN_DISPERSION)) info.push_back( iteminfo( "GUN", _( "Dispersion: " ), "", mod->gun_dispersion( false ), true, "", !has_ammo, true ) ); @@ -1217,7 +1217,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, info.emplace_back( "GUN", _( "Recommended strength (burst): "), "", ceil( mod->type->weight / 333.0_gram ), true, "", true, true ); } - + if (parts->test(iteminfo_parts::GUN_RELOAD_TIME)) info.emplace_back( "GUN", _( "Reload time: " ), has_flag( "RELOAD_ONE" ) ? _( " seconds per round" ) : _( " seconds" ), @@ -1537,12 +1537,12 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, insert_separation_line(); info.push_back( iteminfo( "DESCRIPTION", recipe_line ) ); } - + if (recipe_list.size() != book.recipes.size() && parts->test(iteminfo_parts::DESCRIPTION_BOOK_ADDITIONAL_RECIPES)) { info.push_back(iteminfo("DESCRIPTION", _("It might help you figuring out some more recipes."))); } - + } else { if (parts->test(iteminfo_parts::BOOK_UNREAD)) info.push_back( iteminfo( "BOOK", @@ -1706,7 +1706,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, insert_separation_line(); if (parts->test(iteminfo_parts::DESCRIPTION_MELEEDMG)) info.push_back( iteminfo( "DESCRIPTION", string_format( _( "Average melee damage:" ) ) ) ); - if (parts->test(iteminfo_parts::DESCRIPTION_MELEEDMG_CRIT)) + if (parts->test(iteminfo_parts::DESCRIPTION_MELEEDMG_CRIT)) info.push_back( iteminfo( "DESCRIPTION", string_format( _( "Critical hit chance %d%% - %d%%" ), int( g->u.crit_chance( 0, 100, *this ) * 100 ), @@ -1770,7 +1770,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, info.emplace_back( "DESCRIPTION", _( "* This item is not repairable." ) ); } } - + if (parts->test(iteminfo_parts::DESCRIPTION_CONDUCTIVITY)) { if( !conductive () ) { info.push_back( iteminfo( "BASE", string_format( _( "* This item does not conduct electricity." ) ) ) ); @@ -1876,7 +1876,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, } // @todo: Unhide when enforcing limits - if( is_bionic() && g->u.has_trait( trait_id( "DEBUG_CBM_SLOTS" ) ) + if( is_bionic() && g->u.has_trait( trait_id( "DEBUG_CBM_SLOTS" ) ) && parts->test(iteminfo_parts::DESCRIPTION_CBM_SLOTS)) { info.push_back( iteminfo( "DESCRIPTION", list_occupied_bps( type->bionic->id, _( "This bionic is installed in the following body part(s):" ) ) ) ); @@ -1892,7 +1892,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, _( "* This mod obscures sights of the base weapon." ) ) ); } - if( has_flag( "LEAK_DAM" ) && has_flag( "RADIOACTIVE" ) && damage() > 0 + if( has_flag( "LEAK_DAM" ) && has_flag( "RADIOACTIVE" ) && damage() > 0 && parts->test(iteminfo_parts::DESCRIPTION_RADIOACTIVITY_DAMAGED)) { info.push_back( iteminfo( "DESCRIPTION", _( "* The casing of this item has cracked, revealing an ominous green glow." ) ) ); @@ -1953,7 +1953,7 @@ std::string item::info(std::vector &info, const iteminfo_query *parts, []( const itype *e ) { return e->nname( 1 ); } ) ); } - + if (parts->test(iteminfo_parts::DESCRIPTION_ACTIVATABLE_TRANSFORMATION)) { for( auto &u : type->use_methods ) { const auto tt = dynamic_cast( u.second.get_actor_ptr() ); @@ -6090,6 +6090,11 @@ std::string item::get_plant_name() const return type->seed->plant_name; } +bool item::is_warm_enought() const +{ + return temp_to_celsius( g->get_temperature( g-> u.pos() ) ) >= type->seed->comfortable_temperature; +} + bool item::is_dangerous() const { if( has_flag( "DANGEROUS" ) ) { diff --git a/src/item.h b/src/item.h index f41e43f393b1f..83a0fb30f5e64 100644 --- a/src/item.h +++ b/src/item.h @@ -1223,6 +1223,10 @@ class item : public visitable * translated. Returns an empty string for non-seed items. */ std::string get_plant_name() const; + /** + * Is temperature comfortable for this plant. + */ + bool is_warm_enought() const; /*@}*/ /** diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 9e961ac7632af..cfcef2e12137e 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1544,10 +1544,12 @@ void Item_factory::load_container( JsonObject &jo, const std::string &src ) void Item_factory::load( islot_seed &slot, JsonObject &jo, const std::string & ) { assign( jo, "grow", slot.grow, false, 1_days ); - slot.fruit_div = jo.get_int( "fruit_div", 1 ); slot.plant_name = _( jo.get_string( "plant_name" ).c_str() ); + slot.comfortable_temperature = jo.get_int( "comfortable_temperature", 0 ); slot.fruit_id = jo.get_string( "fruit" ); - slot.spawn_seeds = jo.get_bool( "seeds", true ); + slot.fruit_count = jo.get_int( "fruit_count", 10 ); + slot.seed_id = jo.get_string( "seed", slot.fruit_id ); + slot.seed_count = jo.get_int( "seed_count", 0 ); slot.byproducts = jo.get_string_array( "byproducts" ); } diff --git a/src/itype.h b/src/itype.h index 9337917543f42..9cef8e41a0886 100644 --- a/src/itype.h +++ b/src/itype.h @@ -620,9 +620,9 @@ struct islot_seed { */ time_duration grow = 0; /** - * Amount of harvested charges of fruits is divided by this number. + * Minimal comfortable temperature (in degree Celsius) */ - int fruit_div = 1; + int comfortable_temperature; /** * Name of the plant, already translated. */ @@ -632,9 +632,17 @@ struct islot_seed { */ std::string fruit_id; /** - * Whether to spawn seed items additionally to the fruit items. + * Average number of fruits per harvest. */ - bool spawn_seeds = true; + int fruit_count; + /** + * Type id of the seed item. + */ + std::string seed_id; + /** + * Average number of seeds per harvest. + */ + int seed_count; /** * Additionally items (a list of their item ids) that will spawn when harvesting the plant. */ diff --git a/src/map.cpp b/src/map.cpp index aafe98db63a41..9320add6cdd7d 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -6833,14 +6833,22 @@ void map::grow_plant( const tripoint &p ) return; } - const time_duration plantEpoch = seed.get_plant_epoch(); - const time_point since = seed.birthday(); + item &seed_item = i_at( p ).front(); + const time_point seed_bday = seed_item.birthday(); + time_duration seed_age = time_duration::from_turns( seed_item.get_var( "seed_age", 1 ) ); + + const time_duration plantEpoch = seed_item.get_plant_epoch(); + const time_point since = time_point::from_turn( seed_item.get_var( "last_grow_check", to_turn( seed_bday ) ) ); + const time_point until = calendar::turn; - const time_duration seed_age = get_crops_grow_since( since, until, p ); + seed_age += get_crops_grow_since( since, until, p ); + seed_item.set_var( "last_grow_check", to_turn( until ) ); + seed_item.set_var( "seed_age", to_turns( seed_age ) ); + furn_id cur_furn = this->furn(p).id(); // The plant have died - if( seed_age < 0 ) { + if( seed_item.get_var( "frozen", 0 ) > 0 ) { i_clear( p ); furn_set( p, f_null ); if( rng( 0, 1 ) > 0 ) { diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 8943189110d8e..e429265454e5c 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -930,7 +930,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) } tmp = item( seed_types[plant_index], calendar::turn ); const islot_seed &seed_data = *tmp.type->seed; - if( seed_data.spawn_seeds ){ + if( seed_data.seed_count > 0 ){ if( tmp.count_by_charges() ) { tmp.charges = 1; } @@ -1532,7 +1532,7 @@ std::vector talk_function::loot_building(const tripoint site) bay.collapse_at( p, false ); } //Smash easily breakable stuff - else if ((t == t_window || t == t_window_taped || t == t_window_domestic || + else if ((t == t_window || t == t_window_taped || t == t_window_domestic || t == t_window_boarded_noglass || t == t_window_domestic_taped || t == t_window_alarm_taped || t == t_window_boarded || t == t_curtains || t == t_window_alarm || diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 6311606ed7b81..50ddc1d8537a5 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -4077,14 +4077,12 @@ void vehicle::operate_reaper(){ const tripoint &veh_start = global_pos3(); for( const int reaper_id : all_parts_with_feature( "REAPER" ) ){ const tripoint reaper_pos = veh_start + parts[ reaper_id ].precalc[ 0 ]; - const int plant_produced = rng( 1, parts[ reaper_id ].info().bonus ); - const int seed_produced = rng( 1, 3 ); const units::volume max_pickup_volume = parts[ reaper_id ].info().size / 20; if( g->m.furn( reaper_pos ) != f_plant_harvest || !g->m.has_items( reaper_pos ) ) { continue; } - const item& seed = g->m.i_at( reaper_pos ).front(); + item& seed = g->m.i_at( reaper_pos ).front(); if( seed.typeId() == "fungal_seeds" || seed.typeId() == "marloss_seed" ) { // Otherworldly plants, the earth-made reaper can not handle those. @@ -4092,8 +4090,7 @@ void vehicle::operate_reaper(){ } g->m.furn_set( reaper_pos, f_null ); g->m.i_clear( reaper_pos ); - for( auto &i : iexamine::get_harvest_items( - *seed.type, plant_produced, seed_produced, false ) ) { + for( auto &i : iexamine::get_harvest_items( seed ) ) { g->m.add_item_or_charges( reaper_pos, i ); } sounds::sound( reaper_pos, rng( 10, 25 ), _("Swish") ); diff --git a/src/weather.cpp b/src/weather.cpp index 4d57112b89fd7..841bb04dc6c96 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -94,26 +94,114 @@ time_duration get_rot_since( const time_point &start, const time_point &end, con time_duration get_crops_grow_since( const time_point &start, const time_point &end, const tripoint &location ) { + item &seed = g->m.i_at( location ).front(); + int health = seed.get_var( "health", 0 ); + int water = seed.get_var( "water", 0 ); + int fertilizer = seed.get_var( "fertilizer", 0 ); + int weed = seed.get_var( "weed", 0 ); + + /* + 1L = 10 units of water + One plant tile will absorb 50 L/week ( 0.3 L/hour, 650 L/season ) + Precipitation is 300 L/season + Watering once per week is recommended for the best results + + Common IRL watering is 50L per week per square meter. + + Per season plant will have -2000 health without watering and -4300 health without watering and weed control + +4300 health is possible for the best conditions. + */ + int water_max = 500; + + // weeds will grow to max in 1 week ( 168 hours ) + int weed_max = 168; + time_duration eff_grow_time = 0; + if( location.z < 0 ) { return 0; } const auto &wgen = g->get_cur_weather_gen(); for( time_point i = start; i < end; i += 1_hours ) { w_point w = wgen.get_weather( location, i, g->get_seed() ); + weather_type wtype = wgen.get_weather_conditions( location, i, g->get_seed() ); + + // plant grow speed int temperature = w.temperature; float temperature_coeff = 0.0f; if( temperature > 70 ) { temperature_coeff = 1.0f; } else if( temperature > 32 ) { temperature_coeff = ( temperature - 32 ) / 38.0f; + } else if ( ( temperature < 23 ) && one_in( 20 ) ) { + // Freezing can kill the plant + seed.set_var( "frozen", 1 ); + return eff_grow_time; + } + eff_grow_time += 1_hours * temperature_coeff; + + // Low temperature damage the plant + if( !seed.is_warm_enought() ){ + health -= 1; + } + + // Absorb fertilizer + if( fertilizer > 0 ){ + fertilizer -= 1; + health += roll_remainder( 3.0f * temperature_coeff ); + } + + // Absorb water + water -= 3; + if ( water <= 0 ){ + health -= 1; + } + + // Precipitation was reduced 10 times to compensate rain frequency + switch( wtype ) { + case WEATHER_DRIZZLE: + water += 4; + break; + case WEATHER_RAINY: + case WEATHER_THUNDER: + case WEATHER_LIGHTNING: + water += 8; + break; + default: + break; + } + + // Air temperature above 80F(26C) increase water consumption + if( temperature > 80 ) { + water -= 5; + if ( water <= 0 ){ + health -= 1; + } + } + + // Grow weeds + if( weed == weed_max ){ + health -= 2; + fertilizer -= 2; + water -= 6; } else { - // Freezing can kill the plants - if( one_in( 20 ) ) { - return -1_turns; + weed += roll_remainder( 1.0f / calendar::season_ratio() ); + if( one_in( weed_max - weed) ){ + health -= 1; + fertilizer -= 1; + water -= 3; } } - eff_grow_time += 1_hours * temperature_coeff; + + water = std::max( water , -water_max ); + water = std::min( water , water_max ); + fertilizer = std::max( fertilizer , 0 ); + weed = std::min( weed , weed_max ); + + seed.set_var( "health", health ); + seed.set_var( "water", water ); + seed.set_var( "fertilizer", fertilizer ); + seed.set_var( "weed", weed ); } return eff_grow_time; } @@ -759,8 +847,5 @@ bool warm_enough_to_plant() { return g->get_temperature( g-> u.pos() ) >= 32; } -bool warm_enough_to_safe_plant() { - return g->get_temperature( g-> u.pos() ) >= 50; -} ///@} diff --git a/src/weather.h b/src/weather.h index 151aec2ec16c2..be097d222be7e 100644 --- a/src/weather.h +++ b/src/weather.h @@ -168,7 +168,6 @@ time_duration get_rot_since( const time_point &start, const time_point &end, con /** * Get effective grow time based on the temperature, similar to get_rot_since() above. - * Return negative value if the plant was frozen to death. */ time_duration get_crops_grow_since( const time_point &start, const time_point &end, const tripoint &pos ); @@ -178,9 +177,4 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e */ bool warm_enough_to_plant(); -/** - * Is it (mostly) safe from night frost? Just a placeholder for now. - */ -bool warm_enough_to_safe_plant(); - #endif From 0182edb6a150dd322a15e3da8245d23a2c7516e9 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Tue, 31 Jul 2018 14:10:43 +0300 Subject: [PATCH 09/35] Edit seeds info. --- data/json/items/comestibles/seed.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index c5073c2c93700..84759de2541e6 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -253,7 +253,7 @@ "name_plural": "chili pepper seeds", "color": "white", "description": "Some chili pepper seeds.", - "seed_data": { "plant_name": "chili pepper", "fruit": "chili_pepper", "byproducts": [ "withered" ], "grow": 65 } + "seed_data": { "plant_name": "chili pepper", "fruit": "chili_pepper", "comfortable_temperature": 10, "byproducts": [ "withered" ], "grow": 65 } }, { "type": "COMESTIBLE", @@ -275,7 +275,7 @@ "description": "A raw potato, cut into pieces, separating each bud for planting.", "weight": 20, "stack_size": 10, - "seed_data": { "plant_name": "potatoes", "fruit": "potato_raw", "byproducts": [ "withered" ], "grow": 95 } + "seed_data": { "plant_name": "potatoes", "fruit": "potato_raw", "fruit_count": 10, "byproducts": [ "withered" ], "grow": 95 } }, { "type": "COMESTIBLE", From 9dba40fd5978389622ff85f050d5bb3be34d105f Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Tue, 31 Jul 2018 15:43:57 +0300 Subject: [PATCH 10/35] Add "water requirement" and "weed susceptibility" plant parameters. --- src/item_factory.cpp | 2 ++ src/itype.h | 8 ++++++++ src/weather.cpp | 11 +++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/item_factory.cpp b/src/item_factory.cpp index cfcef2e12137e..010207d1a52ad 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1551,6 +1551,8 @@ void Item_factory::load( islot_seed &slot, JsonObject &jo, const std::string & ) slot.seed_id = jo.get_string( "seed", slot.fruit_id ); slot.seed_count = jo.get_int( "seed_count", 0 ); slot.byproducts = jo.get_string_array( "byproducts" ); + slot.water_requirement = jo.get_float( "water_requirement", 1.0f ); + slot.weed_susceptibility = jo.get_float( "weed_susceptibility", 1.0f ); } void Item_factory::load( islot_container &slot, JsonObject &jo, const std::string & ) diff --git a/src/itype.h b/src/itype.h index 9cef8e41a0886..09bda91406aed 100644 --- a/src/itype.h +++ b/src/itype.h @@ -643,6 +643,14 @@ struct islot_seed { * Average number of seeds per harvest. */ int seed_count; + /** + * Relative water requirement. + */ + float water_requirement; + /** + * Relative weed susceptibility. + */ + float weed_susceptibility; /** * Additionally items (a list of their item ids) that will spawn when harvesting the plant. */ diff --git a/src/weather.cpp b/src/weather.cpp index 841bb04dc6c96..084b3c6f4b919 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -17,6 +17,7 @@ #include "sounds.h" #include "cata_utility.h" #include "player.h" +#include "itype.h" #include #include @@ -99,6 +100,8 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); int weed = seed.get_var( "weed", 0 ); + float water_requirement = seed.type->seed->water_requirement; + float weed_susceptibility = seed.type->seed->weed_susceptibility; /* 1L = 10 units of water @@ -152,7 +155,7 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e } // Absorb water - water -= 3; + water -= roll_remainder( 3.0f * water_requirement ) ; if ( water <= 0 ){ health -= 1; } @@ -173,7 +176,7 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e // Air temperature above 80F(26C) increase water consumption if( temperature > 80 ) { - water -= 5; + water -= roll_remainder( 5.0f * water_requirement ) ; if ( water <= 0 ){ health -= 1; } @@ -181,13 +184,13 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e // Grow weeds if( weed == weed_max ){ - health -= 2; + health -= roll_remainder( 2.0f * weed_susceptibility ) ; fertilizer -= 2; water -= 6; } else { weed += roll_remainder( 1.0f / calendar::season_ratio() ); if( one_in( weed_max - weed) ){ - health -= 1; + health -= roll_remainder( 1.0f * weed_susceptibility ) ; fertilizer -= 1; water -= 3; } From 7ffece979a17c9644f132fcc9e1b76462fe4882e Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 12:59:16 +0300 Subject: [PATCH 11/35] Add mushrooms and shrubs. --- data/json/furniture.json | 120 +++++++++++++++++++++++++++++++++++++++ src/mapdata.cpp | 12 ++++ src/mapdata.h | 6 +- 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/data/json/furniture.json b/data/json/furniture.json index 3ba0b5515cffb..92ab8d4bd880d 100644 --- a/data/json/furniture.json +++ b/data/json/furniture.json @@ -1798,6 +1798,126 @@ "sound": "crunch.", "sound_fail": "whish." } + },{ + "type" : "furniture", + "id" : "f_mushroom_seed", + "name": "starting mushroom bed", + "symbol": "^", + "color": "white", + "move_cost_mod": 0, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "examine_action": "aggie_plant" + },{ + "type" : "furniture", + "id" : "f_mushroom_seedling", + "name": "weak mushroom bed", + "symbol": "#", + "color": "white", + "move_cost_mod": 0, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "examine_action": "aggie_plant" + },{ + "type" : "furniture", + "id" : "f_mushroom_mature", + "name": "mature mushroom bed", + "symbol": "#", + "color": "white", + "move_cost_mod": 0, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "examine_action": "aggie_plant" + },{ + "type" : "furniture", + "id" : "f_mushroom_mature_harvest", + "name": "mushroom bed with grown mushrooms", + "symbol": "#", + "color": "white", + "move_cost_mod": 0, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "examine_action": "aggie_plant" + },{ + "type" : "furniture", + "id" : "f_shrub_blueberry", + "name": "blueberry bush", + "symbol": "#", + "color": "blue_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_blueberry_harvest", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_blueberry_harvest", + "name": "blueberry bush_harvest", + "symbol": "#", + "color": "light_blue_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_blueberry", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_strawberry", + "name": "strawberry bush", + "symbol": "#", + "color": "red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_strawberry_harvest", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_strawberry_harvest", + "name": "strawberry bush_harvest", + "symbol": "#", + "color": "light_red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_strawberry", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } },{ "type" : "furniture", "id" : "f_fvat_empty", diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 945a8bc675722..07be87776a7ea 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -831,6 +831,9 @@ furn_id f_null, f_mutpoppy, f_flower_fungal, f_fungal_mass, f_fungal_clump,f_dahlia,f_datura,f_dandelion,f_cattails,f_bluebell, f_safe_c, f_safe_l, f_safe_o, f_plant_seed, f_plant_seedling, f_plant_mature, f_plant_harvest, + f_mushroom_seed, f_mushroom_seedling, f_mushroom_mature, f_mushroom_mature_harvest, + f_shrub_blueberry, f_shrub_blueberry_harvest, + f_shrub_strawberry, f_shrub_strawberry_harvest, f_fvat_empty, f_fvat_full, f_wood_keg, f_standing_tank, @@ -924,6 +927,14 @@ void set_furn_ids() { f_plant_seedling = furn_id( "f_plant_seedling" ); f_plant_mature = furn_id( "f_plant_mature" ); f_plant_harvest = furn_id( "f_plant_harvest" ); + f_mushroom_seed = furn_id( "f_mushroom_seed" ); + f_mushroom_seedling = furn_id( "f_mushroom_seedling" ); + f_mushroom_mature = furn_id( "f_mushroom_mature" ); + f_mushroom_mature_harvest = furn_id( "f_mushroom_mature_harvest" ); + f_shrub_blueberry = furn_id( "f_shrub_blueberry" ); + f_shrub_blueberry_harvest = furn_id( "f_shrub_blueberry_harvest" ); + f_shrub_strawberry = furn_id( "f_shrub_strawberry" ); + f_shrub_strawberry_harvest = furn_id( "f_shrub_strawberry_harvest" ); f_fvat_empty = furn_id( "f_fvat_empty" ); f_fvat_full = furn_id( "f_fvat_full" ); f_wood_keg = furn_id( "f_wood_keg" ); @@ -1108,6 +1119,7 @@ void furn_t::load( JsonObject &jo, const std::string &src ) optional( jo, was_loaded, "max_volume", max_volume, legacy_volume_reader, DEFAULT_MAX_VOLUME_IN_SQUARE ); optional( jo, was_loaded, "crafting_pseudo_item", crafting_pseudo_item, "" ); optional( jo, was_loaded, "deployed_item", deployed_item ); + optional( jo, was_loaded, "transforms_into", transforms_into, furn_str_id::NULL_ID() ); load_symbol( jo ); transparent = false; diff --git a/src/mapdata.h b/src/mapdata.h index e78bf6baea900..f691f7955ea38 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -187,7 +187,7 @@ enum ter_connects : int { struct map_data_common_t { map_bash_info bash; map_deconstruct_info deconstruct; - + public: virtual ~map_data_common_t() = default; @@ -307,6 +307,7 @@ struct furn_t : map_data_common_t { furn_str_id close; // Close action: transform into furniture with matching id std::string crafting_pseudo_item; itype_id deployed_item; // item id string used to create furniture + furn_str_id transforms_into; // Transform into what furniture? int move_str_req; //The amount of strength required to move through this furniture easily. @@ -468,6 +469,9 @@ extern furn_id f_null, f_mutpoppy, f_flower_fungal, f_fungal_mass, f_fungal_clump, f_safe_c, f_safe_l, f_safe_o, f_plant_seed, f_plant_seedling, f_plant_mature, f_plant_harvest, + f_mushroom_seed, f_mushroom_seedling, f_mushroom_mature, f_mushroom_mature_harvest, + f_shrub_blueberry, f_shrub_blueberry_harvest, + f_shrub_strawberry, f_shrub_strawberry_harvest, f_fvat_empty, f_fvat_full, f_wood_keg, f_standing_tank, From 5efb79bd63f753d1c8263d000f06dd3ebf407439 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:00:31 +0300 Subject: [PATCH 12/35] Add carrot and sugar beet. --- data/json/recipes/food/seed.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/data/json/recipes/food/seed.json b/data/json/recipes/food/seed.json index 886e4870e3b7a..851af0a65abea 100644 --- a/data/json/recipes/food/seed.json +++ b/data/json/recipes/food/seed.json @@ -336,5 +336,29 @@ "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "potato_raw", 1 ] ] ] + }, + { + "result": "seed_carrot_raw", + "type": "recipe", + "category": "CC_FOOD", + "subcategory": "CSC_FOOD_SEEDS", + "skill_used": "survival", + "difficulty": 2, + "time": 5000, + "autolearn": true, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "carrot", 1 ] ] ] + }, + { + "result": "seed_sugar_beet_raw", + "type": "recipe", + "category": "CC_FOOD", + "subcategory": "CSC_FOOD_SEEDS", + "skill_used": "survival", + "difficulty": 2, + "time": 5000, + "autolearn": true, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "sugar_beet", 1 ] ] ] } ] From 88d54c4bb0002ad83aa38f74086212fa32900a56 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:01:12 +0300 Subject: [PATCH 13/35] Remove charges from pumpkin. --- data/json/items/comestibles.json | 1 - 1 file changed, 1 deletion(-) diff --git a/data/json/items/comestibles.json b/data/json/items/comestibles.json index c0c7e4fb7e290..36f519dd6c621 100644 --- a/data/json/items/comestibles.json +++ b/data/json/items/comestibles.json @@ -6217,7 +6217,6 @@ "price": 750, "material": "veggy", "volume": 12, - "charges": 8, "bashing": 2, "fun": -1, "rot_spawn": "GROUP_ROTTING_PLANT" From d78a0be1630bd6eeb43e5143f878e87bf0693804 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:01:55 +0300 Subject: [PATCH 14/35] Edit seed data. --- data/json/items/comestibles/seed.json | 127 ++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 7 deletions(-) diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index 29c30795ac8ea..543f40b2043aa 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -50,7 +50,15 @@ "name": "blueberry seeds", "name_plural": "blueberry seeds", "description": "Some blueberry seeds.", - "seed_data": { "plant_name": "blueberry", "fruit": "blueberries", "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { + "plant_name": "blueberry", + "fruit": "blueberries", + "fruit_count": 5, + "grow": 91, + "grow_secondary": 45, + "is_shrub": true, + "grow_into": "f_shrub_blueberry_harvest" + } }, { "id": "seed_cranberries", @@ -90,7 +98,15 @@ "name": "strawberry seeds", "name_plural": "strawberry seeds", "description": "Some strawberry seeds.", - "seed_data": { "plant_name": "strawberry", "fruit": "strawberries", "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { + "plant_name": "strawberry", + "fruit": "strawberries", + "fruit_count": 5, + "grow": 91, + "grow_secondary": 45, + "is_shrub": true, + "grow_into": "f_shrub_strawberry_harvest" + } }, { "type": "COMESTIBLE", @@ -118,6 +134,27 @@ "stack_size": 40, "seed_data": { "plant_name": "sugar beet", "fruit": "sugar_beet", "grow": 90 } }, + { + "type": "COMESTIBLE", + "id": "seed_sugar_beet_raw", + "copy-from": "seed", + "price": 120, + "name": "sugar beet seeds", + "name_plural": "sugar beet seeds", + "description": "Some sugar beet seeds.", + "volume": 1, + "weight": 310, + "stack_size": 10, + "charges": 1, + "seed_data": { + "plant_name": "sugar beet", + "fruit": "sugar_beet", + "fruit_count": 0, + "seed": "sugar_beet", + "seed_count": 5, + "grow": 90 + } + }, { "type": "COMESTIBLE", "id": "seed_lettuce", @@ -234,6 +271,28 @@ "description": "Some carrot seeds.", "seed_data": { "plant_name": "carrot", "fruit": "carrot", "byproducts": [ "withered" ], "grow": 65 } }, + { + "type": "COMESTIBLE", + "id": "seed_carrot_raw", + "copy-from": "seed", + "price": 50, + "name": "seed carrot", + "name_plural": "seed carrots", + "description": "A raw carrot prepared for planting.", + "weight": 80, + "volume": 1, + "stack_size": 10, + "charges": 1, + "seed_data": { + "plant_name": "carrot", + "fruit": "carrot", + "fruit_count": 0, + "seed": "seed_carrot", + "seed_count": 5, + "byproducts": [ "withered" ], + "grow": 65 + } + }, { "type": "COMESTIBLE", "id": "seed_corn", @@ -265,6 +324,24 @@ "description": "Some cucumber seeds.", "seed_data": { "plant_name": "cucumber", "fruit": "cucumber", "byproducts": [ "withered" ], "grow": 60 } }, + { + "type": "COMESTIBLE", + "id": "seed_potato", + "copy-from": "seed", + "price": 50, + "name": "potato seed", + "name_plural": "potato seeds", + "description": "Some potato seeds.", + "seed_data": { + "plant_name": "potatoes", + "fruit": "potato_raw", + "fruit_count": 10, + "seed": "seed_potato", + "seed_count": 5, + "byproducts": [ "withered" ], + "grow": 95 + } + }, { "type": "COMESTIBLE", "id": "seed_potato_raw", @@ -275,7 +352,15 @@ "description": "A raw potato, cut into pieces, separating each bud for planting.", "weight": 20, "stack_size": 10, - "seed_data": { "plant_name": "potatoes", "fruit": "potato_raw", "fruit_count": 10, "byproducts": [ "withered" ], "grow": 95 } + "seed_data": { + "plant_name": "potatoes", + "fruit": "potato_raw", + "fruit_count": 10, + "seed": "seed_potato", + "seed_count": 5, + "byproducts": [ "withered" ], + "grow": 95 + } }, { "type": "COMESTIBLE", @@ -493,7 +578,14 @@ "copy-from": "seed_mushroom_base", "name": "mushroom spores", "name_plural": "mushroom spores", - "seed_data": { "plant_name": "mushroom", "fruit": "mushroom", "grow": 91 } + "seed_data": { + "plant_name": "mushroom", + "is_mushroom": true, + "fruit": "mushroom", + "fruit_count": 2, + "grow": 45, + "grow_secondary": 10 + } }, { "type": "COMESTIBLE", @@ -502,7 +594,14 @@ "name": "morel mushroom spores", "name_plural": "morel mushroom spores", "description": "Some morel mushroom spores. You could probably plant these.", - "seed_data": { "plant_name": "morel mushroom", "fruit": "mushroom_morel", "grow": 91 } + "seed_data": { + "plant_name": "morel mushroom", + "is_mushroom": true, + "fruit": "mushroom_morel", + "fruit_count": 2, + "grow": 45, + "grow_secondary": 10 + } }, { "type": "COMESTIBLE", @@ -511,7 +610,14 @@ "name": "mushroom spores", "name_plural": "mushroom spores", "flags": "HIDDEN_HALLU", - "seed_data": { "plant_name": "mushroom", "fruit": "mushroom_magic", "grow": 91 } + "seed_data": { + "plant_name": "mushroom", + "is_mushroom": true, + "fruit": "mushroom_magic", + "fruit_count": 2, + "grow": 45, + "grow_secondary": 10 + } }, { "type": "COMESTIBLE", @@ -520,7 +626,14 @@ "name": "mushroom spores", "name_plural": "mushroom spores", "flags": "HIDDEN_POISON", - "seed_data": { "plant_name": "mushroom", "fruit": "mushroom_poison", "grow": 91 } + "seed_data": { + "plant_name": "mushroom", + "is_mushroom": true, + "fruit": "mushroom_poison", + "fruit_count": 2, + "grow": 45, + "grow_secondary": 10 + } }, { "id": "datura_seed", From 85ada5bd6fd79b2019fc0de48f9d4bc826999984 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:03:07 +0300 Subject: [PATCH 15/35] Add more seed parameters. --- src/item_factory.cpp | 4 ++++ src/itype.h | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/item_factory.cpp b/src/item_factory.cpp index f8475ad84d24d..9c782a93951df 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1569,6 +1569,7 @@ void Item_factory::load_container( JsonObject &jo, const std::string &src ) void Item_factory::load( islot_seed &slot, JsonObject &jo, const std::string & ) { assign( jo, "grow", slot.grow, false, 1_days ); + assign( jo, "grow_secondary", slot.grow_secondary, false, 1_days ); slot.plant_name = _( jo.get_string( "plant_name" ).c_str() ); slot.comfortable_temperature = jo.get_int( "comfortable_temperature", 0 ); slot.fruit_id = jo.get_string( "fruit" ); @@ -1578,6 +1579,9 @@ void Item_factory::load( islot_seed &slot, JsonObject &jo, const std::string & ) slot.byproducts = jo.get_string_array( "byproducts" ); slot.water_requirement = jo.get_float( "water_requirement", 1.0f ); slot.weed_susceptibility = jo.get_float( "weed_susceptibility", 1.0f ); + slot.grow_into = jo.get_string( "grow_into", "" ); + slot.is_mushroom = jo.get_bool( "is_mushroom", false ); + slot.is_shrub = jo.get_bool( "is_shrub", false ); } void Item_factory::load( islot_container &slot, JsonObject &jo, const std::string & ) diff --git a/src/itype.h b/src/itype.h index 286762e730bfd..9316fa9ca5470 100644 --- a/src/itype.h +++ b/src/itype.h @@ -620,6 +620,10 @@ struct islot_seed { * Time it takes for a seed to grow (based of off a season length of 91 days). */ time_duration grow = 0; + /** + * Time it takes for a perennial plant to grow fruits (based of off a season length of 91 days). + */ + time_duration grow_secondary = 0; /** * Minimal comfortable temperature (in degree Celsius) */ @@ -652,10 +656,22 @@ struct islot_seed { * Relative weed susceptibility. */ float weed_susceptibility; + /** + * ID of the shrub this plant will grow into. + */ + std::string grow_into; /** * Additionally items (a list of their item ids) that will spawn when harvesting the plant. */ std::vector byproducts; + /** + * Is this plant a mushroom. + */ + bool is_mushroom; + /** + * Will this plant grow into a berry shrub. + */ + bool is_shrub; islot_seed() { } }; From 15748497aaf6e0087af31d7864dc8fb03c873bc1 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:05:10 +0300 Subject: [PATCH 16/35] Edit plant processing. --- src/iexamine.h | 2 + src/map.cpp | 59 +++++++++++++++++++++----- src/map.h | 2 + src/weather.cpp | 109 +++++++++++++++++++++++++++++++----------------- 4 files changed, 124 insertions(+), 48 deletions(-) diff --git a/src/iexamine.h b/src/iexamine.h index d2fab310af300..beb722b35ba93 100644 --- a/src/iexamine.h +++ b/src/iexamine.h @@ -107,6 +107,8 @@ bool has_keg( const tripoint &pos ); std::list get_harvest_items( item &seed ); +void proceed_plant_after_harvest( const int x, const int y, const int z ); +void proceed_plant_after_harvest( const tripoint &examp ); } //namespace iexamine diff --git a/src/map.cpp b/src/map.cpp index be27edb37c4e5..5f29e68a6fba1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1450,9 +1450,10 @@ void map::furn_set(const int x, const int y, const furn_id new_furniture) furn_set( tripoint( x, y, abs_sub.z ), new_furniture ); } -std::string map::furnname(const int x, const int y) { - return furnname( tripoint( x, y, abs_sub.z ) ); +furn_id map::get_furn_transforms_into( const tripoint &p ) const { + return furn( p ).obj().transforms_into.id(); } + // End of 2D overloads for furniture void map::set( const tripoint &p, const ter_id new_terrain, const furn_id new_furniture) @@ -6838,7 +6839,8 @@ void map::grow_plant( const tripoint &p ) time_duration seed_age = time_duration::from_turns( seed_item.get_var( "seed_age", 1 ) ); const time_duration plantEpoch = seed_item.get_plant_epoch(); - const time_point since = time_point::from_turn( seed_item.get_var( "last_grow_check", to_turn( seed_bday ) ) ); + const time_point since = time_point::from_turn( seed_item.get_var( "last_grow_check", + to_turn( seed_bday ) ) ); const time_point until = calendar::turn; seed_age += get_crops_grow_since( since, until, p ); @@ -6857,33 +6859,63 @@ void map::grow_plant( const tripoint &p ) return; } - // Normal grow - if( seed_age >= plantEpoch && cur_furn != furn_str_id( "f_plant_harvest" ) ){ + if( seed_item.type->seed->is_mushroom ) { + // Mushroom bed grow + if( cur_furn != furn_str_id( "f_mushroom_mature" ) && + cur_furn != furn_str_id( "f_mushroom_mature_harvest" ) ) { + if( seed_age >= plantEpoch && seed_age < plantEpoch * 3 ) { + furn_set(p, furn_str_id( "f_mushroom_seedling" ) ); + } else if( seed_age >= plantEpoch * 3 ) { + seed_item.set_birthday( until ); + furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); + seed_item.set_var( "is_mature", 1 ); + } + } + // Mushrooms grow on beds + if( cur_furn == furn_str_id( "f_mushroom_mature" ) && + seed_age > ( seed_item.type->seed->grow_secondary * calendar::season_ratio() ) ){ + seed_item.set_var( "can_be_harvested", 1 ); + furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); + } + return; + } + + // Grow berries on shrubs + if( seed_item.type->seed->is_shrub && seed_item.get_var( "is_mature", 0 ) && + seed_age > seed_item.type->seed->grow_secondary * calendar::season_ratio() ) { + seed_item.set_var( "can_be_harvested", 1 ); + const auto &furn_obj = this->furn( p ).obj(); + furn_set( p, furn_obj.transforms_into ); + return; + } + + // Normal plant grow + if( seed_age >= plantEpoch && cur_furn != furn_str_id( "f_plant_harvest" ) ) { if( seed_age < plantEpoch * 2 ) { - if( cur_furn == furn_str_id( "f_plant_seedling" ) ){ + if( cur_furn == furn_str_id( "f_plant_seedling" ) ) { return; } i_rem( p, 1 ); rotten_item_spawn( seed, p ); furn_set(p, furn_str_id( "f_plant_seedling" ) ); } else if( seed_age < plantEpoch * 3 ) { - if( cur_furn == furn_str_id( "f_plant_mature" ) ){ + if( cur_furn == furn_str_id( "f_plant_mature" ) ) { return; } i_rem(p, 1); rotten_item_spawn( seed, p ); //You've skipped the seedling stage so roll monsters twice - if( cur_furn != furn_str_id( "f_plant_seedling" ) ){ + if( cur_furn != furn_str_id( "f_plant_seedling" ) ) { rotten_item_spawn( seed, p ); } furn_set( p, furn_str_id( "f_plant_mature" ) ); } else { //You've skipped two stages so roll monsters two times - if( cur_furn == furn_str_id( "f_plant_seedling" ) ){ + if( cur_furn == furn_str_id( "f_plant_seedling" ) ) { rotten_item_spawn( seed, p ); rotten_item_spawn( seed, p ); //One stage change - } else if( cur_furn == furn_str_id( "f_plant_mature" ) ){ + } else if( cur_furn == furn_str_id( "f_plant_mature" ) ) { rotten_item_spawn( seed, p ); //Goes from seed to harvest in one check } else { @@ -6891,6 +6923,13 @@ void map::grow_plant( const tripoint &p ) rotten_item_spawn( seed, p ); rotten_item_spawn( seed, p ); } + // Plant grow into shrub + if ( seed_item.type->seed->is_shrub ) { + furn_set( p, furn_str_id( seed_item.type->seed->grow_into ) ); + seed_item.set_var( "is_mature", 1 ); + return; + } + i_clear( p ); furn_set(p, furn_str_id( "f_plant_harvest" ) ); } } diff --git a/src/map.h b/src/map.h index d7096384e01ae..5effe015f738a 100644 --- a/src/map.h +++ b/src/map.h @@ -542,6 +542,8 @@ class map // Furniture at coordinates (x, y); {x|y}=(0, SEE{X|Y}*3] furn_id furn( const int x, const int y ) const; + furn_id get_furn_transforms_into( const tripoint &p ) const; + void furn_set( const int x, const int y, const furn_id new_furniture ); std::string furnname( const int x, const int y ); diff --git a/src/weather.cpp b/src/weather.cpp index e639f2b38a985..64ac7cf2bccfb 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -83,7 +83,7 @@ time_duration get_rot_since( const time_point &start, const time_point &end, //Use weather if above ground, use map temp if below double temperature = ( location.z >= 0 ? w.temperature : g->get_temperature( location ) ) + ( g->new_game ? 0 : g->m.temperature( g->m.getlocal( location ) ) ); - + if( !g->new_game && g->m.ter( g->m.getlocal( location ) ) == t_rootcellar ) { temperature = AVERAGE_ANNUAL_TEMPERATURE; } @@ -101,8 +101,11 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); int weed = seed.get_var( "weed", 0 ); + bool is_mature = seed.get_var( "is_mature", 0 ); + bool growing_was_started = seed.get_var( "growing_was_started", 0 ); float water_requirement = seed.type->seed->water_requirement; float weed_susceptibility = seed.type->seed->weed_susceptibility; + bool is_mushroom = seed.type->seed->is_mushroom; /* 1L = 10 units of water @@ -112,7 +115,8 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e Common IRL watering is 50L per week per square meter. - Per season plant will have -2000 health without watering and -4300 health without watering and weed control + Per season plant will have -2000 health without watering, + -4300 health without watering and weed control, +4300 health is possible for the best conditions. */ int water_max = 500; @@ -122,78 +126,105 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e time_duration eff_grow_time = 0; - if( location.z < 0 ) { + // only mushrooms can grow underground + if( !is_mushroom && location.z < 0 ) { return 0; } + const auto &wgen = g->get_cur_weather_gen(); for( time_point i = start; i < end; i += 1_hours ) { w_point w = wgen.get_weather( location, i, g->get_seed() ); weather_type wtype = wgen.get_weather_conditions( location, i, g->get_seed() ); + int temperature = w.temperature; + + // Plants will not start to grow if the temperature is too cold + if ( temperature < 40 && !growing_was_started ) + continue; + + // Start growing and reset health + if ( temperature > 40 && !growing_was_started ) { + growing_was_started = true; + health = 0; + } // plant grow speed - int temperature = w.temperature; float temperature_coeff = 0.0f; if( temperature > 70 ) { temperature_coeff = 1.0f; } else if( temperature > 32 ) { temperature_coeff = ( temperature - 32 ) / 38.0f; - } else if ( ( temperature < 23 ) && one_in( 20 ) ) { - // Freezing can kill the plant - seed.set_var( "frozen", 1 ); - return eff_grow_time; + } else if ( temperature < 23 ) { + // Freezing will kill the plant or reset fruit grow for perennial plants + if( is_mature ) { + seed.set_var( "growing_was_started", 0 ); + continue; + } else { + seed.set_var( "frozen", 1 ); + return eff_grow_time; + } + + } + if( !is_mushroom ) { + eff_grow_time += 1_hours * temperature_coeff; + } else if( water > 0 ) { + // Mushrooms will grow only if have enough water + eff_grow_time += 1_hours * temperature_coeff; } - eff_grow_time += 1_hours * temperature_coeff; - // Low temperature damage the plant - if( !seed.is_warm_enought() ){ - health -= 1; + // Low temperature damage the plant unless plant is mushroom or mature perennial + if( !seed.is_warm_enought() && !is_mature && !is_mushroom ) { + health -= 2; } // Absorb fertilizer - if( fertilizer > 0 ){ + if( fertilizer > 0 ) { fertilizer -= 1; health += roll_remainder( 3.0f * temperature_coeff ); } // Absorb water - water -= roll_remainder( 3.0f * water_requirement ) ; + water -= roll_remainder( 3.0f * water_requirement ); if ( water <= 0 ){ health -= 1; } - // Precipitation was reduced 10 times to compensate rain frequency - switch( wtype ) { - case WEATHER_DRIZZLE: - water += 4; - break; - case WEATHER_RAINY: - case WEATHER_THUNDER: - case WEATHER_LIGHTNING: - water += 8; - break; - default: - break; + // Precipitation was reduced 10 times to compensate abnormal rain frequency + if( location.z >= 0 ) { + switch( wtype ) { + case WEATHER_DRIZZLE: + water += 4; + break; + case WEATHER_RAINY: + case WEATHER_THUNDER: + case WEATHER_LIGHTNING: + water += 8; + break; + default: + break; + } } // Air temperature above 80F(26C) increase water consumption if( temperature > 80 ) { water -= roll_remainder( 5.0f * water_requirement ) ; - if ( water <= 0 ){ - health -= 1; + if ( water <= 0 ) { + health -= 2; } } // Grow weeds - if( weed == weed_max ){ - health -= roll_remainder( 2.0f * weed_susceptibility ) ; - fertilizer -= 2; - water -= 6; - } else { - weed += roll_remainder( 1.0f / calendar::season_ratio() ); - if( one_in( weed_max - weed) ){ - health -= roll_remainder( 1.0f * weed_susceptibility ) ; - fertilizer -= 1; - water -= 3; + if( location.z >= 0 ) { + if( weed == weed_max ) { + health -= roll_remainder( 2.0f * weed_susceptibility ) ; + fertilizer -= 2; + water -= 6; + } else { + weed += roll_remainder( 1.0f / calendar::season_ratio() ); + if( one_in( weed_max - weed) ){ + health -= roll_remainder( 1.0f * weed_susceptibility ) ; + fertilizer -= 1; + water -= 3; + } } } @@ -206,6 +237,8 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e seed.set_var( "water", water ); seed.set_var( "fertilizer", fertilizer ); seed.set_var( "weed", weed ); + seed.set_var( "growing_was_started", growing_was_started ); + seed.set_var( "is_mature", is_mature ); } return eff_grow_time; } From 55541c8f85c7c1f7f774925425cfdcba4d45bba1 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:05:38 +0300 Subject: [PATCH 17/35] Edit mission with plants. --- src/mission_companion.cpp | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index c6290884c5cec..66fdf7944cec0 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -3345,23 +3345,11 @@ bool talk_function::camp_farm_return( npc &p, std::string task, bool harvest, bo if ( harvest && bay.furn(x,y) == furn_str_id( "f_plant_harvest" ) && !bay.i_at(x,y).empty()){ const item &seed = bay.i_at( x,y )[0]; if( seed.is_seed() && seed.typeId() != "fungal_seeds" && seed.typeId() != "marloss_seed") { - const itype &type = *seed.type; - int skillLevel = comp->get_skill_level( skill_survival ); - ///\EFFECT_SURVIVAL increases number of plants harvested from a seed - int plantCount = rng(skillLevel / 2, skillLevel); - //this differs from - if (plantCount >= 9) { - plantCount = 9; - } else if( plantCount <= 0 ) { - plantCount = 1; - } - const int seedCount = std::max( 1l, rng( plantCount / 4, plantCount / 2 ) ); - for( auto &i : iexamine::get_harvest_items( type, plantCount, seedCount, true ) ) { + item &seed_item = g->m.i_at( x,y ).front(); + for( auto &i : iexamine::get_harvest_items( seed_item ) ) { g->m.add_item_or_charges( g->u.posx(), g->u.posy(), i ); } - bay.i_clear( x,y ); - bay.furn_set( x, y, f_null ); - bay.ter_set( x, y, t_dirt ); + iexamine::proceed_plant_after_harvest( x, y, g->u.posz() ); } } } From 893809f052d1b264c1a73c9b56fe2afb21315866 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:06:21 +0300 Subject: [PATCH 18/35] Edit plant processing. --- src/iexamine.cpp | 70 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 4328b597cca5f..cbc73f80fbef6 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1766,7 +1766,12 @@ void iexamine::dirtmound(player &p, const tripoint &examp) used_seed.front().set_var( "fertilizer", 0 ); used_seed.front().set_var( "weed", 0 ); g->m.add_item_or_charges( examp, used_seed.front() ); - g->m.set( examp, t_dirt, f_plant_seed ); + item &seed = g->m.i_at( examp ).front(); + if( seed.type->seed->is_mushroom ) { + g->m.set( examp, t_dirt, f_mushroom_seed ); + } else { + g->m.set( examp, t_dirt, f_plant_seed ); + } p.moves -= 500; add_msg(_("Planted %s"), std::get<1>( seed_entries[seed_index] ).c_str() ); } @@ -1798,11 +1803,17 @@ std::list iexamine::get_harvest_items( item &seed ) int health = seed.get_var( "health", 0 ); // Multiplier for fruit yield. - // Should be in range (0, 2), equal to 1 if plant has default health (0). - const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); - float fruit_multiplier = ( 3.0f * to_hours( seed_grow_time ) + health ) / ( 3.0f * to_hours( seed_grow_time ) ); + // Should be in range (0.1, 2), equal to 1 if plant has default health (0). + time_duration seed_grow_time = 0; + if( seed.get_var( "is_mature", 0 ) ) { + seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); + } else { + seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + } + float fruit_multiplier = ( 3.0f * to_hours( seed_grow_time ) + health ) / + ( 3.0f * to_hours( seed_grow_time ) ); + fruit_multiplier = std::max( fruit_multiplier, 0.1f ); fruit_multiplier *= calendar::season_ratio(); - fruit_multiplier = std::max( fruit_multiplier, 0.0f ); std::string fruit_id; fruit_id = seed.type->seed->fruit_id; @@ -1825,6 +1836,30 @@ std::list iexamine::get_harvest_items( item &seed ) return result; } +void iexamine::proceed_plant_after_harvest( const int x, const int y, const int z ) { + return proceed_plant_after_harvest( tripoint( x, y, z ) ); +} + +void iexamine::proceed_plant_after_harvest( const tripoint &examp ) { + item &seed = g->m.i_at( examp ).front(); + if( g->m.furn(examp) == f_mushroom_mature_harvest ) { + // Mushrooms + seed.set_var( "seed_age", 1 ); + seed.set_birthday( calendar::turn ); + g->m.furn_set(examp, f_mushroom_mature ); + } else if( seed.type->seed->is_shrub && seed.get_var( "can_be_harvested", 0 ) ) { + // Berries + seed.set_var( "seed_age", 1 ); + seed.set_birthday( calendar::turn ); + seed.set_var( "can_be_harvested", 0 ); + g->m.furn_set( examp, g->m.get_furn_transforms_into( examp ) ); + } else { + // Generic seed + g->m.i_clear( examp ); + g->m.furn_set( examp, f_null ); + } +} + void iexamine::aggie_plant(player &p, const tripoint &examp) { if( g->m.i_at( examp ).empty() ) { @@ -1841,7 +1876,8 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) const std::string pname = seed.get_plant_name(); - if (g->m.furn(examp) == f_plant_harvest && query_yn(_("Harvest the %s?"), pname.c_str() )) { + if ( ( g->m.furn(examp) == f_plant_harvest || seed.get_var( "can_be_harvested", 0 ) ) && + query_yn( _("Harvest the %s?"), pname.c_str() ) ) { const std::string &seedType = seed.typeId(); if (seedType == "fungal_seeds") { fungus(p, examp); @@ -1863,13 +1899,11 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) g->m.furn_set(examp, f_flower_fungal); add_msg(m_info, _("The seed blossoms into a flower-looking fungus.")); } - } else { // Generic seed, use the seed item data - g->m.i_clear(examp); - g->m.furn_set(examp, f_null); - + } else { for( auto &i : get_harvest_items( seed ) ) { g->m.add_item_or_charges( examp, i ); } + proceed_plant_after_harvest( examp ); p.moves -= 500; } } else if (g->m.furn(examp) != f_plant_harvest) { @@ -1877,19 +1911,25 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); int weed = seed.get_var( "weed", 0 ); + bool growing_was_started = seed.get_var( "growing_was_started", 0 ); + bool is_mature = seed.get_var( "is_mature", 0 ); - const time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); + time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); int seed_age_days = to_days( seed_age ); - const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + + time_duration seed_grow_time = 0; + if( is_mature ){ + seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); + } else { + seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + } int seed_grow_time_days = to_days( seed_grow_time ); uimenu pmenu; pmenu.return_invalid = true; std::stringstream data; - // data << string_format( _( "Plant info - %-15s" ), pname ) << string_format( _( "Plant info - %-15s" ), pname ) << std::endl; data << string_format( _( "%-15s" ), pname ) << std::endl; - // pmenu.text = data.str(); pmenu.text = pname; //pmenu.text = _( "Plant info - %s", seedType ); @@ -1898,6 +1938,8 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) pmenu.addentry( 3, true, MENU_AUTOASSIGN, _("water %s"), water ); pmenu.addentry( 4, true, MENU_AUTOASSIGN, _("fertilizer %s"), fertilizer ); pmenu.addentry( 5, true, MENU_AUTOASSIGN, _("weed %s"), weed ); + pmenu.addentry( 6, false, MENU_AUTOASSIGN, _("grow %s"), ( growing_was_started ? 1 : 0 ) ); + pmenu.addentry( 7, false, MENU_AUTOASSIGN, _("is_mature %s"), ( is_mature ? 1 : 0 ) ); pmenu.query(); int action_index = pmenu.ret; From eadb21d97db1c624f8fda9395efe22cb8b86bf21 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Fri, 3 Aug 2018 13:08:10 +0300 Subject: [PATCH 19/35] Update seed data. --- doc/JSON_INFO.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index da522467b2823..2ac6e0ad8adb6 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -959,14 +959,23 @@ Every item type can have optional seed data, if the item has seed data, it's con ``` "seed_data" : { - "fruits": "weed", // The item id of the fruits that this seed will produce. - "seeds": false, // (optional, default is true). If true, harvesting the plant will spawn seeds (the same type as the item used to plant). If false only the fruits are spawned, no seeds. - "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. + "comfortable_temperature": 10, // (optional, default is 0). Minimal comfortable temperature (in degree Celsius). + // Plant will be damaged in the air temperature is below this point. + "fruit": "corn", // The item id of the fruits that this seed will produce. + "fruit_count": 10, // (optional, default is 10). Number of fruits per harvest for plants with default health. + "seed": "seed_sunflower", // (optional). The item id of the seeds that this plant will produce. + "seed_count": 10, // (optional, default is 0). Number of seeds per harvest for plants with default health. + "water_requirement": 1.0, // (optional, default is 1.0). Multiplier for plant water requirement. + "weed_susceptibility": 1.0, // (optional, default is 1.0). Multiplier for damage to plants health from weeds. If set to 0.0 weeds will + // still consume plants water and fertilizer, and therefore damage indirectly. + "grow_into": "t_shrub_blueberry", // (optional). The furniture id this plant will transform once fully grown. Used for perennial plants. + "byproducts": ["withered", "straw_pile"], // A list of further items that should spawn upon harvest. + "is_mushroom": true, // (optional, default is false) Is this plant a mushroom. + "is_shrub": true, // (optional, default is false) Will this plant grow into a berry shrub. "grow" : 91 // Time 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. + // Note that growing time is later converted based upon the season_length option. + "grow_secondary" : 91 // (optional). Time it takes for a perennial plant to grow fruits (based of off a season length of 91 days). } ``` From 7fed619000b0c9437edc7cc24abdb9b085a6703a Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sun, 5 Aug 2018 13:35:32 +0300 Subject: [PATCH 20/35] Add more berries. --- data/json/furniture.json | 132 +++++++++++++++++++++++++++++++++++++-- src/mapdata.cpp | 9 +++ src/mapdata.h | 3 + 3 files changed, 140 insertions(+), 4 deletions(-) diff --git a/data/json/furniture.json b/data/json/furniture.json index 92ab8d4bd880d..b33eab94b6f48 100644 --- a/data/json/furniture.json +++ b/data/json/furniture.json @@ -1841,7 +1841,7 @@ },{ "type" : "furniture", "id" : "f_shrub_blueberry", - "name": "blueberry bush", + "name": "blueberry shrub", "symbol": "#", "color": "blue_green", "move_cost_mod": 2, @@ -1861,7 +1861,7 @@ },{ "type" : "furniture", "id" : "f_shrub_blueberry_harvest", - "name": "blueberry bush_harvest", + "name": "blueberry shrub", "symbol": "#", "color": "light_blue_green", "move_cost_mod": 2, @@ -1881,7 +1881,7 @@ },{ "type" : "furniture", "id" : "f_shrub_strawberry", - "name": "strawberry bush", + "name": "strawberry shrub", "symbol": "#", "color": "red_green", "move_cost_mod": 2, @@ -1901,7 +1901,7 @@ },{ "type" : "furniture", "id" : "f_shrub_strawberry_harvest", - "name": "strawberry bush_harvest", + "name": "strawberry shrub", "symbol": "#", "color": "light_red_green", "move_cost_mod": 2, @@ -1918,6 +1918,130 @@ { "item": "withered", "prob": 50, "count": [1, 2] } ] } + },{ + "type" : "furniture", + "id" : "f_shrub_cranberry", + "name": "cranberry shrub", + "symbol": "#", + "color": "red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_cranberry_harvest", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_cranberry_harvest", + "name": "cranberry shrub", + "symbol": "#", + "color": "light_red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_cranberry", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_blackberry", + "name": "blackberry bush", + "symbol": "#", + "color": "red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_blackberry_harvest", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] }, + { "item": "stick_long", "count": [0, 5] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_blackberry_harvest", + "name": "blackberry bush", + "symbol": "#", + "color": "light_red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_blackberry", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] }, + { "item": "stick_long", "count": [0, 5] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_raspberry", + "name": "raspberry bush", + "symbol": "#", + "color": "red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_raspberry_harvest", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] }, + { "item": "stick_long", "count": [0, 5] } + ] + } + },{ + "type" : "furniture", + "id" : "f_shrub_raspberry_harvest", + "name": "raspberry bush", + "symbol": "#", + "color": "light_red_green", + "move_cost_mod": 2, + "required_str": -1, + "flags": ["PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN"], + "transforms_into": "f_shrub_raspberry", + "examine_action": "aggie_plant", + "bash": { + "str_min": 4, "str_max": 60, + "sound": "crunch.", + "sound_fail": "brush.", + "ter_set": "t_dirt", + "items": [ + { "item": "withered", "prob": 50, "count": [1, 2] }, + { "item": "stick_long", "count": [0, 5] } + ] + } },{ "type" : "furniture", "id" : "f_fvat_empty", diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 07be87776a7ea..d81c05ef1fe87 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -834,6 +834,9 @@ furn_id f_null, f_mushroom_seed, f_mushroom_seedling, f_mushroom_mature, f_mushroom_mature_harvest, f_shrub_blueberry, f_shrub_blueberry_harvest, f_shrub_strawberry, f_shrub_strawberry_harvest, + f_shrub_cranberry, f_shrub_cranberry_harvest, + f_shrub_blackberry, f_shrub_blackberry_harvest, + f_shrub_raspberry, f_shrub_raspberry_harvest, f_fvat_empty, f_fvat_full, f_wood_keg, f_standing_tank, @@ -935,6 +938,12 @@ void set_furn_ids() { f_shrub_blueberry_harvest = furn_id( "f_shrub_blueberry_harvest" ); f_shrub_strawberry = furn_id( "f_shrub_strawberry" ); f_shrub_strawberry_harvest = furn_id( "f_shrub_strawberry_harvest" ); + f_shrub_cranberry = furn_id( "f_shrub_cranberry" ); + f_shrub_cranberry_harvest = furn_id( "f_shrub_cranberry_harvest" ); + f_shrub_blackberry = furn_id( "f_shrub_blackberry" ); + f_shrub_blackberry_harvest = furn_id( "f_shrub_blackberry_harvest" ); + f_shrub_raspberry = furn_id( "f_shrub_raspberry" ); + f_shrub_raspberry_harvest = furn_id( "f_shrub_raspberry_harvest" ); f_fvat_empty = furn_id( "f_fvat_empty" ); f_fvat_full = furn_id( "f_fvat_full" ); f_wood_keg = furn_id( "f_wood_keg" ); diff --git a/src/mapdata.h b/src/mapdata.h index f691f7955ea38..57ccd97b1477c 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -472,6 +472,9 @@ extern furn_id f_null, f_mushroom_seed, f_mushroom_seedling, f_mushroom_mature, f_mushroom_mature_harvest, f_shrub_blueberry, f_shrub_blueberry_harvest, f_shrub_strawberry, f_shrub_strawberry_harvest, + f_shrub_cranberry, f_shrub_cranberry_harvest, + f_shrub_blackberry, f_shrub_blackberry_harvest, + f_shrub_raspberry, f_shrub_raspberry_harvest, f_fvat_empty, f_fvat_full, f_wood_keg, f_standing_tank, From bf2e681bf228a9292b929113aee7eb8ff46a75de Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sun, 5 Aug 2018 13:36:08 +0300 Subject: [PATCH 21/35] Update seeds. --- data/json/items/comestibles/seed.json | 88 +++++++++++++++++++++++---- data/json/recipes/food/seed.json | 12 ++++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index 543f40b2043aa..72ef3dbc7abd6 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -41,7 +41,15 @@ "name": "blackberry seeds", "name_plural": "blackberry seeds", "description": "Some blackberry seeds.", - "seed_data": { "plant_name": "blackberry", "fruit": "blackberries", "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { + "plant_name": "blackberry", + "fruit": "blackberries", + "fruit_count": 5, + "grow": 91, + "grow_secondary": 45, + "is_shrub": true, + "grow_into": "f_shrub_blackberry_harvest" + } }, { "id": "seed_blueberries", @@ -67,7 +75,15 @@ "name": "cranberry seeds", "name_plural": "cranberry seeds", "description": "Some cranberry seeds.", - "seed_data": { "plant_name": "cranberry", "fruit": "cranberries", "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { + "plant_name": "cranberry", + "fruit": "cranberries", + "fruit_count": 5, + "grow": 91, + "grow_secondary": 45, + "is_shrub": true, + "grow_into": "f_shrub_cranberry_harvest" + } }, { "id": "seed_hops", @@ -89,7 +105,15 @@ "name": "raspberry seeds", "name_plural": "raspberry seeds", "description": "Some raspberry seeds.", - "seed_data": { "plant_name": "raspberry", "fruit": "raspberries", "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { + "plant_name": "raspberry", + "fruit": "raspberries", + "fruit_count": 5, + "grow": 91, + "grow_secondary": 45, + "is_shrub": true, + "grow_into": "f_shrub_raspberry_harvest" + } }, { "id": "seed_strawberries", @@ -139,9 +163,9 @@ "id": "seed_sugar_beet_raw", "copy-from": "seed", "price": 120, - "name": "sugar beet seeds", - "name_plural": "sugar beet seeds", - "description": "Some sugar beet seeds.", + "name": "seed sugar beet", + "name_plural": "seed sugar beets", + "description": "A raw sugar beet prepared for planting.", "volume": 1, "weight": 310, "stack_size": 10, @@ -150,7 +174,7 @@ "plant_name": "sugar beet", "fruit": "sugar_beet", "fruit_count": 0, - "seed": "sugar_beet", + "seed": "seed_sugar_beet", "seed_count": 5, "grow": 90 } @@ -184,7 +208,14 @@ "name": "tomato seeds", "name_plural": "tomato seeds", "description": "Some tomato seeds.", - "seed_data": { "plant_name": "tomato", "fruit": "tomato", "byproducts": [ "withered" ], "grow": 65 } + "seed_data": { + "plant_name": "tomato", + "fruit": "tomato", + "water_requirement": 2.0, + "comfortable_temperature": 5, + "byproducts": [ "withered" ], + "grow": 65 + } }, { "type": "COMESTIBLE", @@ -197,7 +228,14 @@ "weight": 5, "charges": 8, "stack_size": 40, - "seed_data": { "plant_name": "cotton", "fruit": "cotton_boll", "byproducts": [ "withered" ], "grow": 130 } + "seed_data": { + "plant_name": "cotton", + "fruit": "cotton_boll", + "water_requirement": 1.3, + "comfortable_temperature": 5, + "byproducts": [ "withered" ], + "grow": 130 + } }, { "type": "COMESTIBLE", @@ -229,6 +267,27 @@ "description": "Some onion seeds.", "seed_data": { "plant_name": "onion", "fruit": "onion", "byproducts": [ "withered" ], "grow": 65 } }, + { + "type": "COMESTIBLE", + "id": "seed_onion_raw", + "copy-from": "seed", + "price": 120, + "name": "seed onion", + "name_plural": "seed onions", + "description": "A raw onion prepared for planting.", + "volume": 1, + "weight": 310, + "stack_size": 10, + "charges": 1, + "seed_data": { + "plant_name": "onion", + "fruit": "onion", + "fruit_count": 0, + "seed": "seed_onion", + "seed_count": 5, + "grow": 65 + } + }, { "type": "COMESTIBLE", "id": "seed_garlic", @@ -322,7 +381,14 @@ "name": "cucumber seeds", "name_plural": "cucumber seeds", "description": "Some cucumber seeds.", - "seed_data": { "plant_name": "cucumber", "fruit": "cucumber", "byproducts": [ "withered" ], "grow": 60 } + "seed_data": { + "plant_name": "cucumber", + "fruit": "cucumber", + "water_requirement": 2.0, + "comfortable_temperature": 5, + "byproducts": [ "withered" ], + "grow": 60 + } }, { "type": "COMESTIBLE", @@ -467,7 +533,7 @@ "description": "Some raw pumpkin seeds. Could be fried and eaten or planted.", "price": 100, "charges": 2, - "seed_data": { "plant_name": "pumpkin", "fruit": "pumpkin", "fruit_div": 3, "byproducts": [ "withered" ], "grow": 91 } + "seed_data": { "plant_name": "pumpkin", "fruit": "pumpkin", "fruit_count": 4, "byproducts": [ "withered" ], "grow": 91 } }, { "type": "COMESTIBLE", diff --git a/data/json/recipes/food/seed.json b/data/json/recipes/food/seed.json index 851af0a65abea..226afcbb8869d 100644 --- a/data/json/recipes/food/seed.json +++ b/data/json/recipes/food/seed.json @@ -360,5 +360,17 @@ "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "sugar_beet", 1 ] ] ] + }, + { + "result": "seed_onion_raw", + "type": "recipe", + "category": "CC_FOOD", + "subcategory": "CSC_FOOD_SEEDS", + "skill_used": "survival", + "difficulty": 2, + "time": 5000, + "autolearn": true, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "onion", 1 ] ] ] } ] From 142b2afba6bf22bb0331f8fae36cbe403a0d67a6 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sun, 5 Aug 2018 13:36:59 +0300 Subject: [PATCH 22/35] Bugfixing. --- src/iexamine.cpp | 3 ++- src/map.cpp | 3 ++- src/weather.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index cbc73f80fbef6..7e08db619622a 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1846,6 +1846,7 @@ void iexamine::proceed_plant_after_harvest( const tripoint &examp ) { // Mushrooms seed.set_var( "seed_age", 1 ); seed.set_birthday( calendar::turn ); + seed.set_var( "can_be_harvested", 0 ); g->m.furn_set(examp, f_mushroom_mature ); } else if( seed.type->seed->is_shrub && seed.get_var( "can_be_harvested", 0 ) ) { // Berries @@ -1906,7 +1907,7 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) proceed_plant_after_harvest( examp ); p.moves -= 500; } - } else if (g->m.furn(examp) != f_plant_harvest) { + } else if ( g->m.furn(examp) != f_plant_harvest ) { int health = seed.get_var( "health", 0 ); int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); diff --git a/src/map.cpp b/src/map.cpp index 5f29e68a6fba1..797f4dfc5e3fd 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -6869,6 +6869,7 @@ void map::grow_plant( const tripoint &p ) seed_item.set_birthday( until ); furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); seed_item.set_var( "is_mature", 1 ); + seed_item.set_var( "can_be_harvested", 1 ); } } // Mushrooms grow on beds @@ -6927,9 +6928,9 @@ void map::grow_plant( const tripoint &p ) if ( seed_item.type->seed->is_shrub ) { furn_set( p, furn_str_id( seed_item.type->seed->grow_into ) ); seed_item.set_var( "is_mature", 1 ); + seed_item.set_var( "can_be_harvested", 1 ); return; } - i_clear( p ); furn_set(p, furn_str_id( "f_plant_harvest" ) ); } } diff --git a/src/weather.cpp b/src/weather.cpp index 64ac7cf2bccfb..bc1561337560b 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -135,7 +135,7 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e for( time_point i = start; i < end; i += 1_hours ) { w_point w = wgen.get_weather( location, i, g->get_seed() ); weather_type wtype = wgen.get_weather_conditions( location, i, g->get_seed() ); - int temperature = w.temperature; + int temperature = ( location.z >= 0 ? w.temperature : g->get_temperature( location ) ); // Plants will not start to grow if the temperature is too cold if ( temperature < 40 && !growing_was_started ) From deed0d5ffb6071e1a76e4dafb00875140f73b4a6 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Mon, 6 Aug 2018 17:07:06 +0300 Subject: [PATCH 23/35] Update seed info. --- data/json/items/comestibles/seed.json | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index 72ef3dbc7abd6..fb33f841816a9 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -46,7 +46,7 @@ "fruit": "blackberries", "fruit_count": 5, "grow": 91, - "grow_secondary": 45, + "grow_secondary": 35, "is_shrub": true, "grow_into": "f_shrub_blackberry_harvest" } @@ -63,7 +63,7 @@ "fruit": "blueberries", "fruit_count": 5, "grow": 91, - "grow_secondary": 45, + "grow_secondary": 35, "is_shrub": true, "grow_into": "f_shrub_blueberry_harvest" } @@ -80,7 +80,7 @@ "fruit": "cranberries", "fruit_count": 5, "grow": 91, - "grow_secondary": 45, + "grow_secondary": 35, "is_shrub": true, "grow_into": "f_shrub_cranberry_harvest" } @@ -110,7 +110,7 @@ "fruit": "raspberries", "fruit_count": 5, "grow": 91, - "grow_secondary": 45, + "grow_secondary": 35, "is_shrub": true, "grow_into": "f_shrub_raspberry_harvest" } @@ -127,7 +127,7 @@ "fruit": "strawberries", "fruit_count": 5, "grow": 91, - "grow_secondary": 45, + "grow_secondary": 35, "is_shrub": true, "grow_into": "f_shrub_strawberry_harvest" } @@ -212,7 +212,7 @@ "plant_name": "tomato", "fruit": "tomato", "water_requirement": 2.0, - "comfortable_temperature": 5, + "comfortable_temperature": 5, "byproducts": [ "withered" ], "grow": 65 } @@ -371,7 +371,13 @@ "name_plural": "chili pepper seeds", "color": "white", "description": "Some chili pepper seeds.", - "seed_data": { "plant_name": "chili pepper", "fruit": "chili_pepper", "comfortable_temperature": 10, "byproducts": [ "withered" ], "grow": 65 } + "seed_data": { + "plant_name": "chili pepper", + "fruit": "chili_pepper", + "comfortable_temperature": 10, + "byproducts": [ "withered" ], + "grow": 65 + } }, { "type": "COMESTIBLE", @@ -649,6 +655,7 @@ "is_mushroom": true, "fruit": "mushroom", "fruit_count": 2, + "water_requirement": 0.5, "grow": 45, "grow_secondary": 10 } @@ -665,6 +672,7 @@ "is_mushroom": true, "fruit": "mushroom_morel", "fruit_count": 2, + "water_requirement": 0.5, "grow": 45, "grow_secondary": 10 } @@ -681,6 +689,7 @@ "is_mushroom": true, "fruit": "mushroom_magic", "fruit_count": 2, + "water_requirement": 0.5, "grow": 45, "grow_secondary": 10 } @@ -697,6 +706,7 @@ "is_mushroom": true, "fruit": "mushroom_poison", "fruit_count": 2, + "water_requirement": 0.5, "grow": 45, "grow_secondary": 10 } From aa4848974e2b34147419fbdae5ec5bf89308f37e Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Mon, 6 Aug 2018 17:08:00 +0300 Subject: [PATCH 24/35] Edit is_warm_enought(). --- src/item.cpp | 4 ++-- src/item.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 3e7d60c57b928..115e56f95a5f3 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -6092,9 +6092,9 @@ std::string item::get_plant_name() const return type->seed->plant_name; } -bool item::is_warm_enought() const +bool item::is_warm_enought( int temperature ) const { - return temp_to_celsius( g->get_temperature( g-> u.pos() ) ) >= type->seed->comfortable_temperature; + return temp_to_celsius( temperature ) >= type->seed->comfortable_temperature; } bool item::is_dangerous() const diff --git a/src/item.h b/src/item.h index b50b44a809641..80dfa4fee85ad 100644 --- a/src/item.h +++ b/src/item.h @@ -1226,7 +1226,7 @@ class item : public visitable /** * Is temperature comfortable for this plant. */ - bool is_warm_enought() const; + bool is_warm_enought( int temperature ) const; /*@}*/ /** From a383f70d545d4ad5c8ec05a1a83438184c0991dd Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Mon, 6 Aug 2018 17:09:17 +0300 Subject: [PATCH 25/35] Water rebalancing and astyle. --- src/iexamine.cpp | 246 ++++++++++++++++++++++++++++++----------------- src/weather.cpp | 45 ++++----- 2 files changed, 176 insertions(+), 115 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 7e08db619622a..ade8433f70ed6 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1674,11 +1674,11 @@ void iexamine::fungus(player &p, const tripoint &examp) /** * If it's warm enough, pick one of the player's seeds and plant it. */ -void iexamine::dirtmound(player &p, const tripoint &examp) +void iexamine::dirtmound( player &p, const tripoint &examp ) { if( !warm_enough_to_plant() ) { - add_msg(m_info, _("It is too cold to plant anything now.")); + add_msg( m_info, _( "It is too cold to plant anything now." ) ); return; } /* ambient_light_at() not working? @@ -1686,15 +1686,15 @@ void iexamine::dirtmound(player &p, const tripoint &examp) add_msg(m_info, _("It is too dark to plant anything now.")); return; }*/ - std::vector seed_inv = p.items_with( []( const item &itm ) { + std::vector seed_inv = p.items_with( []( const item & itm ) { return itm.is_seed(); } ); if( seed_inv.empty() ) { - add_msg(m_info, _("You have no seeds to plant.")); + add_msg( m_info, _( "You have no seeds to plant." ) ); return; } - if( !g->m.i_at(examp).empty() ) { - add_msg(_("Something's lying there...")); + if( !g->m.i_at( examp ).empty() ) { + add_msg( _( "Something's lying there..." ) ); return; } @@ -1703,8 +1703,8 @@ void iexamine::dirtmound(player &p, const tripoint &examp) std::vector seed_info; for( auto &seed : seed_inv ) { int seed_count = ( seed->charges > 0 ? seed->charges : 1 ); - seed_info = { seed_count, seed->is_warm_enought() }; - seed_map.insert( std::pair>( seed->typeId() , seed_info ) ); + seed_info = { seed_count, seed->is_warm_enought( g->get_temperature( g->u.pos() ) ) }; + seed_map.insert( std::pair>( seed->typeId(), seed_info ) ); } using seed_tuple = std::tuple>; @@ -1717,8 +1717,8 @@ void iexamine::dirtmound(player &p, const tripoint &examp) // Sort by name std::sort( seed_entries.begin(), seed_entries.end(), - []( const seed_tuple &l, const seed_tuple &r ) { - return std::get<1>( l ).compare( std::get<1>( r ) ) < 0; + []( const seed_tuple & l, const seed_tuple & r ) { + return std::get<1>( l ).compare( std::get<1>( r ) ) < 0; } ); // Choose seed @@ -1733,22 +1733,22 @@ void iexamine::dirtmound(player &p, const tripoint &examp) seed_info = std::get<2>( entry ); int seed_count = seed_info[0]; - if( p.get_skill_level( skill_survival ) >= 2 ){ + if( p.get_skill_level( skill_survival ) >= 2 ) { temp = ( seed_info[1] ? _( "Comfortable" ) : _( "Too cold" ) ); } else { temp = _( "Looks fine" ); } - smenu.addentry( count++, true, MENU_AUTOASSIGN, ("%-20s (%s) | %s"), - std::get<1>( entry ).c_str(), seed_count, temp ); + smenu.addentry( count++, true, MENU_AUTOASSIGN, ( "%-20s (%s) | %s" ), + std::get<1>( entry ).c_str(), seed_count, temp ); } smenu.query(); int seed_index = smenu.ret; // Did we cancel? - if( seed_index < 0 || seed_index >= (int)seed_entries.size() ) { - add_msg(_("You saved your seeds for later.")); + if( seed_index < 0 || seed_index >= ( int )seed_entries.size() ) { + add_msg( _( "You saved your seeds for later." ) ); return; } const auto &seed_id = std::get<0>( seed_entries[seed_index] ); @@ -1773,7 +1773,7 @@ void iexamine::dirtmound(player &p, const tripoint &examp) g->m.set( examp, t_dirt, f_plant_seed ); } p.moves -= 500; - add_msg(_("Planted %s"), std::get<1>( seed_entries[seed_index] ).c_str() ); + add_msg( _( "Planted %s" ), std::get<1>( seed_entries[seed_index] ).c_str() ); } /** @@ -1787,11 +1787,11 @@ std::list iexamine::get_harvest_items( item &seed ) return result; } - const auto add = [&]( const itype_id &id, const int count ) { + const auto add = [&]( const itype_id & id, const int count ) { item new_item( id, calendar::turn ); if( new_item.count_by_charges() && count > 0 ) { new_item.charges *= count; - if(new_item.charges <= 0) { + if( new_item.charges <= 0 ) { new_item.charges = 1; } result.push_back( new_item ); @@ -1836,18 +1836,20 @@ std::list iexamine::get_harvest_items( item &seed ) return result; } -void iexamine::proceed_plant_after_harvest( const int x, const int y, const int z ) { +void iexamine::proceed_plant_after_harvest( const int x, const int y, const int z ) +{ return proceed_plant_after_harvest( tripoint( x, y, z ) ); } -void iexamine::proceed_plant_after_harvest( const tripoint &examp ) { +void iexamine::proceed_plant_after_harvest( const tripoint &examp ) +{ item &seed = g->m.i_at( examp ).front(); - if( g->m.furn(examp) == f_mushroom_mature_harvest ) { + if( g->m.furn( examp ) == f_mushroom_mature_harvest ) { // Mushrooms seed.set_var( "seed_age", 1 ); seed.set_birthday( calendar::turn ); seed.set_var( "can_be_harvested", 0 ); - g->m.furn_set(examp, f_mushroom_mature ); + g->m.furn_set( examp, f_mushroom_mature ); } else if( seed.type->seed->is_shrub && seed.get_var( "can_be_harvested", 0 ) ) { // Berries seed.set_var( "seed_age", 1 ); @@ -1861,7 +1863,7 @@ void iexamine::proceed_plant_after_harvest( const tripoint &examp ) { } } -void iexamine::aggie_plant(player &p, const tripoint &examp) +void iexamine::aggie_plant( player &p, const tripoint &examp ) { if( g->m.i_at( examp ).empty() ) { g->m.i_clear( examp ); @@ -1877,28 +1879,30 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) const std::string pname = seed.get_plant_name(); - if ( ( g->m.furn(examp) == f_plant_harvest || seed.get_var( "can_be_harvested", 0 ) ) && - query_yn( _("Harvest the %s?"), pname.c_str() ) ) { + if( ( g->m.furn( examp ) == f_plant_harvest || seed.get_var( "can_be_harvested", 0 ) ) && + query_yn( _( "Harvest the %s?" ), pname.c_str() ) ) { const std::string &seedType = seed.typeId(); - if (seedType == "fungal_seeds") { - fungus(p, examp); - g->m.i_clear(examp); - } else if (seedType == "marloss_seed") { - fungus(p, examp); - g->m.i_clear(examp); - if (p.has_trait(trait_M_DEPENDENT) && ((p.get_hunger() > 500) || p.get_thirst() > 300 )) { - g->m.ter_set(examp, t_marloss); - add_msg(m_info, _("We have altered this unit's configuration to extract and provide local nutriment. The Mycus provides.")); - } else if ( (p.has_trait(trait_M_DEFENDER)) || ( (p.has_trait(trait_M_SPORES) || p.has_trait(trait_M_FERTILE)) && - one_in(2)) ) { + if( seedType == "fungal_seeds" ) { + fungus( p, examp ); + g->m.i_clear( examp ); + } else if( seedType == "marloss_seed" ) { + fungus( p, examp ); + g->m.i_clear( examp ); + if( p.has_trait( trait_M_DEPENDENT ) && ( ( p.get_hunger() > 500 ) || p.get_thirst() > 300 ) ) { + g->m.ter_set( examp, t_marloss ); + add_msg( m_info, + _( "We have altered this unit's configuration to extract and provide local nutriment. The Mycus provides." ) ); + } else if( ( p.has_trait( trait_M_DEFENDER ) ) || ( ( p.has_trait( trait_M_SPORES ) || + p.has_trait( trait_M_FERTILE ) ) && + one_in( 2 ) ) ) { g->summon_mon( mon_fungal_blossom, examp ); - add_msg(m_info, _("The seed blooms forth! We have brought true beauty to this world.")); - } else if ( (p.has_trait(trait_THRESH_MYCUS)) || one_in(4)) { - g->m.furn_set(examp, f_flower_marloss); - add_msg(m_info, _("The seed blossoms rather rapidly...")); + add_msg( m_info, _( "The seed blooms forth! We have brought true beauty to this world." ) ); + } else if( ( p.has_trait( trait_THRESH_MYCUS ) ) || one_in( 4 ) ) { + g->m.furn_set( examp, f_flower_marloss ); + add_msg( m_info, _( "The seed blossoms rather rapidly..." ) ); } else { - g->m.furn_set(examp, f_flower_fungal); - add_msg(m_info, _("The seed blossoms into a flower-looking fungus.")); + g->m.furn_set( examp, f_flower_fungal ); + add_msg( m_info, _( "The seed blossoms into a flower-looking fungus." ) ); } } else { for( auto &i : get_harvest_items( seed ) ) { @@ -1907,7 +1911,7 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) proceed_plant_after_harvest( examp ); p.moves -= 500; } - } else if ( g->m.furn(examp) != f_plant_harvest ) { + } else if( g->m.furn( examp ) != f_plant_harvest ) { int health = seed.get_var( "health", 0 ); int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); @@ -1915,45 +1919,108 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) bool growing_was_started = seed.get_var( "growing_was_started", 0 ); bool is_mature = seed.get_var( "is_mature", 0 ); - time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); - int seed_age_days = to_days( seed_age ); - time_duration seed_grow_time = 0; - if( is_mature ){ + if( is_mature ) { seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); } else { - seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); } - int seed_grow_time_days = to_days( seed_grow_time ); + int seed_grow_time_turns = to_turns( seed_grow_time ); + int seed_age_turns = seed.get_var( "seed_age", 1 ); + + float grow_ratio = 1.0f * seed_age_turns / seed_grow_time_turns; + float health_ratio = health / 3.0f * 600.0f / seed_grow_time_turns; uimenu pmenu; pmenu.return_invalid = true; - std::stringstream data; - data << string_format( _( "%-15s" ), pname ) << std::endl; - pmenu.text = pname; + std::string water_info; + std::string fertilizer_info; + std::string weed_info; + std::string grow_info; + std::string health_info; + + if( p.get_skill_level( skill_survival ) >= 2 ) { + if( water > 250 ) { + water_info = _( "more than enough" ); + } else if( water > 0 ) { + water_info = _( "enough" ); + } else if( water > -250 ) { + water_info = _( "not enough" ); + } else { + water_info = _( "too dry" ); + } + + if( fertilizer > 300 ) { + fertilizer_info = _( "more than enough" ); + } else if( fertilizer > 150 ) { + fertilizer_info = _( "enough" ); + } else if( fertilizer > 50 ) { + fertilizer_info = _( "only few" ); + } else { + fertilizer_info = _( "none" ); + } + + if( weed > 100 ) { + weed_info = _( "too many" ); + } else if( weed > 50 ) { + weed_info = _( "some" ); + } else if( weed > 5 ) { + weed_info = _( "few" ); + } else { + weed_info = _( "none" ); + } + + if( grow_ratio > 1.0 ) { + grow_info = _( "Harvest is ready" ); + } else if( grow_ratio > 0.66 ) { + grow_info = _( "Harvest is almost ready" ); + } else if( grow_ratio > 0.33 ) { + grow_info = _( "Growing is in the middle" ); + } else { + grow_info = _( "Growing just started." ); + } + + if( health_ratio > 0.75 ) { + health_info = _( "Plants health is very good" ); + } else if( health_ratio > 0.25 ) { + health_info = _( "Plants health is good" ); + } else if( health_ratio > -0.25 ) { + health_info = _( "Plants health is average" ); + } else if( health_ratio > -0.75 ) { + health_info = _( "Plants health is bad" ); + } else { + health_info = _( "Plants health is very bad" ); + } + } - //pmenu.text = _( "Plant info - %s", seedType ); - pmenu.addentry( 1, false, MENU_AUTOASSIGN, _("health %s"), health ); - pmenu.addentry( 2, false, MENU_AUTOASSIGN, _("grow %s / %s"), seed_age_days, seed_grow_time_days ); - pmenu.addentry( 3, true, MENU_AUTOASSIGN, _("water %s"), water ); - pmenu.addentry( 4, true, MENU_AUTOASSIGN, _("fertilizer %s"), fertilizer ); - pmenu.addentry( 5, true, MENU_AUTOASSIGN, _("weed %s"), weed ); - pmenu.addentry( 6, false, MENU_AUTOASSIGN, _("grow %s"), ( growing_was_started ? 1 : 0 ) ); - pmenu.addentry( 7, false, MENU_AUTOASSIGN, _("is_mature %s"), ( is_mature ? 1 : 0 ) ); + pmenu.text = pname; + pmenu.addentry( 1, true, MENU_AUTOASSIGN, _( "add water %s" ), water_info ); + pmenu.addentry( 2, true, MENU_AUTOASSIGN, _( "add fertilizer %s" ), fertilizer_info ); + pmenu.addentry( 3, true, MENU_AUTOASSIGN, _( "remove weeds %s" ), weed_info ); + if( p.get_skill_level( skill_survival ) >= 2 ) { + pmenu.addentry( 0, false, MENU_AUTOASSIGN, health_info ); + pmenu.addentry( 0, false, MENU_AUTOASSIGN, grow_info ); + if( !growing_was_started ) { + pmenu.addentry( 0, false, MENU_AUTOASSIGN, _( "It is too cold to grow." ) ); + } + if( is_mature ) { + pmenu.addentry( 0, false, MENU_AUTOASSIGN, _( "The plant is mature and will yield fruits." ) ); + } + } pmenu.query(); int action_index = pmenu.ret; // Watering - if( action_index == 3 ) { + if( action_index == 1 ) { const inventory &crafting_inv = p.crafting_inventory(); int water_charges = crafting_inv.charges_of( "water" ); - if ( water_charges == 0) { - add_msg( _("You don't have water.")); + if( water_charges == 0 ) { + add_msg( _( "You don't have water." ) ); return; - } else if ( water > 400 ) { - add_msg( _("There is no need to water this plant.")); + } else if( water > 400 ) { + add_msg( _( "There is no need to water this plant." ) ); return; } else { // Up to 50L of water can be used per plant @@ -1962,27 +2029,27 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) seed.set_var( "water", water ); float water_used = water_use / 5.0f; std::vector comps; - comps.push_back( item_comp( "water", std::max ( static_cast( water_used ), 1 ) ) ); + comps.push_back( item_comp( "water", std::max( static_cast( water_used ), 1 ) ) ); p.consume_items( comps ); - add_msg( _("You watered the plant.")); + add_msg( _( "You watered the plant." ) ); p.moves -= 500; return; } } // Use fertilizer - if( action_index == 4 ) { - if ( water > 400 ){ - add_msg(_("There is no need to fertilize this plant.")); + if( action_index == 2 ) { + if( fertilizer > 300 ) { + add_msg( _( "There is no need to fertilize this plant." ) ); return; } else { std::vector f_inv = p.all_items_with_flag( "FERTILIZER" ); if( f_inv.empty() ) { - add_msg(m_info, _("You have no fertilizer for the %s."), pname.c_str()); + add_msg( m_info, _( "You have no fertilizer for the %s." ), pname.c_str() ); return; } - if (query_yn(_("Fertilize the %s"), pname.c_str() )) { + if( query_yn( _( "Fertilize the %s" ), pname.c_str() ) ) { std::vector f_types; std::vector f_names; for( auto &f : f_inv ) { @@ -1993,53 +2060,52 @@ void iexamine::aggie_plant(player &p, const tripoint &examp) } // Choose fertilizer from list int f_index = 0; - if (f_types.size() > 1) { - f_names.push_back(_("Cancel")); - f_index = menu_vec(false, _("Use which fertilizer?"), f_names) - 1; - if (f_index == (int)f_names.size() - 1) { + if( f_types.size() > 1 ) { + f_names.push_back( _( "Cancel" ) ); + f_index = menu_vec( false, _( "Use which fertilizer?" ), f_names ) - 1; + if( f_index == ( int )f_names.size() - 1 ) { f_index = -1; } } else { - f_index = 0; + f_index = 0; } - if (f_index < 0) { + if( f_index < 0 ) { return; } std::list planted = p.use_charges( f_types[f_index], 1 ); - if (planted.empty()) { // nothing was removed from inv => weapon is the SEED - if (p.weapon.charges > 1) { + if( planted.empty() ) { // nothing was removed from inv => weapon is the SEED + if( p.weapon.charges > 1 ) { p.weapon.charges--; } else { p.remove_weapon(); } } - add_msg(_("You fertilized the plant.")); + add_msg( _( "You fertilized the plant." ) ); p.moves -= 500; - const time_duration seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); - int seed_grow_time_hours = to_hours( seed_grow_time ); - seed.set_var( "fertilizer", fertilizer + seed_grow_time_hours ); + int add_fertilizer = to_hours( calendar::season_length() ); + seed.set_var( "fertilizer", fertilizer + add_fertilizer ); } return; } } // Weed control - if( action_index == 5 ) { - if ( weed == 0 ){ - add_msg(_("There are no weeds here.")); + if( action_index == 3 ) { + if( weed == 0 ) { + add_msg( _( "There are no weeds here." ) ); return; } else { p.moves -= 10 * weed; int survival = p.get_skill_level( skill_survival ); - if( survival >= 2 ){ + if( survival >= 2 ) { seed.set_var( "weed", 0 ); - add_msg(_("You removed all weeds.")); + add_msg( _( "You removed all weeds." ) ); } else { weed *= rng( survival * 50, 100 ) / 100.0f; seed.set_var( "weed", weed ); health -= rng( 0, 20 - survival * 10 ); seed.set_var( "health", health ); - add_msg(_("You removed some weeds.")); + add_msg( _( "You removed some weeds." ) ); } return; } diff --git a/src/weather.cpp b/src/weather.cpp index bc1561337560b..b15dd282c6650 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -109,15 +109,9 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e /* 1L = 10 units of water - One plant tile will absorb 50 L/week ( 0.3 L/hour, 650 L/season ) + One plant tile will absorb 33 L/week ( 0.2 L/hour, 430 L/season ) Precipitation is 300 L/season - Watering once per week is recommended for the best results - - Common IRL watering is 50L per week per square meter. - - Per season plant will have -2000 health without watering, - -4300 health without watering and weed control, - +4300 health is possible for the best conditions. + Watering and weed control once per week is recommended for the best results */ int water_max = 500; @@ -138,11 +132,12 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e int temperature = ( location.z >= 0 ? w.temperature : g->get_temperature( location ) ); // Plants will not start to grow if the temperature is too cold - if ( temperature < 40 && !growing_was_started ) + if( temperature < 40 && !growing_was_started ) { continue; + } // Start growing and reset health - if ( temperature > 40 && !growing_was_started ) { + if( temperature > 40 && !growing_was_started ) { growing_was_started = true; health = 0; } @@ -153,7 +148,7 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e temperature_coeff = 1.0f; } else if( temperature > 32 ) { temperature_coeff = ( temperature - 32 ) / 38.0f; - } else if ( temperature < 23 ) { + } else if( temperature < 23 ) { // Freezing will kill the plant or reset fruit grow for perennial plants if( is_mature ) { seed.set_var( "growing_was_started", 0 ); @@ -172,7 +167,7 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e } // Low temperature damage the plant unless plant is mushroom or mature perennial - if( !seed.is_warm_enought() && !is_mature && !is_mushroom ) { + if( !seed.is_warm_enought( temperature ) && !is_mature && !is_mushroom ) { health -= 2; } @@ -183,8 +178,8 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e } // Absorb water - water -= roll_remainder( 3.0f * water_requirement ); - if ( water <= 0 ){ + water -= roll_remainder( 2.0f * water_requirement ); + if( water <= 0 ) { health -= 1; } @@ -206,8 +201,8 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e // Air temperature above 80F(26C) increase water consumption if( temperature > 80 ) { - water -= roll_remainder( 5.0f * water_requirement ) ; - if ( water <= 0 ) { + water -= roll_remainder( 3.0f * water_requirement ) ; + if( water <= 0 ) { health -= 2; } } @@ -217,21 +212,21 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e if( weed == weed_max ) { health -= roll_remainder( 2.0f * weed_susceptibility ) ; fertilizer -= 2; - water -= 6; + water -= 4; } else { weed += roll_remainder( 1.0f / calendar::season_ratio() ); - if( one_in( weed_max - weed) ){ - health -= roll_remainder( 1.0f * weed_susceptibility ) ; - fertilizer -= 1; - water -= 3; + if( one_in( weed_max - weed ) ) { + health -= roll_remainder( 1.0f * weed_susceptibility ) ; + fertilizer -= 1; + water -= 2; } } } - water = std::max( water , -water_max ); - water = std::min( water , water_max ); - fertilizer = std::max( fertilizer , 0 ); - weed = std::min( weed , weed_max ); + water = std::max( water, -water_max ); + water = std::min( water, water_max ); + fertilizer = std::max( fertilizer, 0 ); + weed = std::min( weed, weed_max ); seed.set_var( "health", health ); seed.set_var( "water", water ); From 7313c2c605640fb8c06968f33fa393e180f1f2a3 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Tue, 7 Aug 2018 13:35:50 +0300 Subject: [PATCH 26/35] Replace dash-like character with minus sign. --- src/weather.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/weather.cpp b/src/weather.cpp index b15dd282c6650..72ca2b5163a3d 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -685,13 +685,13 @@ static std::string print_time_just_hour( const time_point &p ) // MONDAY...MOSTLY SUNNY. HIGHS IN THE LOWER 60S. NORTHEAST WINDS 10 TO 15 MPH. // MONDAY NIGHT...PARTLY CLOUDY. LOWS AROUND 40. NORTHEAST WINDS 5 TO 10 MPH. -// 0% � No mention of precipitation -// 10% � No mention of precipitation, or isolated/slight chance -// 20% � Isolated/slight chance -// 30% � (Widely) scattered/chance -// 40% or 50% � Scattered/chance -// 60% or 70% � Numerous/likely -// 80%, 90% or 100% � No additional modifiers (i.e. "showers and thunderstorms") +// 0% - No mention of precipitation +// 10% - No mention of precipitation, or isolated/slight chance +// 20% - Isolated/slight chance +// 30% - (Widely) scattered/chance +// 40% or 50% - Scattered/chance +// 60% or 70% - Numerous/likely +// 80%, 90% or 100% - No additional modifiers (i.e. "showers and thunderstorms") /** * Generate textual weather forecast for the specified radio tower. */ From 5af234236d2c56592a34086ed5b81655492fdc83 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 11 Aug 2018 17:53:44 +0300 Subject: [PATCH 27/35] Edit crops interactions. --- src/iexamine.cpp | 109 ++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 00baa938ce22c..1e7e2e79f719d 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1703,7 +1703,7 @@ void iexamine::dirtmound( player &p, const tripoint &examp ) std::vector seed_info; for( auto &seed : seed_inv ) { int seed_count = ( seed->charges > 0 ? seed->charges : 1 ); - seed_info = { seed_count, seed->is_warm_enought( g->get_temperature( g->u.pos() ) ) }; + seed_info = { seed_count, seed->is_warm_enough( g->get_temperature( g->u.pos() ) ) }; seed_map.insert( std::pair>( seed->typeId(), seed_info ) ); } @@ -1762,9 +1762,15 @@ void iexamine::dirtmound( player &p, const tripoint &examp ) } used_seed.front().set_age( 0 ); used_seed.front().set_var( "health", 0 ); - used_seed.front().set_var( "water", 0 ); + used_seed.front().set_var( "water", 100 ); used_seed.front().set_var( "fertilizer", 0 ); used_seed.front().set_var( "weed", 0 ); + if( g->get_temperature( examp ) > 40 ) { + used_seed.front().set_var( "growing_was_started", 1 ); + } else { + used_seed.front().set_var( "growing_was_started", 0 ); + } + g->m.add_item_or_charges( examp, used_seed.front() ); item &seed = g->m.i_at( examp ).front(); if( seed.type->seed->is_mushroom ) { @@ -1800,10 +1806,9 @@ std::list iexamine::get_harvest_items( item &seed ) } }; - int health = seed.get_var( "health", 0 ); - // Multiplier for fruit yield. // Should be in range (0.1, 2), equal to 1 if plant has default health (0). + int health = seed.get_var( "health", 0 ); time_duration seed_grow_time = 0; if( seed.get_var( "is_mature", 0 ) ) { seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); @@ -1877,6 +1882,7 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) return; } + get_crops_grow( examp ); const std::string pname = seed.get_plant_name(); if( ( g->m.furn( examp ) == f_plant_harvest || seed.get_var( "can_be_harvested", 0 ) ) && @@ -1903,13 +1909,19 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) add_msg( m_info, _( "The seed blossoms into a flower-looking fungus." ) ); } } else { - for( auto &i : get_harvest_items( seed ) ) { - g->m.add_item_or_charges( examp, i ); - } + std::list harvest_items = get_harvest_items( seed ); proceed_plant_after_harvest( examp ); + for( auto &i : harvest_items ) { + if( seed.type->seed->is_shrub || seed.type->seed->is_mushroom ) { + // shrubs and mushrooms add items at player position + g->m.add_item_or_charges( p.pos(), i ); + } else { + g->m.add_item_or_charges( examp, i ); + } + } p.moves -= 500; } - } else if( g->m.furn( examp ) != f_plant_harvest ) { + } else { int health = seed.get_var( "health", 0 ); int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); @@ -1939,11 +1951,11 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) std::string health_info; if( p.get_skill_level( skill_survival ) >= 2 ) { - if( water > 250 ) { + if( water > 125 ) { water_info = _( "more than enough" ); } else if( water > 0 ) { water_info = _( "enough" ); - } else if( water > -250 ) { + } else if( water > -125 ) { water_info = _( "not enough" ); } else { water_info = _( "too dry" ); @@ -1997,10 +2009,13 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) pmenu.addentry( 2, true, MENU_AUTOASSIGN, _( "add fertilizer %s" ), fertilizer_info ); pmenu.addentry( 3, true, MENU_AUTOASSIGN, _( "remove weeds %s" ), weed_info ); if( p.get_skill_level( skill_survival ) >= 2 ) { + int irrigation_max = ( 250 - water ) / 10.0f; + pmenu.addentry( 0, false, MENU_AUTOASSIGN, _( "Earth here can absorb up to %s L of water" ), irrigation_max ); pmenu.addentry( 0, false, MENU_AUTOASSIGN, health_info ); - pmenu.addentry( 0, false, MENU_AUTOASSIGN, grow_info ); if( !growing_was_started ) { pmenu.addentry( 0, false, MENU_AUTOASSIGN, _( "It is too cold to grow." ) ); + } else { + pmenu.addentry( 0, false, MENU_AUTOASSIGN, grow_info ); } if( is_mature ) { pmenu.addentry( 0, false, MENU_AUTOASSIGN, _( "The plant is mature and will yield fruits." ) ); @@ -2017,17 +2032,16 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) if( water_charges == 0 ) { add_msg( _( "You don't have water." ) ); return; - } else if( water > 400 ) { + } else if( water > 200 ) { add_msg( _( "There is no need to water this plant." ) ); return; } else { // Up to 50L of water can be used per plant - int water_use = std::min( water_charges * 5, ( 500 - water ) ); - water += water_use; + int water_used = std::min( water_charges, ( 250 - water ) / 5 ); + water += water_used * 5; seed.set_var( "water", water ); - float water_used = water_use / 5.0f; std::vector comps; - comps.push_back( item_comp( "water", std::max( static_cast( water_used ), 1 ) ) ); + comps.push_back( item_comp( "water", water_used ) ); p.consume_items( comps ); add_msg( _( "You watered the plant." ) ); p.moves -= 500; @@ -2046,43 +2060,40 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) add_msg( m_info, _( "You have no fertilizer for the %s." ), pname.c_str() ); return; } - - if( query_yn( _( "Fertilize the %s" ), pname.c_str() ) ) { - std::vector f_types; - std::vector f_names; - for( auto &f : f_inv ) { - if( std::find( f_types.begin(), f_types.end(), f->typeId() ) == f_types.end() ) { - f_types.push_back( f->typeId() ); - f_names.push_back( f->tname() ); - } - } - // Choose fertilizer from list - int f_index = 0; - if( f_types.size() > 1 ) { - f_names.push_back( _( "Cancel" ) ); - f_index = menu_vec( false, _( "Use which fertilizer?" ), f_names ) - 1; - if( f_index == ( int )f_names.size() - 1 ) { - f_index = -1; - } - } else { - f_index = 0; + std::vector f_types; + std::vector f_names; + for( auto &f : f_inv ) { + if( std::find( f_types.begin(), f_types.end(), f->typeId() ) == f_types.end() ) { + f_types.push_back( f->typeId() ); + f_names.push_back( f->tname() ); } - if( f_index < 0 ) { - return; + } + // Choose fertilizer from list + int f_index = 0; + if( f_types.size() > 1 ) { + f_names.push_back( _( "Cancel" ) ); + f_index = menu_vec( false, _( "Use which fertilizer?" ), f_names ) - 1; + if( f_index == ( int )f_names.size() - 1 ) { + f_index = -1; } - std::list planted = p.use_charges( f_types[f_index], 1 ); - if( planted.empty() ) { // nothing was removed from inv => weapon is the SEED - if( p.weapon.charges > 1 ) { - p.weapon.charges--; - } else { - p.remove_weapon(); - } + } else { + f_index = 0; + } + if( f_index < 0 ) { + return; + } + std::list planted = p.use_charges( f_types[f_index], 1 ); + if( planted.empty() ) { // nothing was removed from inv => weapon is the SEED + if( p.weapon.charges > 1 ) { + p.weapon.charges--; + } else { + p.remove_weapon(); } - add_msg( _( "You fertilized the plant." ) ); - p.moves -= 500; - int add_fertilizer = to_hours( calendar::season_length() ); - seed.set_var( "fertilizer", fertilizer + add_fertilizer ); } + add_msg( _( "You fertilized the plant." ) ); + p.moves -= 500; + int add_fertilizer = to_hours( calendar::season_length() ); + seed.set_var( "fertilizer", fertilizer + add_fertilizer ); return; } } From f0035ca0fc28470335537d8fd1bfa78c36720bf4 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 11 Aug 2018 17:54:21 +0300 Subject: [PATCH 28/35] Linting. --- data/json/items/comestibles/seed.json | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index fb33f841816a9..081991ba3c44f 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -279,14 +279,7 @@ "weight": 310, "stack_size": 10, "charges": 1, - "seed_data": { - "plant_name": "onion", - "fruit": "onion", - "fruit_count": 0, - "seed": "seed_onion", - "seed_count": 5, - "grow": 65 - } + "seed_data": { "plant_name": "onion", "fruit": "onion", "fruit_count": 0, "seed": "seed_onion", "seed_count": 5, "grow": 65 } }, { "type": "COMESTIBLE", @@ -404,7 +397,7 @@ "name": "potato seed", "name_plural": "potato seeds", "description": "Some potato seeds.", - "seed_data": { + "seed_data": { "plant_name": "potatoes", "fruit": "potato_raw", "fruit_count": 10, @@ -424,7 +417,7 @@ "description": "A raw potato, cut into pieces, separating each bud for planting.", "weight": 20, "stack_size": 10, - "seed_data": { + "seed_data": { "plant_name": "potatoes", "fruit": "potato_raw", "fruit_count": 10, From 4009795233c427ff084a7ad4197883f9df9abf68 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 11 Aug 2018 17:55:09 +0300 Subject: [PATCH 29/35] Typo. --- src/item.cpp | 2 +- src/item.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 0f7d2ad55288d..ccc571cc34b12 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -6096,7 +6096,7 @@ std::string item::get_plant_name() const return type->seed->plant_name; } -bool item::is_warm_enought( int temperature ) const +bool item::is_warm_enough( int temperature ) const { return temp_to_celsius( temperature ) >= type->seed->comfortable_temperature; } diff --git a/src/item.h b/src/item.h index f40c0dbce9ed6..e77158c3c0ecb 100644 --- a/src/item.h +++ b/src/item.h @@ -1227,7 +1227,7 @@ class item : public visitable /** * Is temperature comfortable for this plant. */ - bool is_warm_enought( int temperature ) const; + bool is_warm_enough( int temperature ) const; /*@}*/ /** From 0becd481f764808e9adb86b55aabf36423cebf83 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 11 Aug 2018 17:55:49 +0300 Subject: [PATCH 30/35] Edit crops grow. --- src/map.cpp | 20 +++--------- src/weather.cpp | 84 +++++++++++++++++++++++++++++++------------------ src/weather.h | 5 ++- 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 180884502d263..343026ad3eb2e 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -6836,18 +6836,10 @@ void map::grow_plant( const tripoint &p ) return; } + get_crops_grow( p ); item &seed_item = i_at( p ).front(); - const time_point seed_bday = seed_item.birthday(); - time_duration seed_age = time_duration::from_turns( seed_item.get_var( "seed_age", 1 ) ); - const time_duration plantEpoch = seed_item.get_plant_epoch(); - const time_point since = time_point::from_turn( seed_item.get_var( "last_grow_check", - to_turn( seed_bday ) ) ); - - const time_point until = calendar::turn; - seed_age += get_crops_grow_since( since, until, p ); - seed_item.set_var( "last_grow_check", to_turn( until ) ); - seed_item.set_var( "seed_age", to_turns( seed_age ) ); + time_duration seed_age = time_duration::from_turns( seed_item.get_var( "seed_age", 1 ) ); furn_id cur_furn = this->furn(p).id(); @@ -6868,16 +6860,13 @@ void map::grow_plant( const tripoint &p ) if( seed_age >= plantEpoch && seed_age < plantEpoch * 3 ) { furn_set(p, furn_str_id( "f_mushroom_seedling" ) ); } else if( seed_age >= plantEpoch * 3 ) { - seed_item.set_birthday( until ); furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); seed_item.set_var( "is_mature", 1 ); seed_item.set_var( "can_be_harvested", 1 ); } } // Mushrooms grow on beds - if( cur_furn == furn_str_id( "f_mushroom_mature" ) && - seed_age > ( seed_item.type->seed->grow_secondary * calendar::season_ratio() ) ){ - seed_item.set_var( "can_be_harvested", 1 ); + if( seed_item.get_var( "is_mature", 0 ) && seed_item.get_var( "can_be_harvested", 0 ) ) { furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); } return; @@ -6885,8 +6874,7 @@ void map::grow_plant( const tripoint &p ) // Grow berries on shrubs if( seed_item.type->seed->is_shrub && seed_item.get_var( "is_mature", 0 ) && - seed_age > seed_item.type->seed->grow_secondary * calendar::season_ratio() ) { - seed_item.set_var( "can_be_harvested", 1 ); + seed_item.get_var( "can_be_harvested", 0 ) ) { const auto &furn_obj = this->furn( p ).obj(); furn_set( p, furn_obj.transforms_into ); return; diff --git a/src/weather.cpp b/src/weather.cpp index 72ca2b5163a3d..b5543f78ea947 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -93,16 +93,24 @@ time_duration get_rot_since( const time_point &start, const time_point &end, return ret; } -time_duration get_crops_grow_since( const time_point &start, const time_point &end, - const tripoint &location ) +void get_crops_grow( const tripoint &location ) { item &seed = g->m.i_at( location ).front(); + const time_point seed_bday = seed.birthday(); + time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); + const time_point since = time_point::from_turn( seed.get_var( "last_grow_check", + to_turn( seed_bday ) ) ); + const time_point until = calendar::turn; + seed.set_var( "last_grow_check", to_turn( until ) ); + int health = seed.get_var( "health", 0 ); int water = seed.get_var( "water", 0 ); int fertilizer = seed.get_var( "fertilizer", 0 ); int weed = seed.get_var( "weed", 0 ); bool is_mature = seed.get_var( "is_mature", 0 ); bool growing_was_started = seed.get_var( "growing_was_started", 0 ); + bool can_be_harvested = seed.get_var( "can_be_harvested", 0 ); + float water_requirement = seed.type->seed->water_requirement; float weed_susceptibility = seed.type->seed->weed_susceptibility; bool is_mushroom = seed.type->seed->is_mushroom; @@ -111,35 +119,48 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e 1L = 10 units of water One plant tile will absorb 33 L/week ( 0.2 L/hour, 430 L/season ) Precipitation is 300 L/season + Irrigation with 15L of water per week should be sufficient Watering and weed control once per week is recommended for the best results */ - int water_max = 500; + int water_max = 250; // weeds will grow to max in 1 week ( 168 hours ) int weed_max = 168; - time_duration eff_grow_time = 0; - // only mushrooms can grow underground - if( !is_mushroom && location.z < 0 ) { - return 0; - } + if( !is_mushroom && location.z < 0 ) + return; const auto &wgen = g->get_cur_weather_gen(); - for( time_point i = start; i < end; i += 1_hours ) { + for( time_point i = since; i < until; i += 1_hours ) { w_point w = wgen.get_weather( location, i, g->get_seed() ); weather_type wtype = wgen.get_weather_conditions( location, i, g->get_seed() ); int temperature = ( location.z >= 0 ? w.temperature : g->get_temperature( location ) ); + // Skip if the harvest is ready + if ( can_be_harvested ) + continue; + // Plants will not start to grow if the temperature is too cold - if( temperature < 40 && !growing_was_started ) { + if( temperature < 40 && !growing_was_started ) continue; + + if( temperature < 23 ) { + // Freezing will kill the plant or reset fruit grow for perennial plants + if( is_mature ) { + growing_was_started = 0; + continue; + } else { + seed.set_var( "frozen", 1 ); + return; + } } // Start growing and reset health if( temperature > 40 && !growing_was_started ) { growing_was_started = true; health = 0; + seed_age = 0; } // plant grow speed @@ -148,26 +169,17 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e temperature_coeff = 1.0f; } else if( temperature > 32 ) { temperature_coeff = ( temperature - 32 ) / 38.0f; - } else if( temperature < 23 ) { - // Freezing will kill the plant or reset fruit grow for perennial plants - if( is_mature ) { - seed.set_var( "growing_was_started", 0 ); - continue; - } else { - seed.set_var( "frozen", 1 ); - return eff_grow_time; - } - } + if( !is_mushroom ) { - eff_grow_time += 1_hours * temperature_coeff; + seed_age += 1_hours * temperature_coeff; } else if( water > 0 ) { // Mushrooms will grow only if have enough water - eff_grow_time += 1_hours * temperature_coeff; + seed_age += 1_hours * temperature_coeff; } // Low temperature damage the plant unless plant is mushroom or mature perennial - if( !seed.is_warm_enought( temperature ) && !is_mature && !is_mushroom ) { + if( !seed.is_warm_enough( temperature ) && !is_mature && !is_mushroom ) { health -= 2; } @@ -223,19 +235,29 @@ time_duration get_crops_grow_since( const time_point &start, const time_point &e } } + time_duration seed_grow_time = 0; + if( is_mature ) { + seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); + } else { + seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); + } + if( seed_age > seed_grow_time ) + can_be_harvested = true; + water = std::max( water, -water_max ); water = std::min( water, water_max ); fertilizer = std::max( fertilizer, 0 ); weed = std::min( weed, weed_max ); - - seed.set_var( "health", health ); - seed.set_var( "water", water ); - seed.set_var( "fertilizer", fertilizer ); - seed.set_var( "weed", weed ); - seed.set_var( "growing_was_started", growing_was_started ); - seed.set_var( "is_mature", is_mature ); } - return eff_grow_time; + seed.set_var( "health", health ); + seed.set_var( "water", water ); + seed.set_var( "fertilizer", fertilizer ); + seed.set_var( "weed", weed ); + seed.set_var( "growing_was_started", growing_was_started ); + seed.set_var( "is_mature", is_mature ); + seed.set_var( "seed_age", to_turns( seed_age ) ); + seed.set_var( "can_be_harvested", can_be_harvested ); + return; } inline void proc_weather_sum( const weather_type wtype, weather_sum &data, diff --git a/src/weather.h b/src/weather.h index be097d222be7e..2acc286fa950c 100644 --- a/src/weather.h +++ b/src/weather.h @@ -167,10 +167,9 @@ double funnel_charges_per_turn( double surface_area_mm2, double rain_depth_mm_pe time_duration get_rot_since( const time_point &start, const time_point &end, const tripoint &pos ); /** - * Get effective grow time based on the temperature, similar to get_rot_since() above. + * Update crops grow based on the temperature and weather, similar to get_rot_since() above. */ -time_duration get_crops_grow_since( const time_point &start, const time_point &end, - const tripoint &pos ); +void get_crops_grow( const tripoint &pos ); /** * Is it warm enough to plant seeds? From de8cc6f61713f15e57cf45ff926a565a3da94c8f Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 25 Aug 2018 07:40:06 +0300 Subject: [PATCH 31/35] Bugfixes for crop farming. --- data/json/furniture.json | 20 ++------ data/json/items/comestibles.json | 1 - data/json/items/comestibles/seed.json | 15 ++++-- src/iexamine.cpp | 65 +++++++++-------------- src/item_factory.cpp | 1 + src/itype.h | 4 ++ src/map.cpp | 74 +++++++++++---------------- src/map.h | 10 ++-- src/weather.cpp | 6 ++- 9 files changed, 84 insertions(+), 112 deletions(-) diff --git a/data/json/furniture.json b/data/json/furniture.json index ffdf992d4a404..df351d750d464 100644 --- a/data/json/furniture.json +++ b/data/json/furniture.json @@ -1875,7 +1875,6 @@ "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_blueberry_harvest", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1889,13 +1888,12 @@ { "type": "furniture", "id": "f_shrub_blueberry_harvest", - "name": "blueberry shrub", + "name": "blueberry shrub with berries", "symbol": "#", "color": "light_blue_green", "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_blueberry", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1915,7 +1913,6 @@ "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_strawberry_harvest", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1929,13 +1926,12 @@ { "type": "furniture", "id": "f_shrub_strawberry_harvest", - "name": "strawberry shrub", + "name": "strawberry shrub with berries", "symbol": "#", "color": "light_red_green", "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_strawberry", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1955,7 +1951,6 @@ "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_cranberry_harvest", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1969,13 +1964,12 @@ { "type": "furniture", "id": "f_shrub_cranberry_harvest", - "name": "cranberry shrub", + "name": "cranberry shrub with berries", "symbol": "#", "color": "light_red_green", "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "TRANSPARENT", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_cranberry", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -1995,7 +1989,6 @@ "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_blackberry_harvest", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -2009,13 +2002,12 @@ { "type": "furniture", "id": "f_shrub_blackberry_harvest", - "name": "blackberry bush", + "name": "blackberry bush with berries", "symbol": "#", "color": "light_red_green", "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_blackberry", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -2035,7 +2027,6 @@ "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_raspberry_harvest", "examine_action": "aggie_plant", "bash": { "str_min": 4, @@ -2049,13 +2040,12 @@ { "type": "furniture", "id": "f_shrub_raspberry_harvest", - "name": "raspberry bush", + "name": "raspberry bush with berries", "symbol": "#", "color": "light_red_green", "move_cost_mod": 2, "required_str": -1, "flags": [ "PLANT", "SEALED", "CONTAINER", "NOITEM", "TINY", "DONT_REMOVE_ROTTEN" ], - "transforms_into": "f_shrub_raspberry", "examine_action": "aggie_plant", "bash": { "str_min": 4, diff --git a/data/json/items/comestibles.json b/data/json/items/comestibles.json index 00c939715c79a..2c7838a100213 100644 --- a/data/json/items/comestibles.json +++ b/data/json/items/comestibles.json @@ -4414,7 +4414,6 @@ "price": 200, "material": "veggy", "volume": 1, - "charges": 6, "fun": -1, "flags": [ "SMOKABLE" ], "rot_spawn": "GROUP_ROTTING_PLANT" diff --git a/data/json/items/comestibles/seed.json b/data/json/items/comestibles/seed.json index 29ebf6c340acf..4c5b494b8574a 100644 --- a/data/json/items/comestibles/seed.json +++ b/data/json/items/comestibles/seed.json @@ -48,7 +48,8 @@ "grow": 91, "grow_secondary": 35, "is_shrub": true, - "grow_into": "f_shrub_blackberry_harvest" + "grow_into": "f_shrub_blackberry", + "grow_into_harvest": "f_shrub_blackberry_harvest" } }, { @@ -65,7 +66,8 @@ "grow": 91, "grow_secondary": 35, "is_shrub": true, - "grow_into": "f_shrub_blueberry_harvest" + "grow_into": "f_shrub_blueberry", + "grow_into_harvest": "f_shrub_blueberry_harvest" } }, { @@ -82,7 +84,8 @@ "grow": 91, "grow_secondary": 35, "is_shrub": true, - "grow_into": "f_shrub_cranberry_harvest" + "grow_into": "f_shrub_cranberry", + "grow_into_harvest": "f_shrub_cranberry_harvest" } }, { @@ -112,7 +115,8 @@ "grow": 91, "grow_secondary": 35, "is_shrub": true, - "grow_into": "f_shrub_raspberry_harvest" + "grow_into": "f_shrub_raspberry", + "grow_into_harvest": "f_shrub_raspberry_harvest" } }, { @@ -129,7 +133,8 @@ "grow": 91, "grow_secondary": 35, "is_shrub": true, - "grow_into": "f_shrub_strawberry_harvest" + "grow_into": "f_shrub_strawberry", + "grow_into_harvest": "f_shrub_strawberry_harvest" } }, { diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 8ff17b7f5057b..e1dfb862d78b1 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1801,30 +1801,16 @@ std::list iexamine::get_harvest_items( item &seed ) return result; } - const auto add = [&]( const itype_id & id, const int count ) { + const auto add = [&]( const itype_id & id, int count ) { item new_item( id, calendar::turn ); - if( new_item.count_by_charges() && count > 0 ) { - new_item.charges *= count; - if( new_item.charges <= 0 ) { - new_item.charges = 1; - } - result.push_back( new_item ); - } else if( count > 0 ) { - result.insert( result.begin(), count, new_item ); - } + result.insert( result.begin(), count, new_item ); }; + int health = seed.get_var( "health", 0 ); + int seed_age = seed.get_var( "seed_age", 1 ); // Multiplier for fruit yield. // Should be in range (0.1, 2), equal to 1 if plant has default health (0). - int health = seed.get_var( "health", 0 ); - time_duration seed_grow_time = 0; - if( seed.get_var( "is_mature", 0 ) ) { - seed_grow_time = seed.type->seed->grow_secondary * calendar::season_ratio(); - } else { - seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); - } - float fruit_multiplier = ( 3.0f * to_hours( seed_grow_time ) + health ) / - ( 3.0f * to_hours( seed_grow_time ) ); + float fruit_multiplier = ( seed_age / 200.0f + health ) / ( seed_age / 200.0f ); fruit_multiplier = std::max( fruit_multiplier, 0.1f ); fruit_multiplier *= calendar::season_ratio(); @@ -1832,15 +1818,19 @@ std::list iexamine::get_harvest_items( item &seed ) fruit_id = seed.type->seed->fruit_id; int fruit_count = seed.type->seed->fruit_count; fruit_count = roll_remainder( fruit_count * fruit_multiplier ); - add( fruit_id, fruit_count ); + if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) + fruit_count = std::max( fruit_count, 1 ); + if( fruit_count ) + add( fruit_id, fruit_count ); + std::string seed_id; + seed_id = seed.type->seed->seed_id; int seed_count = seed.type->seed->seed_count; seed_count = roll_remainder( seed_count * fruit_multiplier ); - if( seed_count ) { - std::string seed_id; - seed_id = seed.type->seed->seed_id; + if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) + seed_count = std::max( seed_count, 1 ); + if( seed_count ) add( seed_id, seed_count ); - } for( auto &b : seed.type->seed->byproducts ) { add( b, 1 ); @@ -1857,18 +1847,12 @@ void iexamine::proceed_plant_after_harvest( const int x, const int y, const int void iexamine::proceed_plant_after_harvest( const tripoint &examp ) { item &seed = g->m.i_at( examp ).front(); - if( g->m.furn( examp ) == f_mushroom_mature_harvest ) { - // Mushrooms + if( seed.type->seed->is_mushroom || seed.type->seed->is_shrub ) { + // Mushrooms and berries seed.set_var( "seed_age", 1 ); - seed.set_birthday( calendar::turn ); seed.set_var( "can_be_harvested", 0 ); - g->m.furn_set( examp, f_mushroom_mature ); - } else if( seed.type->seed->is_shrub && seed.get_var( "can_be_harvested", 0 ) ) { - // Berries - seed.set_var( "seed_age", 1 ); - seed.set_birthday( calendar::turn ); - seed.set_var( "can_be_harvested", 0 ); - g->m.furn_set( examp, g->m.get_furn_transforms_into( examp ) ); + seed.set_var( "last_grow_check", to_turn( calendar::turn ) ); + g->m.grow_plant( examp ); } else { // Generic seed g->m.i_clear( examp ); @@ -1890,7 +1874,7 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) return; } - get_crops_grow( examp ); + g->m.grow_plant( examp ); const std::string pname = seed.get_plant_name(); if( ( g->m.furn( examp ) == f_plant_harvest || seed.get_var( "can_be_harvested", 0 ) ) && @@ -1928,6 +1912,7 @@ void iexamine::aggie_plant( player &p, const tripoint &examp ) } } p.moves -= 500; + return; } } else { int health = seed.get_var( "health", 0 ); @@ -4245,7 +4230,7 @@ void iexamine::smoker_options( player &p, const tripoint &examp ) int char_quantity = 0; bool f_check = false; bool c_check = false; - + for( size_t i = 0; i < items_here.size(); i++ ) { auto &it = items_here[i]; if( it.is_food() ) { @@ -4261,7 +4246,7 @@ void iexamine::smoker_options( player &p, const tripoint &examp ) minutes_left = to_minutes( time_left ) + 1; } } - + uimenu smenu; smenu.text = _( "What to do with the smoking rack:" ); smenu.return_invalid = true; @@ -4309,7 +4294,7 @@ void iexamine::smoker_options( player &p, const tripoint &examp ) } } else { pop << "" << _( "There's a smoking rack here." ) << "" << "\n"; - } + } pop << "" << _( "You inspect it's contents and find: " ) << "" << "\n \n "; if( items_here.empty() ) { pop << "... that it is empty."; @@ -4320,11 +4305,11 @@ void iexamine::smoker_options( player &p, const tripoint &examp ) pop << "\n " << "" << _( "You see some smoldering embers there." ) << "" << "\n "; continue; } - pop << "-> " << it.nname( it.typeId(), count_charges_in_list( it.type, items_here ) ); + pop << "-> " << it.nname( it.typeId(), count_charges_in_list( it.type, items_here ) ); pop << " (" << std::to_string( count_charges_in_list( it.type, items_here ) ) << ") \n "; } } - popup( pop.str(), PF_NONE ); + popup( pop.str(), PF_NONE ); break; } case 1: //activate diff --git a/src/item_factory.cpp b/src/item_factory.cpp index e3c9472f818ef..185a7adb404d2 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1603,6 +1603,7 @@ void Item_factory::load( islot_seed &slot, JsonObject &jo, const std::string & ) slot.water_requirement = jo.get_float( "water_requirement", 1.0f ); slot.weed_susceptibility = jo.get_float( "weed_susceptibility", 1.0f ); slot.grow_into = jo.get_string( "grow_into", "" ); + slot.grow_into_harvest = jo.get_string( "grow_into_harvest", "" ); slot.is_mushroom = jo.get_bool( "is_mushroom", false ); slot.is_shrub = jo.get_bool( "is_shrub", false ); } diff --git a/src/itype.h b/src/itype.h index 0fe5f4b51f353..37fa69256ba20 100644 --- a/src/itype.h +++ b/src/itype.h @@ -660,6 +660,10 @@ struct islot_seed { * ID of the shrub this plant will grow into. */ std::string grow_into; + /** + * ID of the shrub (with berries) this plant will grow into. + */ + std::string grow_into_harvest; /** * Additionally items (a list of their item ids) that will spawn when harvesting the plant. */ diff --git a/src/map.cpp b/src/map.cpp index 62c645456668a..9b6a446b590f6 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1451,10 +1451,6 @@ void map::furn_set(const int x, const int y, const furn_id new_furniture) furn_set( tripoint( x, y, abs_sub.z ), new_furniture ); } -furn_id map::get_furn_transforms_into( const tripoint &p ) const { - return furn( p ).obj().transforms_into.id(); -} - // End of 2D overloads for furniture void map::set( const tripoint &p, const ter_id new_terrain, const furn_id new_furniture) @@ -6865,15 +6861,13 @@ void map::grow_plant( const tripoint &p ) if( !furn.has_flag( "PLANT" ) ) { return; } - auto items = i_at( p ); - if( items.empty() ) { + if( i_at( p ).empty() ) { // No seed there anymore, we don't know what kind of plant it was. dbg( D_ERROR ) << "a seed item has vanished at " << p.x << "," << p.y << "," << p.z; furn_set( p, f_null ); return; } - - auto seed = items.front(); + item &seed = i_at( p ).front(); if( !seed.is_seed() ) { // No seed there anymore, we don't know what kind of plant it was. dbg( D_ERROR ) << "a planted item at " << p.x << "," << p.y << "," << p.z << " has no seed data"; @@ -6882,14 +6876,13 @@ void map::grow_plant( const tripoint &p ) } get_crops_grow( p ); - item &seed_item = i_at( p ).front(); - const time_duration plantEpoch = seed_item.get_plant_epoch(); - time_duration seed_age = time_duration::from_turns( seed_item.get_var( "seed_age", 1 ) ); + const time_duration plantEpoch = seed.get_plant_epoch(); + time_duration seed_age = time_duration::from_turns( seed.get_var( "seed_age", 1 ) ); - furn_id cur_furn = this->furn(p).id(); + furn_id cur_furn = this->furn( p ).id(); // The plant have died - if( seed_item.get_var( "frozen", 0 ) > 0 ) { + if( seed.get_var( "frozen", 0 ) > 0 ) { i_clear( p ); furn_set( p, f_null ); if( rng( 0, 1 ) > 0 ) { @@ -6898,47 +6891,47 @@ void map::grow_plant( const tripoint &p ) return; } - if( seed_item.type->seed->is_mushroom ) { - // Mushroom bed grow - if( cur_furn != furn_str_id( "f_mushroom_mature" ) && - cur_furn != furn_str_id( "f_mushroom_mature_harvest" ) ) { - if( seed_age >= plantEpoch && seed_age < plantEpoch * 3 ) { - furn_set(p, furn_str_id( "f_mushroom_seedling" ) ); - } else if( seed_age >= plantEpoch * 3 ) { - furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); - seed_item.set_var( "is_mature", 1 ); - seed_item.set_var( "can_be_harvested", 1 ); - } - } - // Mushrooms grow on beds - if( seed_item.get_var( "is_mature", 0 ) && seed_item.get_var( "can_be_harvested", 0 ) ) { - furn_set(p, furn_str_id( "f_mushroom_mature_harvest" ) ); + // Mushrooms + if( seed.type->seed->is_mushroom ) { + if( seed.get_var( "can_be_harvested", 0 ) ) { + furn_set( p, furn_str_id( "f_mushroom_mature_harvest" ) ); + } else if( seed.get_var( "is_mature", 0 ) ) { + furn_set( p, furn_str_id( "f_mushroom_mature" ) ); + } else if( seed_age > plantEpoch ) { + furn_set( p, furn_str_id( "f_mushroom_seedling" ) ); + } else { + furn_set( p, furn_str_id( "f_mushroom_seed" ) ); } return; } - // Grow berries on shrubs - if( seed_item.type->seed->is_shrub && seed_item.get_var( "is_mature", 0 ) && - seed_item.get_var( "can_be_harvested", 0 ) ) { - const auto &furn_obj = this->furn( p ).obj(); - furn_set( p, furn_obj.transforms_into ); - return; + // Mature shrubs + if( seed.type->seed->is_shrub && seed.get_var( "is_mature", 0 ) ) { + if( seed.get_var( "can_be_harvested", 0 ) ){ + furn_set( p, furn_str_id( seed.type->seed->grow_into_harvest ) ); + } else { + furn_set( p, furn_str_id( seed.type->seed->grow_into ) ); + } + return; } // Normal plant grow + if( seed.get_var( "can_be_harvested", 0 ) ) { + furn_set( p, furn_str_id( "f_plant_harvest" ) ); + return; + } + if( seed_age >= plantEpoch && cur_furn != furn_str_id( "f_plant_harvest" ) ) { if( seed_age < plantEpoch * 2 ) { if( cur_furn == furn_str_id( "f_plant_seedling" ) ) { return; } - i_rem( p, 1 ); rotten_item_spawn( seed, p ); furn_set(p, furn_str_id( "f_plant_seedling" ) ); } else if( seed_age < plantEpoch * 3 ) { if( cur_furn == furn_str_id( "f_plant_mature" ) ) { return; } - i_rem(p, 1); rotten_item_spawn( seed, p ); //You've skipped the seedling stage so roll monsters twice if( cur_furn != furn_str_id( "f_plant_seedling" ) ) { @@ -6959,14 +6952,7 @@ void map::grow_plant( const tripoint &p ) rotten_item_spawn( seed, p ); rotten_item_spawn( seed, p ); } - // Plant grow into shrub - if ( seed_item.type->seed->is_shrub ) { - furn_set( p, furn_str_id( seed_item.type->seed->grow_into ) ); - seed_item.set_var( "is_mature", 1 ); - seed_item.set_var( "can_be_harvested", 1 ); - return; - } - furn_set(p, furn_str_id( "f_plant_harvest" ) ); + furn_set( p, furn_str_id( "f_plant_harvest" ) ); } } } diff --git a/src/map.h b/src/map.h index 9ebbb034feec3..242d331e901ae 100644 --- a/src/map.h +++ b/src/map.h @@ -544,8 +544,6 @@ class map // Furniture at coordinates (x, y); {x|y}=(0, SEE{X|Y}*3] furn_id furn( const int x, const int y ) const; - furn_id get_furn_transforms_into( const tripoint &p ) const; - void furn_set( const int x, const int y, const furn_id new_furniture ); std::string furnname( const int x, const int y ); @@ -1270,6 +1268,10 @@ class map * If false, monsters are not spawned in view of player character. */ void spawn_monsters( bool ignore_sight ); + /** + * Try to grow a harvestable plant to the next stage(s). + */ + void grow_plant( const tripoint &p ); private: // Helper #1 - spawns monsters on one submap void spawn_monsters_submap( const tripoint &gp, bool ignore_sight ); @@ -1316,10 +1318,6 @@ class map * @param p The location in this map where to fill funnels. */ void fill_funnels( const tripoint &p, const time_point &since ); - /** - * Try to grow a harvestable plant to the next stage(s). - */ - void grow_plant( const tripoint &p ); /** * Try to grow fruits on static plants (not planted by the player) * @param p Place to restock diff --git a/src/weather.cpp b/src/weather.cpp index b5543f78ea947..8ac4791f83ff8 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -114,6 +114,7 @@ void get_crops_grow( const tripoint &location ) float water_requirement = seed.type->seed->water_requirement; float weed_susceptibility = seed.type->seed->weed_susceptibility; bool is_mushroom = seed.type->seed->is_mushroom; + bool is_shrub = seed.type->seed->is_shrub; /* 1L = 10 units of water @@ -241,8 +242,11 @@ void get_crops_grow( const tripoint &location ) } else { seed_grow_time = seed.type->seed->grow * calendar::season_ratio(); } - if( seed_age > seed_grow_time ) + if( seed_age > seed_grow_time ) { can_be_harvested = true; + if( is_mushroom || is_shrub ) + is_mature = true; + } water = std::max( water, -water_max ); water = std::min( water, water_max ); From 3b959a42bbebd33fce5b1ae6f54cdcada78a3e93 Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sat, 25 Aug 2018 08:01:23 +0300 Subject: [PATCH 32/35] Bugfixes for crop farming. --- src/vehicle_use.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index fb7fa38573e99..727f755c5744e 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -932,14 +932,12 @@ void vehicle::operate_reaper() const tripoint &veh_start = global_pos3(); for( const int reaper_id : all_parts_with_feature( "REAPER" ) ) { const tripoint reaper_pos = veh_start + parts[ reaper_id ].precalc[ 0 ]; - const int plant_produced = rng( 1, parts[ reaper_id ].info().bonus ); - const int seed_produced = rng( 1, 3 ); const units::volume max_pickup_volume = parts[ reaper_id ].info().size / 20; if( g->m.furn( reaper_pos ) != f_plant_harvest || !g->m.has_items( reaper_pos ) ) { continue; } - const item &seed = g->m.i_at( reaper_pos ).front(); + item& seed = g->m.i_at( reaper_pos ).front(); if( seed.typeId() == "fungal_seeds" || seed.typeId() == "marloss_seed" ) { // Otherworldly plants, the earth-made reaper can not handle those. @@ -947,8 +945,7 @@ void vehicle::operate_reaper() } g->m.furn_set( reaper_pos, f_null ); g->m.i_clear( reaper_pos ); - for( auto &i : iexamine::get_harvest_items( - *seed.type, plant_produced, seed_produced, false ) ) { + for( auto &i : iexamine::get_harvest_items( seed ) ) { g->m.add_item_or_charges( reaper_pos, i ); } sounds::sound( reaper_pos, rng( 10, 25 ), _( "Swish" ) ); From bdfb4a8386261389a737441f3de8c26932302b8f Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Sat, 25 Aug 2018 21:37:09 +0300 Subject: [PATCH 33/35] Astyle to make Jenkins happy --- src/vehicle_use.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 727f755c5744e..c6c56386fd159 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -937,7 +937,7 @@ void vehicle::operate_reaper() !g->m.has_items( reaper_pos ) ) { continue; } - item& seed = g->m.i_at( reaper_pos ).front(); + item &seed = g->m.i_at( reaper_pos ).front(); if( seed.typeId() == "fungal_seeds" || seed.typeId() == "marloss_seed" ) { // Otherworldly plants, the earth-made reaper can not handle those. From a728c1c84888e4da827fc4e5b29bc8b82daef03f Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sun, 26 Aug 2018 11:12:39 +0300 Subject: [PATCH 34/35] Minor bugfix for crop farming. --- src/iexamine.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index b5f4f4c392615..5842918e3f9b7 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1759,20 +1759,24 @@ std::list iexamine::get_harvest_items( item &seed ) std::string fruit_id; fruit_id = seed.type->seed->fruit_id; int fruit_count = seed.type->seed->fruit_count; - fruit_count = roll_remainder( fruit_count * fruit_multiplier ); - if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) - fruit_count = std::max( fruit_count, 1 ); - if( fruit_count ) - add( fruit_id, fruit_count ); + if( fruit_count ) { + fruit_count = roll_remainder( fruit_count * fruit_multiplier ); + if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) + fruit_count = std::max( fruit_count, 1 ); + if( fruit_count ) + add( fruit_id, fruit_count ); + } std::string seed_id; seed_id = seed.type->seed->seed_id; int seed_count = seed.type->seed->seed_count; - seed_count = roll_remainder( seed_count * fruit_multiplier ); - if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) - seed_count = std::max( seed_count, 1 ); - if( seed_count ) - add( seed_id, seed_count ); + if( seed_count ) { + seed_count = roll_remainder( seed_count * fruit_multiplier ); + if( !seed.type->seed->is_mushroom && !seed.type->seed->is_shrub ) + seed_count = std::max( seed_count, 1 ); + if( seed_count ) + add( seed_id, seed_count ); + } for( auto &b : seed.type->seed->byproducts ) { add( b, 1 ); @@ -4229,7 +4233,7 @@ void iexamine::smoker_options( player &p, const tripoint &examp ) } } else { pop << "" << _( "There's a smoking rack here." ) << "" << "\n"; - } + } pop << "" << _( "You inspect its contents and find: " ) << "" << "\n \n "; if( items_here.empty() ) { pop << "... that it is empty."; From 0ff00d571a5266732538eee36a647b1e1f4e47ea Mon Sep 17 00:00:00 2001 From: vasyan2006 Date: Sun, 26 Aug 2018 16:14:54 +0300 Subject: [PATCH 35/35] Using game constant for freezing temperature. --- src/weather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/weather.cpp b/src/weather.cpp index 725ae848f82ad..430a3fcb6e3bb 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -909,7 +909,7 @@ int get_local_windpower(double windpower, const oter_id &omter, bool sheltered) bool warm_enough_to_plant() { // It is possible but not recommended to plant at the temperature of the ice melting - return g->get_temperature( g-> u.pos() ) >= 32; + return g->get_temperature( g-> u.pos() ) >= FREEZING_TEMPERATURE; }