Skip to content

Commit

Permalink
user defined height and age (#39385)
Browse files Browse the repository at this point in the history
* user defined height and age
* add randomizing age and height to avatar::randomize
  • Loading branch information
KorGgenT authored Apr 9, 2020
1 parent 0265aeb commit 023e222
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 11 deletions.
52 changes: 50 additions & 2 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6835,6 +6835,55 @@ units::mass Character::bionics_weight() const
return bio_weight;
}

int Character::base_age() const
{
return init_age;
}

void Character::mod_base_age( int mod )
{
init_age += mod;
}

int Character::age() const
{
int years_since_cataclysm = to_turns<int>( calendar::turn - calendar::turn_zero ) /
to_turns<int>( calendar::year_length() );
return init_age + years_since_cataclysm;
}

std::string Character::age_string() const
{
//~ how old the character is in years. try to limit number of characters to fit on the screen
std::string unformatted = _( "aged %d" );
return string_format( unformatted, age() );
}

int Character::base_height() const
{
return init_height;
}

void Character::mod_base_height( int mod )
{
init_height += mod;
}

std::string Character::height_string() const
{
const bool metric = get_option<std::string>( "DISTANCE_UNITS" ) == "metric";

if( metric ) {
std::string metric_string = _( "%d cm" );
return string_format( metric_string, height() );
}

int total_inches = std::round( height() / 2.54 );
int feet = std::floor( total_inches / 12 );
int remainder_inches = total_inches % 12;
return string_format( "%d\'%d\"", feet, remainder_inches );
}

int Character::height() const
{
int height = init_height;
Expand Down Expand Up @@ -6866,11 +6915,10 @@ int Character::get_bmr() const
/**
Values are for males, and average!
*/
const int age = 25;
const int equation_constant = 5;
return ceil( metabolic_rate_base() * activity_level * ( units::to_gram<int>
( bodyweight() / 100.0 ) +
( 6.25 * height() ) - ( 5 * age ) + equation_constant ) );
( 6.25 * height() ) - ( 5 * age() ) + equation_constant ) );
}

void Character::increase_activity_level( float new_level )
Expand Down
12 changes: 12 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,16 @@ class Character : public Creature, public visitable<Character>
float get_bmi() const;
// returns amount of calories burned in a day given various metabolic factors
int get_bmr() const;
// age in years, determined at character creation
int base_age() const;
void mod_base_age( int mod );
// age in years
int age() const;
std::string age_string() const;
// returns the height in cm
int base_height() const;
void mod_base_height( int mod );
std::string height_string() const;
// returns the height of the player character in cm
int height() const;
// returns bodyweight of the Character
Expand Down Expand Up @@ -1905,6 +1915,8 @@ class Character : public Creature, public visitable<Character>
int healthy;
int healthy_mod;

