Skip to content

Commit

Permalink
move vomit and adjacent_tile
Browse files Browse the repository at this point in the history
  • Loading branch information
KorGgenT authored and kevingranade committed Jun 5, 2019
1 parent 588f8e0 commit 76755c7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 82 deletions.
16 changes: 16 additions & 0 deletions src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
2 changes: 2 additions & 0 deletions src/avatar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
77 changes: 77 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -58,14 +59,20 @@ 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" );
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" );
Expand Down Expand Up @@ -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!" ), _( "<npcname> 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<tripoint> 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
}
5 changes: 5 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -831,12 +831,17 @@ class Character : public Creature, public visitable<Character>
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;
Expand Down
78 changes: 0 additions & 78 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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!" ), _( "<npcname> 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
Expand Down Expand Up @@ -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<tripoint> 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 ) ) {
Expand Down
4 changes: 0 additions & 4 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 76755c7

Please sign in to comment.