From b43040bb2595a1a9d12ed8ba4e0ba759ee8b7c57 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 6 Aug 2018 11:12:47 -0500 Subject: [PATCH 1/4] better milking: keep the cow in place while milking milking is an extended action, so keep the cow from wandering off while you milk it. --- src/game.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/game.cpp b/src/game.cpp index e1dce04600c60..37f1492c027b7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -7164,7 +7164,18 @@ bool pet_menu(monster *z) } if( milk == choice ) { + // pin the cow in place if it isn't already + bool temp_tie = !z->has_effect( effect_tied ); + if( temp_tie ) { + z->add_effect( effect_tied, 1_turns, num_bp, true); + } + monexamine::milk_source( *z ); + + if( temp_tie ) { + z->remove_effect( effect_tied ); + } + return true; } From 228f3df3715b381909cd5b5494bc28fa92a21c4d Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 6 Aug 2018 11:17:36 -0500 Subject: [PATCH 2/4] better milking: don't use source_mon for fill_liquid_do_turn it's trivial to return the amount of resources consumed when passing an item as the source to fill_liquid_do_turn, and nearly impossible when passing a monster. Since monexamine::milk_source is the only code that passes a source_mon to handle_liquid and then on to fill_liquid_do_turn, simplify life by not passing the source_mon from handle_liquid to fill_liquid_do_turn. Instead, fill_liquid_do_turn takes the milk item that was already being created my milk_source as the source of the transfer liquid activity. --- src/game.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 37f1492c027b7..d6df7774bde25 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -9470,10 +9470,6 @@ bool game::handle_liquid( item &liquid, item * const source, const int radius, u.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); serialize_liquid_source( u.activity, *source_pos, liquid ); return true; - } else if( source_mon != nullptr ) { - u.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); - serialize_liquid_source( u.activity, *source_mon, liquid ); - return true; } else { return false; } From c048b6aa3c16a9226205ed609c8f22b6d88c5542 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 6 Aug 2018 11:23:59 -0500 Subject: [PATCH 3/4] better milking: rewrite milk_source rename milk_per_day to milk_freq, since it's a duration, not a count. remove the redundant check that the milk item is LIQUID - handle_liquid will do that. check the return from handle_liquid, so you don't lose milk if you cancel out of the container selection. increase the size of the milk item to the number of remaining units of milk in the creature. Set the duration of the effect_milked equal to the count of milk units transferred in handle_liquid. Net effect is that a survivor can remove all the milk in a creature in a single long action, if they have a large enough container. --- src/monexamine.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 120fc93b7121d..6ca893642ab18 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -13,26 +13,22 @@ const efftype_id effect_milked( "milked" ); void monexamine::milk_source( monster &source_mon ) { const auto milked_item = source_mon.type->starting_ammo; - item milk( milked_item.begin()->first, calendar::turn, 1 ); + const long milk_per_day = milked_item.begin()->second; + const time_duration milking_freq = 1_days / milk_per_day; - // Milked items must be liquids. - if( !milk.made_of( LIQUID ) ) { - debugmsg( "milked item must be a liquid" ); - } else { - - const time_duration milk_per_day = 1_days / milked_item.begin()->second; - - if( !source_mon.has_effect( effect_milked ) ) { - g->handle_liquid( milk, nullptr, 0, nullptr, nullptr, &source_mon ); - source_mon.add_effect( effect_milked, milk_per_day ); - add_msg( _( "You milk the %s." ), source_mon.get_name().c_str() ); + long remaining_milk = milk_per_day; + if( source_mon.has_effect( effect_milked ) ) { + remaining_milk -= source_mon.get_effect_dur( effect_milked ) / milking_freq; + } - } else if( 1_days - source_mon.get_effect_dur( effect_milked ) >= milk_per_day ) { - source_mon.add_effect( effect_milked, milk_per_day ); - g->handle_liquid( milk, nullptr, 0, nullptr, nullptr, &source_mon ); + if( remaining_milk > 0 ) { + item milk( milked_item.begin()->first, calendar::turn, remaining_milk ); + if( g->handle_liquid( milk, nullptr, 1, nullptr, nullptr, &source_mon ) ) { add_msg( _( "You milk the %s." ), source_mon.get_name().c_str() ); - } else { - add_msg( _( "The %s's udders run dry." ), source_mon.get_name().c_str() ); + long transferred_milk = remaining_milk - milk.charges; + source_mon.add_effect( effect_milked, milking_freq * transferred_milk ); } + } else { + add_msg( _( "The %s's udders run dry." ), source_mon.get_name().c_str() ); } } From 9a024689117a1d20b199a223594ed725def5ba8d Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Tue, 7 Aug 2018 09:42:39 -0500 Subject: [PATCH 4/4] better milking: have milking take time Milking takes 2 minutes per 10 units of milk transferred. This isn't an entirely satisfactory solution, but redoing the handle_liquid interface and adding a milking activity is beyond the scope of this PR. --- src/monexamine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 6ca893642ab18..7af55035fd2ea 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -6,6 +6,7 @@ #include "messages.h" #include "mtype.h" #include "calendar.h" +#include "player.h" #include const efftype_id effect_milked( "milked" ); @@ -27,6 +28,7 @@ void monexamine::milk_source( monster &source_mon ) add_msg( _( "You milk the %s." ), source_mon.get_name().c_str() ); long 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 ) ); } } else { add_msg( _( "The %s's udders run dry." ), source_mon.get_name().c_str() );