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

Make vitamin deficiencies and hypervitaminosis non-cosmetic. #33776

Closed
wants to merge 1 commit into from
Closed
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
92 changes: 82 additions & 10 deletions data/json/effects.json
Original file line number Diff line number Diff line change
Expand Up @@ -1458,15 +1458,23 @@
{
"type": "effect_type",
"id": "hypocalcemia",
"name": [ "Hypocalcemia", "Weak bones", "Brittle bones" ],
"desc": [ "A lack of calcium in your diet will make your bones progressively weaker." ],
"apply_message": "Your bones are becoming more brittle.",
"remove_message": "Your bones regain their usual strength.",
"name": [ "Mild Hypocalcemia", "Hypocalcemia", "Acute Hypocalcemia" ],
"desc": [ "A lack of calcium in your diet will cause various neuromuscular symptoms." ],
"apply_message": "Your muscles are becoming more stiff.",
"remove_message": "Stiffness in your musles passes away.",
"decay_messages": [
[ "Your calcium deficiency is nearly resolved.", "good" ],
[ "Your bones become stronger as your calcium deficiency improves.", "good" ]
[ "Your have better control of your muscles as your calcium deficiency improves.", "good" ]
],
"max_intensity": 3,
"base_mods": {
"dex_mod": [ -1 ],
"speed_mod": [ -10 ]
},
"scaling_mods": {
"dex_mod": [ -2 ],
"speed_mod": [ -15 ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really, hypocalcaemia in a gameplay relevant way has nothing to do with bones. You'd have to be severely hypocalcaemic for many years to get osteoporosis.

In game, hypocalcaemia that matters would be profound, nerve-affecting lack of calcium. It is very hard to get, but the main symptoms would be numbness and seizures, followed by death if it hits too low a level.

For sanity checking, this is not something you can really get through malnutrition unless you try extremely hard. I am not convinced it belongs in the game at all yet.

},
"rating": "bad"
},
{
Expand All @@ -1481,6 +1489,28 @@
[ "Your feel stronger as your anemia starts to improve.", "good" ]
],
"max_intensity": 3,
"base_mods": {
"str_mod": [ -1 ],
"stamina_min": [ -100 ],
"stamina_max": [ -200 ],
"stamina_chance": [ 900 ],
"fatigue_min": [ 10 ],
"fatigue_max": [ 20 ],
"fatigue_chance": [ 900 ],
"h_mod_min": [ -1 ],
"h_mod_min_val": [ 0 ],
"h_mod_chance": [ 900 ]
},
"scaling_mods": {
"str_mod": [ -2 ],
"stamina_max": [ -500 ],
"fatigue_max": [ 20 ],
"stamina_chance": [ -300 ],
"fatigue_chance": [ -300 ],
"h_mod_min": [ -1 ],
"h_mod_min_val": [ -50 ],
"h_mod_chance": [ -200 ]
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great to me, based on numbers alone. The check would be how long it takes to develop anaemia and how fast these symptoms worsen. Until we have a blood loss system I'd assume it should take a few weeks to months of insufficient dietary iron to progress in anaemia stages.

"rating": "bad"
},
{
Expand All @@ -1495,20 +1525,44 @@
[ "Your vision improves as your Vitamin A deficiency improves.", "good" ]
],
"max_intensity": 3,
"base_mods": { "per_mod": [ -1 ] },
"scaling_mods": { "per_mod": [ -2 ] },
"rating": "bad"
},
{
"type": "effect_type",
"id": "hypovitB",
"name": [ "B12 deficiency", "Slow healing", "No healing" ],
"desc": [ "A lack of vitamin B12 in your diet will affect your ability to heal." ],
"apply_message": "Simple wounds are starting to concern you more than usual.",
"remove_message": "Your wounds now heal normally.",
"name": [ "B12 deficiency", "B12 anemia", "B12 dementia" ],
"desc": [
"A lack of vitamin B12 in your diet causes early symptoms of anemia.",
"Prolonged lack of vitamin B12 in your diet causes anemia, loss of taste, problems with focus and fading memory.",
"Severe vitamin B12 deficiency causes bad case of anemia, loss of taste, and damaged memory, causing dementia. Your skills rust."
],
"apply_message": "Your skin is more pale then usual.",
"remove_message": "Your skin tone comes back to its normal color.",
"decay_messages": [
[ "Your vitamin B12 deficiency is starting to resolve.", "good" ],
[ "Your ability to heal returns as your Vitamin B12 deficiency improves.", "good" ]
[ "Your ability to remember things returns as your Vitamin B12 deficiency improves.", "good" ]
],
"max_intensity": 3,
"base_mods": {
"int_mod": [ -1 ],
"dex_mod": [ -1 ],
"fatigue_min": [ 5 ],
"fatigue_max": [ 10 ],
"fatigue_chance": [ 900 ],
"h_mod_min": [ -1 ],
"h_mod_min_val": [ 0 ],
"h_mod_chance": [ 900 ]
},
"scaling_mods": {
"int_mod": [ -2 ],
"dex_mod": [ -2 ],
"speed_mod": [ -5 ],
"fatigue_chance": [ -200 ],
"h_mod_min": [ -1 ],
"h_mod_chance": [ -200 ]
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty reasonable, although the primary effect of b12 deficiency is numbness (and it doesn't always go away). It is very difficult to develop b12 deficiency through dietary insufficiency, but I think that is already modeled by b12 being common in foods in the game.

b12 deficiency also causes anaemia, so you may want to consider copying some of the anaemia effects in here at a lower level.

"rating": "bad"
},
{
Expand All @@ -1523,6 +1577,24 @@
[ "Your scurvy lessens as your Vitamin C deficiency improves.", "good" ]
],
"max_intensity": 3,
"base_mods": {
"pain_max_val": [ 35 ],
"pain_chance": [ 900 ],
"pain_min": [ 1 ],
"pain_max": [ 5 ],
"fatigue_chance": [ 900 ],
"fatigue_min": [ 10 ],
"h_mod_min": [ -1 ],
"h_mod_min_val": [ 0 ],
"h_mod_chance": [ 900 ]
},
"scaling_mods": {
"pain_chance": [ -300 ],
"fatigue_chance": [ -200 ],
"h_mod_min": [ -1 ],
"h_mod_min_val": [ -100 ],
"h_mod_chance": [ -300 ]
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What, you aren't modeling the loss of teeth and hair?

Scurvy is a potentially fatal illness. Do we have the ability to model slower wound healing and increased infection risk in effects yet? Scurvy also causes anaemia and could have some of the anaemia effects copied over at reduced levels, just like b12 deficiency.

Unlike the others, scurvy actually does happen with real diets and it's important we do a good job on this one. Looking good so far.

"rating": "bad"
},
{
Expand Down
2 changes: 2 additions & 0 deletions src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class JsonOut;
const efftype_id effect_contacts( "contacts" );
const efftype_id effect_depressants( "depressants" );
const efftype_id effect_happy( "happy" );
const efftype_id effect_hypovitB( "hypovitB" );
const efftype_id effect_irradiated( "irradiated" );
const efftype_id effect_pkill( "pkill" );
const efftype_id effect_riding( "riding" );
Expand Down Expand Up @@ -163,6 +164,7 @@ size_t avatar::max_memorized_tiles() const
map_memory_capacity_multiplier = 50;
}
current_map_memory_capacity = 2 * SEEX * 2 * SEEY * 100 * map_memory_capacity_multiplier;
current_map_memory_capacity /= std::max( 1, get_effect_int( effect_hypovitB ) * 2 );
}
return current_map_memory_capacity;
}
Expand Down
40 changes: 34 additions & 6 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ 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_hypovitA( "hypovitA" );
const efftype_id effect_infected( "infected" );
const efftype_id effect_in_pit( "in_pit" );
const efftype_id effect_lightsnare( "lightsnare" );
Expand Down Expand Up @@ -746,6 +747,18 @@ void Character::recalc_sight_limits()
if( has_trait( trait_BIRD_EYE ) ) {
vision_mode_cache.set( BIRD_EYE );
}
switch ( get_effect_int( effect_hypovitA ) )
{
case 1:
vision_mode_cache.set( NIGHTBLINDNESS_1 );
break;
case 2:
vision_mode_cache.set( NIGHTBLINDNESS_2 );
break;
case 3:
vision_mode_cache.set( NIGHTBLINDNESS_3 );
break;
}

