Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move player::fall_asleep() and dependent functions to Character scope #34828

Merged
merged 2 commits into from
Oct 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 189 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@
#include "rng.h"
#include "stomach.h"
#include "ui.h"
#include "veh_type.h"
#include "vehicle.h"
#include "vitamin.h"
#include "vpart_position.h"

static const bionic_id bio_ads( "bio_ads" );
static const bionic_id bio_armor_arms( "bio_armor_arms" );
Expand Down Expand Up @@ -5108,3 +5111,189 @@ double Character::footwear_factor() const
}
return ret;
}

void Character::start_hauling()
{
add_msg( _( "You start hauling items along the ground." ) );
if( is_armed() ) {
add_msg( m_warning, _( "Your hands are not free, which makes hauling slower." ) );
}
hauling = true;
}

void Character::stop_hauling()
{
add_msg( _( "You stop hauling items." ) );
hauling = false;
if( has_activity( activity_id( "ACT_MOVE_ITEMS" ) ) ) {
cancel_activity();
}
}

bool Character::is_hauling() const
{
return hauling;
}

void Character::assign_activity( const activity_id &type, int moves, int index, int pos,
const std::string &name )
{
assign_activity( player_activity( type, moves, index, pos, name ) );
}

void Character::assign_activity( const player_activity &act, bool allow_resume )
{
if( allow_resume && !backlog.empty() && backlog.front().can_resume_with( act, *this ) ) {
add_msg_if_player( _( "You resume your task." ) );
activity = backlog.front();
backlog.pop_front();
} else {
if( activity ) {
backlog.push_front( activity );
}

activity = act;
}

if( activity.rooted() ) {
rooted_message();
}
if( is_npc() ) {
npc *guy = dynamic_cast<npc *>( this );
guy->set_attitude( NPCATT_ACTIVITY );
guy->set_mission( NPC_MISSION_ACTIVITY );
guy->current_activity_id = activity.id();
}
}

bool Character::has_activity( const activity_id &type ) const
{
return activity.id() == type;
}

bool Character::has_activity( const std::vector<activity_id> &types ) const
{
return std::find( types.begin(), types.end(), activity.id() ) != types.end();
}

void Character::cancel_activity()
{
if( has_activity( activity_id( "ACT_MOVE_ITEMS" ) ) && is_hauling() ) {
stop_hauling();
}
if( has_activity( activity_id( "ACT_TRY_SLEEP" ) ) ) {
remove_value( "sleep_query" );
}
// Clear any backlog items that aren't auto-resume.
for( auto backlog_item = backlog.begin(); backlog_item != backlog.end(); ) {
if( backlog_item->auto_resume ) {
backlog_item++;
} else {
backlog_item = backlog.erase( backlog_item );
}
}
if( activity && activity.is_suspendable() ) {
backlog.push_front( activity );
}
sfx::end_activity_sounds(); // kill activity sounds when canceled
activity = player_activity();
}

void Character::resume_backlog_activity()
{
if( !backlog.empty() && backlog.front().auto_resume ) {
activity = backlog.front();
backlog.pop_front();
}
}

void Character::fall_asleep()
{
// Communicate to the player that he is using items on the floor
std::string item_name = is_snuggling();
if( item_name == "many" ) {
if( one_in( 15 ) ) {
add_msg_if_player( _( "You nestle your pile of clothes for warmth." ) );
} else {
add_msg_if_player( _( "You use your pile of clothes for warmth." ) );
}
} else if( item_name != "nothing" ) {
if( one_in( 15 ) ) {
add_msg_if_player( _( "You snuggle your %s to keep warm." ), item_name );
} else {
add_msg_if_player( _( "You use your %s to keep warm." ), item_name );
}
}
if( has_active_mutation( trait_id( "HIBERNATE" ) ) &&
get_kcal_percent() > 0.8f ) {
if( is_avatar() ) {
g->memorial().add( pgettext( "memorial_male", "Entered hibernation." ),
pgettext( "memorial_female", "Entered hibernation." ) );
}
// some days worth of round-the-clock Snooze. Cata seasons default to 91 days.
fall_asleep( 10_days );
// If you're not fatigued enough for 10 days, you won't sleep the whole thing.
// In practice, the fatigue from filling the tank from (no msg) to Time For Bed
// will last about 8 days.
}

fall_asleep( 10_hours ); // default max sleep time.
}