/** age in years at character creation */
int init_age = 25;
/**height at character creation*/
int init_height = 175;
/** Size class of character. */
Expand Down
110 changes: 108 additions & 2 deletions src/newcharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ void avatar::randomize( const bool random_scenario, points_left &points, bool pl
} else {
name = MAP_SHARING::getUsername();
}
// if adjusting min and max age from 16 and 55, make sure to see set_description()
init_age = rng( 16, 55 );
// if adjusting min and max height from 145 and 200, make sure to see set_description()
init_height = rng( 145, 200 );
bool cities_enabled = world_generator->active_world->WORLD_OPTIONS["CITY_SIZE"].getValue() != "0";
if( random_scenario ) {
std::vector<const scenario *> scenarios;
Expand Down Expand Up @@ -2217,6 +2221,35 @@ tab_direction set_scenario( avatar &u, points_left &points,
return retval;
}

namespace char_creation
{
enum description_selector {
NAME,
HEIGHT,
AGE
};

static void draw_height( const catacurses::window &w_height, const avatar &you,
const bool highlight )
{
werase( w_height );
mvwprintz( w_height, point_zero, highlight ? h_light_gray : c_light_gray, _( "Height:" ) );
unsigned height_pos = 1 + utf8_width( _( "Height:" ) );
mvwprintz( w_height, point( height_pos, 0 ), c_light_green, string_format( "%d cm",
you.base_height() ) );
wrefresh( w_height );
}

static void draw_age( const catacurses::window &w_age, const avatar &you, const bool highlight )
{
werase( w_age );
mvwprintz( w_age, point_zero, highlight ? h_light_gray : c_light_gray, _( "Age:" ) );
unsigned age_pos = 1 + utf8_width( _( "Age:" ) );
mvwprintz( w_age, point( age_pos, 0 ), c_light_green, string_format( "%d", you.base_age() ) );
wrefresh( w_age );
}
} // namespace char_creation

tab_direction set_description( avatar &you, const bool allow_reroll,
points_left &points )
{
Expand All @@ -2236,6 +2269,8 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
catacurses::window w_profession;
catacurses::window w_skills;
catacurses::window w_guide;
catacurses::window w_height;
catacurses::window w_age;
const auto init_windows = [&]( ui_adaptor & ui ) {
w = catacurses::newwin( TERMY, TERMX, point_zero );
w_name = catacurses::newwin( 2, 42, point( 2, 5 ) );
Expand All @@ -2247,6 +2282,8 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
w_profession = catacurses::newwin( 1, TERMX - 47, point( 46, 10 ) );
w_skills = catacurses::newwin( TERMY - 12, 33, point( 46, 11 ) );
w_guide = catacurses::newwin( 4, TERMX - 3, point( 2, TERMY - 5 ) );
w_height = catacurses::newwin( 1, 20, point( 80, 5 ) );
w_age = catacurses::newwin( 1, 10, point( 80, 6 ) );
ui.position_from_window( w );
};
init_windows( ui );
Expand All @@ -2257,6 +2294,7 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
unsigned female_pos = 2 + male_pos + utf8_width( _( "Male" ) );

input_context ctxt( "NEW_CHAR_DESCRIPTION" );
ctxt.register_cardinal();
ctxt.register_action( "SAVE_TEMPLATE" );
ctxt.register_action( "PICK_RANDOM_NAME" );
ctxt.register_action( "CHANGE_GENDER" );
Expand Down Expand Up @@ -2301,6 +2339,8 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
you.name = get_option<std::string>( "DEF_CHAR_NAME" );
}

char_creation::description_selector current_selector = char_creation::NAME;

bool no_name_entered = false;
ui.on_redraw( [&]( const ui_adaptor & ) {
draw_character_tabs( w, _( "DESCRIPTION" ) );
Expand Down Expand Up @@ -2413,7 +2453,8 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
wrefresh( w_guide );

//We draw this stuff every loop because this is user-editable
mvwprintz( w_name, point_zero, c_light_gray, _( "Name:" ) );
mvwprintz( w_name, point_zero,
current_selector == char_creation::NAME ? h_light_gray : c_light_gray, _( "Name:" ) );
if( no_name_entered ) {
mvwprintz( w_name, point( namebar_pos, 0 ), h_light_gray, _( "_______NO NAME ENTERED!_______" ) );
} else {
Expand All @@ -2440,6 +2481,9 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
ctxt.get_desc( "CHANGE_GENDER" ) );
wrefresh( w_gender );

char_creation::draw_age( w_age, you, current_selector == char_creation::AGE );
char_creation::draw_height( w_height, you, current_selector == char_creation::HEIGHT );

const std::string location_prompt = string_format(
_( "Press <color_light_green>%s</color> to select location." ),
ctxt.get_desc( "CHOOSE_LOCATION" ) );
Expand Down Expand Up @@ -2470,6 +2514,13 @@ tab_direction set_description( avatar &you, const bool allow_reroll,

// do not switch IME mode now, but restore previous mode on return
ime_sentry sentry( ime_sentry::keep );

int min_allowed_age = 16;
int max_allowed_age = 55;
// in centimeters. 2 std. deviations below average female height
int min_allowed_height = 145;
int max_allowed_height = 200;

do {
ui_manager::redraw();
const std::string action = ctxt.handle_input();
Expand Down Expand Up @@ -2504,6 +2555,60 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
}
} else if( action == "PREV_TAB" ) {
return tab_direction::BACKWARD;
} else if( action == "RIGHT" ) {
switch( current_selector ) {
case char_creation::NAME:
current_selector = char_creation::HEIGHT;
break;
case char_creation::HEIGHT:
current_selector = char_creation::AGE;
break;
case char_creation::AGE:
current_selector = char_creation::NAME;
break;
}
} else if( action == "LEFT" ) {
switch( current_selector ) {
case char_creation::NAME:
current_selector = char_creation::AGE;
break;
case char_creation::HEIGHT:
current_selector = char_creation::NAME;
break;
case char_creation::AGE:
current_selector = char_creation::HEIGHT;
break;
}
} else if( action == "UP" ) {
switch( current_selector ) {
case char_creation::HEIGHT:
if( you.base_height() < max_allowed_height ) {
you.mod_base_height( 1 );
}
break;
case char_creation::AGE:
if( you.base_age() < max_allowed_age ) {
you.mod_base_age( 1 );
}
break;
default:
break;
}
} else if( action == "DOWN" ) {
switch( current_selector ) {
case char_creation::HEIGHT:
if( you.base_height() > min_allowed_height ) {
you.mod_base_height( -1 );
}
break;
case char_creation::AGE:
if( you.base_age() > min_allowed_age ) {
you.mod_base_age( -1 );
}
break;
default:
break;
}
} else if( action == "REROLL_CHARACTER" && allow_reroll ) {
points.init_from_options();
you.randomize( false, points );
Expand Down Expand Up @@ -2538,7 +2643,8 @@ tab_direction set_description( avatar &you, const bool allow_reroll,
}
}
} else if( action == "ANY_INPUT" &&
!MAP_SHARING::isSharing() ) { // Don't edit names when sharing maps
// Don't edit names when sharing maps
!MAP_SHARING::isSharing() && current_selector == char_creation::NAME ) {
const int ch = ctxt.get_raw_input().get_first_input();
utf8_wrapper wrap( you.name );
if( ch == KEY_BACKSPACE ) {
Expand Down
4 changes: 4 additions & 0 deletions src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,10 @@ void options_manager::add_options_interface()
{ { "c", translate_marker( "Cup" ) }, { "l", translate_marker( "Liter" ) }, { "qt", translate_marker( "Quart" ) } },
"l"
);
add( "DISTANCE_UNITS", "interface", translate_marker( "Distance units" ),
translate_marker( "Metric or Imperial" ),
{ { "metric", translate_marker( "Metric" ) }, { "imperial", translate_marker( "Imperial" ) } },
"imperial" );

add( "24_HOUR", "interface", translate_marker( "Time format" ),
translate_marker( "12h: AM/PM, e.g. 7:31 AM - Military: 24h Military, e.g. 0731 - 24h: Normal 24h, e.g. 7:31" ),
Expand Down
17 changes: 10 additions & 7 deletions src/player_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1291,16 +1291,19 @@ void player::disp_info()
break;
}
}
//~ player info window: 1s - name, 2s - gender, 3s - Prof or Mutation name
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s | %3$s" ), name,
male ? _( "Male" ) : _( "Female" ), race );
//~ player info window: 1s - name, 2s - gender, 3s - Prof or Mutation name, 4s age (years), 5s height
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s | %3$s | %4$s | %5$s" ), name,
male ? _( "Male" ) : _( "Female" ), race, age_string(), height_string() );
} else if( prof == nullptr || prof == profession::generic() ) {
// Regular person. Nothing interesting.
//~ player info window: 1s - name, 2s - gender, '|' - field separator.
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s" ), name, male ? _( "Male" ) : _( "Female" ) );
//~ player info window: 1s - name, 2s - gender, 3s - age, 4s - height '|' - field separator.
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s | %3$s | %4$s" ), name,
male ? _( "Male" ) : _( "Female" ),
age_string(), height_string() );
} else {
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s | %3$s" ), name,
male ? _( "Male" ) : _( "Female" ), prof->gender_appropriate_name( male ) );
mvwprintw( w_tip, point_zero, _( "%1$s | %2$s | %3$s | %4$s | %5$s" ), name,
male ? _( "Male" ) : _( "Female" ), prof->gender_appropriate_name( male ),
age_string(), height_string() );
}

input_context ctxt( "PLAYER_INFO" );
Expand Down
7 changes: 7 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ void Character::load( const JsonObject &data )
data.read( "per_bonus", per_bonus );
data.read( "int_bonus", int_bonus );
data.read( "omt_path", omt_path );

data.read( "base_age", init_age );
data.read( "base_height", init_height );

// needs
data.read( "thirst", thirst );
data.read( "hunger", hunger );
Expand Down Expand Up @@ -637,6 +641,9 @@ void Character::store( JsonOut &json ) const
json.member( "per_bonus", per_bonus );
json.member( "int_bonus", int_bonus );

json.member( "base_age", init_age );
json.member( "base_height", init_height );

// health
json.member( "healthy", healthy );
json.member( "healthy_mod", healthy_mod );
Expand Down

0 comments on commit 023e222

Please sign in to comment.