From 76755c74cb589fc89deb22c5e3b786101a278c6e Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Tue, 4 Jun 2019 20:05:49 -0400 Subject: [PATCH] move vomit and adjacent_tile --- src/avatar.cpp | 16 ++++++++++ src/avatar.h | 2 ++ src/character.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++ src/character.h | 5 +++ src/player.cpp | 78 ----------------------------------------------- src/player.h | 4 --- 6 files changed, 100 insertions(+), 82 deletions(-) diff --git a/src/avatar.cpp b/src/avatar.cpp index db8c3b53f1a81..4cfedc682a445 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -999,3 +999,19 @@ void avatar::wake_up() } Character::wake_up(); } + +void avatar::vomit() +{ + if( stomach.contains() != 0_ml ) { + // Remove all joy from previously eaten food and apply the penalty + rem_morale( MORALE_FOOD_GOOD ); + rem_morale( MORALE_FOOD_HOT ); + rem_morale( MORALE_HONEY ); // bears must suffer too + add_morale( MORALE_VOMITED, -2 * units::to_milliliter( stomach.contains() / 50 ), -40, 90_minutes, + 45_minutes, false ); // 1.5 times longer + + } else { + add_msg( m_warning, _( "You retched, but your stomach is empty." ) ); + } + Character::vomit(); +} diff --git a/src/avatar.h b/src/avatar.h index d2ddca16c64e4..24191e73cde00 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -93,6 +93,8 @@ class avatar : public player hint_rating rate_action_read( const item &it ) const; void wake_up(); + /** Handles player vomiting effects */ + void vomit(); private: map_memory player_map_memory; bool show_map_memory; diff --git a/src/character.cpp b/src/character.cpp index a8db891b20f72..98dfb0a9f0edf 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -35,6 +35,7 @@ #include "sounds.h" #include "string_formatter.h" #include "translations.h" +#include "trap.h" #include "veh_interact.h" #include "vehicle.h" #include "vehicle_selector.h" @@ -58,6 +59,8 @@ const efftype_id effect_crushed( "crushed" ); const efftype_id effect_darkness( "darkness" ); const efftype_id effect_disinfected( "disinfected" ); const efftype_id effect_downed( "downed" ); +const efftype_id effect_drunk( "drunk" ); +const efftype_id effect_foodpoison( "foodpoison" ); const efftype_id effect_grabbed( "grabbed" ); const efftype_id effect_heavysnare( "heavysnare" ); const efftype_id effect_infected( "infected" ); @@ -65,7 +68,11 @@ const efftype_id effect_in_pit( "in_pit" ); const efftype_id effect_lightsnare( "lightsnare" ); const efftype_id effect_lying_down( "lying_down" ); const efftype_id effect_narcosis( "narcosis" ); +const efftype_id effect_nausea( "nausea" ); const efftype_id effect_no_sight( "no_sight" ); +const efftype_id effect_pkill1( "pkill1" ); +const efftype_id effect_pkill2( "pkill2" ); +const efftype_id effect_pkill3( "pkill3" ); const efftype_id effect_riding( "riding" ); const efftype_id effect_sleep( "sleep" ); const efftype_id effect_slept_through_alarm( "slept_through_alarm" ); @@ -3438,3 +3445,73 @@ void Character::shout( std::string msg, bool order ) sounds::sound( pos(), noise, order ? sounds::sound_t::order : sounds::sound_t::alert, msg, false, "shout", shout ); } + +void Character::vomit() +{ + add_memorial_log( pgettext( "memorial_male", "Threw up." ), + pgettext( "memorial_female", "Threw up." ) ); + + if( stomach.contains() != 0_ml ) { + // empty stomach contents + stomach.bowel_movement(); + g->m.add_field( adjacent_tile(), fd_bile, 1 ); + add_msg_player_or_npc( m_bad, _( "You throw up heavily!" ), _( " throws up heavily!" ) ); + } + + if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea + const effect dummy_nausea( &effect_nausea.obj(), 0_turns, num_bp, false, 1, calendar::turn ); + add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() * units::to_milliliter( + stomach.contains() ) / 21, dummy_nausea.get_int_dur_factor() ) ); + } + + moves -= 100; + for( auto &elem : *effects ) { + for( auto &_effect_it : elem.second ) { + auto &it = _effect_it.second; + if( it.get_id() == effect_foodpoison ) { + it.mod_duration( -30_minutes ); + } else if( it.get_id() == effect_drunk ) { + it.mod_duration( rng( -10_minutes, -50_minutes ) ); + } + } + } + remove_effect( effect_pkill1 ); + remove_effect( effect_pkill2 ); + remove_effect( effect_pkill3 ); + // Don't wake up when just retching + if( stomach.contains() > 0_ml ) { + wake_up(); + } +} + +// adjacent_tile() returns a safe, unoccupied adjacent tile. If there are no such tiles, returns player position instead. +tripoint Character::adjacent_tile() const +{ + std::vector ret; + int dangerous_fields = 0; + for( const tripoint &p : g->m.points_in_radius( pos(), 1 ) ) { + if( p == pos() ) { + // Don't consider player position + continue; + } + const trap &curtrap = g->m.tr_at( p ); + if( g->critter_at( p ) == nullptr && g->m.passable( p ) && + ( curtrap.is_null() || curtrap.is_benign() ) ) { + // Only consider tile if unoccupied, passable and has no traps + dangerous_fields = 0; + auto &tmpfld = g->m.field_at( p ); + for( auto &fld : tmpfld ) { + const field_entry &cur = fld.second; + if( cur.is_dangerous() ) { + dangerous_fields++; + } + } + + if( dangerous_fields == 0 ) { + ret.push_back( p ); + } + } + } + + return random_entry( ret, pos() ); // player position if no valid adjacent tiles +} diff --git a/src/character.h b/src/character.h index 607a590f152cb..99dae23da231c 100644 --- a/src/character.h +++ b/src/character.h @@ -831,12 +831,17 @@ class Character : public Creature, public visitable virtual void on_item_takeoff( const item & ) {} virtual void on_worn_item_washed( const item & ) {} + /** Returns an unoccupied, safe adjacent point. If none exists, returns player position. */ + tripoint adjacent_tile() const; + /** Removes "sleep" and "lying_down" */ void wake_up(); // how loud a character can shout. based on mutations and clothing int get_shout_volume() const; // shouts a message void shout( std::string text = "", bool order = false ); + /** Handles Character vomiting effects */ + void vomit(); protected: Character(); Character( const Character & ) = delete; diff --git a/src/player.cpp b/src/player.cpp index 301fc999afb81..3ca9dc0a44f64 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -6517,52 +6517,6 @@ void player::mend( int rate_multiplier ) } } -void player::vomit() -{ - add_memorial_log( pgettext( "memorial_male", "Threw up." ), - pgettext( "memorial_female", "Threw up." ) ); - - if( stomach.contains() != 0_ml ) { - // Remove all joy from previously eaten food and apply the penalty - rem_morale( MORALE_FOOD_GOOD ); - rem_morale( MORALE_FOOD_HOT ); - rem_morale( MORALE_HONEY ); // bears must suffer too - add_morale( MORALE_VOMITED, -2 * units::to_milliliter( stomach.contains() / 50 ), -40, 90_minutes, - 45_minutes, false ); // 1.5 times longer - stomach.bowel_movement(); // puke all of it - g->m.add_field( adjacent_tile(), fd_bile, 1 ); - - add_msg_player_or_npc( m_bad, _( "You throw up heavily!" ), _( " throws up heavily!" ) ); - } else { - add_msg_if_player( m_warning, _( "You retched, but your stomach is empty." ) ); - } - - if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea - const effect dummy_nausea( &effect_nausea.obj(), 0_turns, num_bp, false, 1, calendar::turn ); - add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() * units::to_milliliter( - stomach.contains() ) / 21, dummy_nausea.get_int_dur_factor() ) ); - } - - moves -= 100; - for( auto &elem : *effects ) { - for( auto &_effect_it : elem.second ) { - auto &it = _effect_it.second; - if( it.get_id() == effect_foodpoison ) { - it.mod_duration( -30_minutes ); - } else if( it.get_id() == effect_drunk ) { - it.mod_duration( rng( -10_minutes, -50_minutes ) ); - } - } - } - remove_effect( effect_pkill1 ); - remove_effect( effect_pkill2 ); - remove_effect( effect_pkill3 ); - // Don't wake up when just retching - if( stomach.contains() > 0_ml ) { - wake_up(); - } -} - void player::sound_hallu() { // Random 'dangerous' sound from a random direction @@ -10985,38 +10939,6 @@ bool player::uncanny_dodge() return false; } -// adjacent_tile() returns a safe, unoccupied adjacent tile. If there are no such tiles, returns player position instead. -tripoint player::adjacent_tile() const -{ - std::vector ret; - int dangerous_fields = 0; - for( const tripoint &p : g->m.points_in_radius( pos(), 1 ) ) { - if( p == pos() ) { - // Don't consider player position - continue; - } - const trap &curtrap = g->m.tr_at( p ); - if( g->critter_at( p ) == nullptr && g->m.passable( p ) && - ( curtrap.is_null() || curtrap.is_benign() ) ) { - // Only consider tile if unoccupied, passable and has no traps - dangerous_fields = 0; - auto &tmpfld = g->m.field_at( p ); - for( auto &fld : tmpfld ) { - const field_entry &cur = fld.second; - if( cur.is_dangerous() ) { - dangerous_fields++; - } - } - - if( dangerous_fields == 0 ) { - ret.push_back( p ); - } - } - } - - return random_entry( ret, pos() ); // player position if no valid adjacent tiles -} - int player::climbing_cost( const tripoint &from, const tripoint &to ) const { if( !g->m.valid_move( from, to, false, true ) ) { diff --git a/src/player.h b/src/player.h index a613817802471..8d233211e93a5 100644 --- a/src/player.h +++ b/src/player.h @@ -709,8 +709,6 @@ class player : public Character /** Handles the uncanny dodge bionic and effects, returns true if the player successfully dodges */ bool uncanny_dodge() override; - /** Returns an unoccupied, safe adjacent point. If none exists, returns player position. */ - tripoint adjacent_tile() const; /** * Checks both the neighborhoods of from and to for climbable surfaces, @@ -819,8 +817,6 @@ class player : public Character bool irradiate( float rads, bool bypass = false ); /** Handles the chance for broken limbs to spontaneously heal to 1 HP */ void mend( int rate_multiplier ); - /** Handles player vomiting effects */ - void vomit(); /** Creates an auditory hallucination */ void sound_hallu();