void Character::fall_asleep( const time_duration &duration )
{
if( activity ) {
if( activity.id() == "ACT_TRY_SLEEP" ) {
activity.set_to_null();
} else {
cancel_activity();
}
}
add_effect( effect_sleep, duration );
}

std::string Character::is_snuggling() const
{
auto begin = g->m.i_at( pos() ).begin();
auto end = g->m.i_at( pos() ).end();

if( in_vehicle ) {
if( const cata::optional<vpart_reference> vp = g->m.veh_at( pos() ).part_with_feature( VPFLAG_CARGO,
false ) ) {
vehicle *const veh = &vp->vehicle();
const int cargo = vp->part_index();
if( !veh->get_items( cargo ).empty() ) {
begin = veh->get_items( cargo ).begin();
end = veh->get_items( cargo ).end();
}
}
}
const item *floor_armor = nullptr;
int ticker = 0;

// If there are no items on the floor, return nothing
if( begin == end ) {
return "nothing";
}

for( auto candidate = begin; candidate != end; ++candidate ) {
if( !candidate->is_armor() ) {
continue;
} else if( candidate->volume() > 250_ml && candidate->get_warmth() > 0 &&
( candidate->covers( bp_torso ) || candidate->covers( bp_leg_l ) ||
candidate->covers( bp_leg_r ) ) ) {
floor_armor = &*candidate;
ticker++;
}
}

if( ticker == 0 ) {
return "nothing";
} else if( ticker == 1 ) {
return floor_armor->type_name();
} else if( ticker > 1 ) {
return "many";
}

return "nothing";
}
30 changes: 30 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "enums.h"
#include "item.h"
#include "optional.h"
#include "player_activity.h"
#include "stomach.h"
#include "string_formatter.h"
#include "string_id.h"
Expand Down Expand Up @@ -1057,7 +1058,12 @@ class Character : public Creature, public visitable<Character>
std::list<item> worn;
std::array<int, num_hp_parts> hp_cur, hp_max, damage_bandaged, damage_disinfected;
bool nv_cached;
// Means player sit inside vehicle on the tile he is now
bool in_vehicle;
bool hauling;

player_activity activity;
std::list<player_activity> backlog;
inventory inv;
itype_id last_item;
item weapon;
Expand All @@ -1077,6 +1083,24 @@ class Character : public Creature, public visitable<Character>
// for vehicle work
int activity_vehicle_part_index = -1;

// Hauling items on the ground
void start_hauling();
void stop_hauling();
bool is_hauling() const;

/** Legacy activity assignment, should not be used where resuming is important. */
void assign_activity( const activity_id &type, int moves = calendar::INDEFINITELY_LONG,
int index = -1, int pos = INT_MIN,
const std::string &name = "" );
/** Assigns activity to player, possibly resuming old activity if it's similar enough. */
void assign_activity( const player_activity &act, bool allow_resume = true );
/** Check if player currently has a given activity */
bool has_activity( const activity_id &type ) const;
/** Check if player currently has any of the given activities */
bool has_activity( const std::vector<activity_id> &types ) const;
void resume_backlog_activity();
void cancel_activity();

void initialize_stomach_contents();

/** Stable base metabolic rate due to traits */
Expand Down Expand Up @@ -1144,6 +1168,12 @@ class Character : public Creature, public visitable<Character>
void rooted_message() const;
void rooted();

/** Adds "sleep" to the player */
void fall_asleep();
void fall_asleep( const time_duration &duration );
/** Checks to see if the player is using floor items to keep warm, and return the name of one such item if so */
std::string is_snuggling() const;

/** Set vitamin deficiency/excess disease states dependent upon current vitamin levels */
void update_vitamins( const vitamin_id &vit );
/**
Expand Down
Loading