// Not exactly a sight limit thing, but related enough
if( has_active_bionic( bionic_id( "bio_infrared" ) ) ||
Expand Down Expand Up @@ -784,26 +797,41 @@ float Character::get_vision_threshold( float light_level ) const

// As light_level goes from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LIT,
// dimming goes from 1.0 to 2.0.
const float dimming_from_light = 1.0 + ( ( static_cast<float>( light_level ) -
float dimming_from_light = 1.0 + ( ( static_cast<float>( light_level ) -
LIGHT_AMBIENT_MINIMAL ) /
( LIGHT_AMBIENT_LIT - LIGHT_AMBIENT_MINIMAL ) );

float range = get_per() / 3.0f - encumb( bp_eyes ) / 10.0f;
if( vision_mode_cache[NV_GOGGLES] || vision_mode_cache[NIGHTVISION_3] ||
vision_mode_cache[FULL_ELFA_VISION] || vision_mode_cache[CEPH_VISION] ) {
range += 10;
range += 10.0f;
} else if( vision_mode_cache[NIGHTVISION_2] || vision_mode_cache[FELINE_VISION] ||
vision_mode_cache[URSINE_VISION] || vision_mode_cache[ELFA_VISION] ) {
range += 4.5;
range += 4.5f;
} else if( vision_mode_cache[NIGHTVISION_1] ) {
range += 2;
range += 2.0f;
}

if( vision_mode_cache[BIRD_EYE] ) {
range++;
}

return std::min( static_cast<float>( LIGHT_AMBIENT_LOW ),
// night blindness effects: sight range reduction at night and increased light level needed to see a tile
// both governed by nightblindness modificator 'nb'; this effect does not affect vision in full light
float nb = 0.0f;
if( vision_mode_cache[NIGHTBLINDNESS_1] ) {
nb = 3.0f;
} else if( vision_mode_cache[NIGHTBLINDNESS_2] ) {
nb = 6.0f;
} else if( vision_mode_cache[NIGHTBLINDNESS_3] ) {
nb = 9.0f;
}
// googles provide electronic light, so no nightblindness modification for them
if( !vision_mode_cache[NV_GOGGLES] ) {
nb = 0.0f;
}
range -= nb;
range = std::max( 0.0f , range );
return std::min( static_cast<float>( LIGHT_AMBIENT_LOW ) + nb,
threshold_for_range( range ) * dimming_from_light );
}

Expand Down
3 changes: 3 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ enum vision_modes {
BOOMERED,
DARKNESS,
IR_VISION,
NIGHTBLINDNESS_1,
NIGHTBLINDNESS_2,
NIGHTBLINDNESS_3,
VISION_CLAIRVOYANCE,
VISION_CLAIRVOYANCE_PLUS,
VISION_CLAIRVOYANCE_SUPER,
Expand Down
4 changes: 4 additions & 0 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const skill_id skill_survival( "survival" );
const skill_id skill_cooking( "cooking" );

const efftype_id effect_foodpoison( "foodpoison" );
const efftype_id effect_hypovitB( "hypovitB" );
const efftype_id effect_poison( "poison" );
const efftype_id effect_tapeworm( "tapeworm" );
const efftype_id effect_bloodworms( "bloodworms" );
Expand Down Expand Up @@ -188,6 +189,9 @@ std::pair<int, int> player::fun_for( const item &comest ) const
if( ( has_effect( effect_common_cold ) || has_effect( effect_flu ) ) && fun > 0 ) {
fun /= 3; // food doesn't taste as good when you're sick
}
if( has_effect( effect_hypovitB ) ) {
fun /= get_effect_int( effect_hypovitB ); //B12 deficiency symptom is loss of taste
}
// Rotten food should be pretty disgusting
const float relative_rot = comest.get_relative_rot();
if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) && !has_trait( trait_SAPROVORE ) ) {
Expand Down
22 changes: 16 additions & 6 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ const efftype_id effect_grabbed( "grabbed" );
const efftype_id effect_hallu( "hallu" );
const efftype_id effect_happy( "happy" );
const efftype_id effect_hot( "hot" );
const efftype_id effect_hypervitaminosis( "hypervitaminosis" );
const efftype_id effect_hypovitB( "hypovitB" );
const efftype_id effect_infected( "infected" );
const efftype_id effect_iodine( "iodine" );
const efftype_id effect_irradiated( "irradiated" );
Expand Down Expand Up @@ -2650,17 +2652,24 @@ int player::read_speed( bool return_stat_effect ) const

int player::rust_rate( bool return_stat_effect ) const
{
if( get_option<std::string>( "SKILL_RUST" ) == "off" ) {
std::string option = get_option<std::string>( "SKILL_RUST" );
bool dementia = get_effect_int( effect_hypovitB ) == 3;
if( option == "off" && !dementia ) {
return 0;
}

// Stat window shows stat effects on based on current stat
int intel = get_int();
/** @EFFECT_INT reduces skill rust */
int ret = ( ( get_option<std::string>( "SKILL_RUST" ) == "vanilla" ||
get_option<std::string>( "SKILL_RUST" ) == "capped" ) ? 500 : 500 - 35 * ( intel - 8 ) );

int ret = 0;
if( dementia ) {
option = "vanilla";
}
ret = ( ( option == "vanilla" || option == "capped" ) ? 500 : 500 - 35 * ( intel - 8 ) );
ret *= mutation_value( "skill_rust_multiplier" );
if( dementia ) {
ret += 100;
}

if( ret < 0 ) {
ret = 0;
Expand Down Expand Up @@ -4942,7 +4951,7 @@ void player::suffer()
}
}
}
if( has_trait( trait_CHEMIMBALANCE ) ) {
if( has_trait( trait_CHEMIMBALANCE ) || has_effect( effect_hypervitaminosis ) ) {
if( one_turn_in( 6_hours ) && !has_trait( trait_NOPAIN ) ) {
add_msg_if_player( m_bad, _( "You suddenly feel sharp pain for no reason." ) );
mod_pain( 3 * rng( 1, 3 ) );
Expand Down Expand Up @@ -11751,7 +11760,8 @@ void player::do_skill_rust()

const bool charged_bio_mem = power_level > 25 && has_active_bionic( bio_memory );
const int oldSkillLevel = skill_level_obj.level();
if( skill_level_obj.rust( charged_bio_mem ) ) {
const bool forced = has_effect( effect_hypovitB );
if( skill_level_obj.rust( charged_bio_mem, forced ) ) {
add_msg_if_player( m_warning,
_( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() );
charge_power( -25 );
Expand Down
4 changes: 3 additions & 1 deletion src/player_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ static const std::string title_SKILLS = translate_marker( "SKILLS" );
static const std::string title_BIONICS = translate_marker( "BIONICS" );
static const std::string title_TRAITS = translate_marker( "TRAITS" );

static const efftype_id effect_hypovitB( "hypovitB" );

static const trait_id trait_COLDBLOOD4( "COLDBLOOD4" );

// use this instead of having to type out 26 spaces like before
Expand Down Expand Up @@ -696,7 +698,7 @@ static const Skill *draw_skills_list( const catacurses::window &w_skills,
} else {
const bool can_train = level.can_train();
const bool training = level.isTraining();
const bool rusting = level.isRusting();
const bool rusting = level.isRusting( g->u.has_effect( effect_hypovitB ) );
int exercise = level.exercise();
int level_num = level.level();
bool locked = false;
Expand Down
Loading