From 5e80f8db5a18403978432056fa165e28694c759d Mon Sep 17 00:00:00 2001 From: dpwb Date: Wed, 29 Jan 2020 20:48:48 +0000 Subject: [PATCH 1/3] change milking to an activity, restore udders every day erroneous edit to mtype.h from review: use iterator instead of map directly add check for udders being empty in milk_finish add serialization for udder timer from review : const int and use iterator instead of map directly add checking for temp_tie effect removal Update src/activity_handlers.cpp Co-Authored-By: BevapDin --- data/json/effects.json | 7 ------ data/json/monsters/mammal.json | 4 ++-- data/json/player_activities.json | 10 ++++++++ src/activity_handlers.cpp | 41 ++++++++++++++++++++++++++++++++ src/activity_handlers.h | 1 + src/cata_string_consts.h | 1 + src/game.cpp | 6 ++++- src/monexamine.cpp | 33 +++++++------------------ src/monster.cpp | 24 +++++++++++++++++++ src/monster.h | 2 ++ src/savegame_json.cpp | 3 +++ 11 files changed, 98 insertions(+), 34 deletions(-) diff --git a/data/json/effects.json b/data/json/effects.json index cc3042f2e3e3f..607ff17ab2cdb 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -1679,13 +1679,6 @@ "max_duration": "2 s", "rating": "bad" }, - { - "type": "effect_type", - "id": "milked", - "name": [ "Milked" ], - "desc": [ "The creature has been partially or fully milked." ], - "max_duration": "1 d" - }, { "type": "effect_type", "id": "pkill", diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index 490c7e982f184..fbf765a46540e 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -313,7 +313,7 @@ "melee_cut": 6, "dodge": 2, "armor_bash": 2, - "starting_ammo": { "milk_raw": 10 }, + "starting_ammo": { "milk_raw": 40 }, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT" ], "fear_triggers": [ "PLAYER_CLOSE" ], @@ -1845,7 +1845,7 @@ "melee_dice_sides": 6, "melee_cut": 2, "dodge": 2, - "starting_ammo": { "milk_raw": 2 }, + "starting_ammo": { "milk_raw": 5 }, "anger_triggers": [ ], "harvest": "mammal_large_wool", "reproduction": { "baby_monster": "mon_sheep_lamb", "baby_count": 1, "baby_timer": 275 }, diff --git a/data/json/player_activities.json b/data/json/player_activities.json index 465dc03b5b104..70dc3f9ef87b7 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -448,6 +448,16 @@ "based_on": "neither", "no_resume": true }, + { + "id": "ACT_MILK", + "type": "activity_type", + "activity_level": "LIGHT_EXERCISE", + "verb": "milking an animal", + "suspendable": false, + "rooted": true, + "based_on": "time", + "no_resume": true + }, { "id": "ACT_HOTWIRE_CAR", "type": "activity_type", diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 566dd08d0a9e6..8a26ada905573 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -224,6 +224,7 @@ activity_handlers::finish_functions = { { ACT_WASH, washing_finish }, { ACT_HACKSAW, hacksaw_finish }, { ACT_CHOP_TREE, chop_tree_finish }, + { ACT_MILK, milk_finish }, { ACT_CHOP_LOGS, chop_logs_finish }, { ACT_CHOP_PLANKS, chop_planks_finish }, { ACT_JACKHAMMER, jackhammer_finish }, @@ -1274,6 +1275,46 @@ void activity_handlers::butcher_finish( player_activity *act, player *p ) resume_for_multi_activities( *p ); } +void activity_handlers::milk_finish( player_activity *act, player *p ) +{ + if( act->coords.empty() ) { + debugmsg( "milking activity with no position of monster stored" ); + return; + } + const tripoint source_pos = g->m.getlocal( act->coords.at( 0 ) ); + monster *source_mon = g->critter_at( source_pos ); + monster *source_mon = dynamic_cast( c ); + if( source_mon == nullptr ) { + debugmsg( "could not find source creature for liquid transfer" ); + return; + } + auto milked_item = source_mon->ammo.find( "milk_raw" ); + if( milked_item == source_mon->ammo.end() ) { + debugmsg( "animal has no milk ammo type" ); + return; + } + if( milked_item->second <= 0 ) { + debugmsg( "started milking but udders are now empty before milking finishes" ); + return; + } + item milk( milked_item->first, calendar::turn, milked_item->second ); + milk.set_item_temperature( 311.75 ); + if( liquid_handler::handle_liquid( milk, nullptr, 1, nullptr, nullptr, -1, source_mon ) ) { + milked_item->second = 0; + if( milk.charges > 0 ) { + milked_item->second = milk.charges; + } else { + p->add_msg_if_player( _( "The %s's udders run dry." ), source_mon->get_name() ); + } + } + // if the monster was not manually tied up, but needed to be fixed in place temporarily then + // remove that now. + if( !act->str_values.empty() && act->str_values[0] == "temp_tie" ) { + source_mon->remove_effect( effect_tied ); + } + act->set_to_null(); +} + void activity_handlers::fill_liquid_do_turn( player_activity *act, player *p ) { player_activity &act_ref = *act; diff --git a/src/activity_handlers.h b/src/activity_handlers.h index 7dc75f5f06cea..060a2be6716bc 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -206,6 +206,7 @@ void pickaxe_finish( player_activity *act, player *p ); void reload_finish( player_activity *act, player *p ); void start_fire_finish( player_activity *act, player *p ); void train_finish( player_activity *act, player *p ); +void milk_finish( player_activity *act, player *p ); void vehicle_finish( player_activity *act, player *p ); void start_engines_finish( player_activity *act, player *p ); void churn_finish( player_activity *act, player *p ); diff --git a/src/cata_string_consts.h b/src/cata_string_consts.h index fcea763f967d9..5b55d35f580a2 100644 --- a/src/cata_string_consts.h +++ b/src/cata_string_consts.h @@ -36,6 +36,7 @@ static const activity_id ACT_FERTILIZE_PLOT( "ACT_FERTILIZE_PLOT" ); static const activity_id ACT_FETCH_REQUIRED( "ACT_FETCH_REQUIRED" ); static const activity_id ACT_FIELD_DRESS( "ACT_FIELD_DRESS" ); static const activity_id ACT_FILL_LIQUID( "ACT_FILL_LIQUID" ); +static const activity_id ACT_MILK( "ACT_MILK" ); static const activity_id ACT_FILL_PIT( "ACT_FILL_PIT" ); static const activity_id ACT_FIND_MOUNT( "ACT_FIND_MOUNT" ); static const activity_id ACT_FIRSTAID( "ACT_FIRSTAID" ); diff --git a/src/game.cpp b/src/game.cpp index 46ab2dbb8efea..13f053823e930 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4111,7 +4111,11 @@ void game::monmove() } m.creature_in_field( critter ); - + if( calendar::once_every( 1_days ) ) { + critter.refill_udders(); + critter.try_biosignature(); + critter.try_reproduce(); + } while( critter.moves > 0 && !critter.is_dead() && !critter.has_effect( effect_ridden ) ) { critter.made_footstep = false; // Controlled critters don't make their own plans diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 469a8791d48a4..9b358da1ddb7b 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -668,39 +668,24 @@ void monexamine::tie_or_untie( monster &z ) void monexamine::milk_source( monster &source_mon ) { - const auto milked_item = source_mon.type->starting_ammo.find( "milk_raw" ); - if( milked_item == source_mon.type->starting_ammo.end() ) { + const auto milked_item = source_mon.ammo.find( "milk_raw" ); + if( milked_item == source_mon.ammo.end() ) { debugmsg( "%s is milkable but has no milk in its starting ammo!", source_mon.get_name() ); return; } - const int milk_per_day = milked_item->second; - const time_duration milking_freq = 1_days / milk_per_day; - - int remaining_milk = milk_per_day; - if( source_mon.has_effect( effect_milked ) ) { - remaining_milk -= source_mon.get_effect_dur( effect_milked ) / milking_freq; - } - - if( remaining_milk > 0 ) { + if( milked_item->second > 0 ) { + const int moves = to_moves( time_duration::from_minutes( milked_item->second / 2 ) ); + g->u.assign_activity( ACT_MILK, moves, -1 ); + g->u.activity.coords.push_back( g->m.getabs( source_mon.pos() ) ); // pin the cow in place if it isn't already bool temp_tie = !source_mon.has_effect( effect_tied ); if( temp_tie ) { source_mon.add_effect( effect_tied, 1_turns, num_bp, true ); + g->u.activity.str_values.push_back( "temp_tie" ); } - - item milk( milked_item->first, calendar::turn, remaining_milk ); - milk.set_item_temperature( 311.75 ); - if( liquid_handler::handle_liquid( milk, nullptr, 1, nullptr, nullptr, -1, &source_mon ) ) { - add_msg( _( "You milk the %s." ), source_mon.get_name() ); - int transferred_milk = remaining_milk - milk.charges; - source_mon.add_effect( effect_milked, milking_freq * transferred_milk ); - g->u.mod_moves( -to_moves( transferred_milk * 1_minutes / 5 ) ); - } - if( temp_tie ) { - source_mon.remove_effect( effect_tied ); - } + add_msg( _( "You milk the %s." ), source_mon.get_name() ); } else { - add_msg( _( "The %s's udders run dry." ), source_mon.get_name() ); + add_msg( _( "The %s has no more milk." ), source_mon.get_name() ); } } diff --git a/src/monster.cpp b/src/monster.cpp index 56539f1e6d6b1..1a1594433b278 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -105,6 +105,7 @@ monster::monster() upgrade_time = -1; last_updated = 0; biosig_timer = -1; + udder_timer = calendar::turn; horde_attraction = MHA_NULL; } @@ -359,6 +360,28 @@ void monster::try_reproduce() } } +void monster::refill_udders() +{ + if( !has_flag( MF_MILKABLE ) ) { + return; + } + const auto milked_item = type->starting_ammo.find( "milk_raw" ); + auto current_milk = ammo.find( "milk_raw" ); + if( milked_item == type->starting_ammo.end() || current_milk == ammo.end() ) { + debugmsg( "%s is milkable but has no milk in its starting ammo!", get_name() ); + return; + } + if( current_milk->second == milked_item->second ) { + // already full up + return; + } + if( calendar::turn - udder_timer > 1_days ) { + // no point granularizing this really, you milk once a day. + current_milk->second = milked_item->second; + udder_timer = calendar::turn; + } +} + void monster::try_biosignature() { if( !biosignatures ) { @@ -2793,6 +2816,7 @@ void monster::on_load() try_upgrade( false ); try_reproduce(); try_biosignature(); + refill_udders(); const time_duration dt = calendar::turn - last_updated; last_updated = calendar::turn; diff --git a/src/monster.h b/src/monster.h index df1b4ec38b1b7..e39b29e828f97 100644 --- a/src/monster.h +++ b/src/monster.h @@ -107,6 +107,7 @@ class monster : public Creature void try_upgrade( bool pin_time ); void try_reproduce(); void try_biosignature(); + void refill_udders(); void spawn( const tripoint &p ); m_size get_size() const override; units::mass get_weight() const override; @@ -548,6 +549,7 @@ class monster : public Creature cata::optional baby_timer; bool biosignatures; cata::optional biosig_timer; + time_point udder_timer; monster_horde_attraction horde_attraction; /** Found path. Note: Not used by monsters that don't pathfind! **/ std::vector path; diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 43572a2f0a278..6a05dadb5dfa0 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1926,6 +1926,8 @@ void monster::load( const JsonObject &data ) biosignatures = data.get_bool( "biosignatures", type->biosignatures ); biosig_timer = data.get_int( "biosig_timer", -1 ); + data.read( "udder_timer", udder_timer ); + horde_attraction = static_cast( data.get_int( "horde_attraction", 0 ) ); data.read( "inv", inv ); @@ -2008,6 +2010,7 @@ void monster::store( JsonOut &json ) const json.member( "baby_timer", baby_timer ); json.member( "biosignatures", biosignatures ); json.member( "biosig_timer", biosig_timer ); + json.member( "udder_timer", udder_timer ); json.member( "summon_time_limit", summon_time_limit ); From 8cef49007d970507e1d8c4ee87e6d6f2563ad756 Mon Sep 17 00:00:00 2001 From: dpwb Date: Thu, 30 Jan 2020 09:09:29 +0000 Subject: [PATCH 2/3] duplicate definition --- src/activity_handlers.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 8a26ada905573..683ad2af7bb6a 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -1283,7 +1283,6 @@ void activity_handlers::milk_finish( player_activity *act, player *p ) } const tripoint source_pos = g->m.getlocal( act->coords.at( 0 ) ); monster *source_mon = g->critter_at( source_pos ); - monster *source_mon = dynamic_cast( c ); if( source_mon == nullptr ) { debugmsg( "could not find source creature for liquid transfer" ); return; From 4f3783d0ef53317268fa3836e2d96174a64a3b6c Mon Sep 17 00:00:00 2001 From: dpwb Date: Sat, 1 Feb 2020 14:58:21 +0000 Subject: [PATCH 3/3] restore milked effect --- data/json/effects.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data/json/effects.json b/data/json/effects.json index 607ff17ab2cdb..cce60f6e1c55e 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -1679,6 +1679,13 @@ "max_duration": "2 s", "rating": "bad" }, + { + "type": "effect_type", + "id": "milked", + "name": [ "Milked" ], + "desc": [ "The creature has been partially or fully milked." ], + "max_duration": "1 d" + }, { "type": "effect_type", "id": "pkill",