diff --git a/data/json/effects.json b/data/json/effects.json index 08fffd206e200..ded5ebcacf431 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -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 ] + }, "rating": "bad" }, { @@ -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 ] + }, "rating": "bad" }, { @@ -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 ] + }, "rating": "bad" }, { @@ -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 ] + }, "rating": "bad" }, { diff --git a/src/avatar.cpp b/src/avatar.cpp index 0600de860179c..18508a517241b 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -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" ); @@ -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; } diff --git a/src/character.cpp b/src/character.cpp index 8b320c3f8838f..316b1ec0b93cb 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -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" ); @@ -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" ) ) || @@ -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( light_level ) - + float dimming_from_light = 1.0 + ( ( static_cast( 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( 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( LIGHT_AMBIENT_LOW ) + nb, threshold_for_range( range ) * dimming_from_light ); } diff --git a/src/character.h b/src/character.h index c5245b4fd0b6f..60da425f49c9e 100644 --- a/src/character.h +++ b/src/character.h @@ -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, diff --git a/src/consumption.cpp b/src/consumption.cpp index 6fb97dc17fe7c..c86a408825813 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -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" ); @@ -188,6 +189,9 @@ std::pair 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 ) ) { diff --git a/src/player.cpp b/src/player.cpp index 94cfe599a94c6..3850af1e156d5 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -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" ); @@ -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( "SKILL_RUST" ) == "off" ) { + std::string option = get_option( "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( "SKILL_RUST" ) == "vanilla" || - get_option( "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; @@ -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 ) ); @@ -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 ); diff --git a/src/player_display.cpp b/src/player_display.cpp index 1369326a83559..2e81771c17745 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -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 @@ -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; diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 0fe42121ad30f..ae9e1e1f08ded 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -23,6 +23,7 @@ #include "enums.h" #include "mtype.h" #include "stomach.h" +#include "morale_types.h" #if defined(TILES) # if defined(_MSC_VER) && defined(USE_VCPKG) @@ -39,6 +40,7 @@ const mtype_id mon_dermatik_larva( "mon_dermatik_larva" ); const efftype_id effect_adrenaline( "adrenaline" ); const efftype_id effect_alarm_clock( "alarm_clock" ); +const efftype_id effect_anemia( "effect_anemia" ); const efftype_id effect_antibiotic( "antibiotic" ); const efftype_id effect_asthma( "asthma" ); const efftype_id effect_attention( "attention" ); @@ -50,6 +52,7 @@ const efftype_id effect_boomered( "boomered" ); const efftype_id effect_brainworms( "brainworms" ); const efftype_id effect_cold( "cold" ); const efftype_id effect_cough_suppress( "cough_suppress" ); +const efftype_id effect_darkness( "darkness" ); const efftype_id effect_datura( "datura" ); const efftype_id effect_dermatik( "dermatik" ); const efftype_id effect_disabled( "disabled" ); @@ -61,6 +64,9 @@ const efftype_id effect_fungus( "fungus" ); const efftype_id effect_grabbed( "grabbed" ); const efftype_id effect_hallu( "hallu" ); const efftype_id effect_hot( "hot" ); +const efftype_id effect_hypocalcemia( "effect_hypocalcemia" ); +const efftype_id effect_hypovitA( "hypovitA" ); +const efftype_id effect_hypovitB( "hypovitB" ); const efftype_id effect_infected( "infected" ); const efftype_id effect_lying_down( "lying_down" ); const efftype_id effect_mending( "mending" ); @@ -71,6 +77,7 @@ const efftype_id effect_paincysts( "paincysts" ); const efftype_id effect_panacea( "panacea" ); const efftype_id effect_rat( "rat" ); const efftype_id effect_recover( "recover" ); +const efftype_id effect_scurvy( "scurvy" ); const efftype_id effect_shakes( "shakes" ); const efftype_id effect_sleep( "sleep" ); const efftype_id effect_slept_through_alarm( "slept_through_alarm" ); @@ -83,6 +90,7 @@ const efftype_id effect_tetanus( "tetanus" ); const efftype_id effect_valium( "valium" ); const efftype_id effect_visuals( "visuals" ); const efftype_id effect_weak_antibiotic( "weak_antibiotic" ); +const efftype_id effect_winded( "winded" ); const vitamin_id vitamin_iron( "iron" ); @@ -1293,5 +1301,483 @@ void player::hardcoded_effects( effect &it ) hp_cur[i] += 10; } mod_pain( -10 ); + } else if( id == effect_anemia ) { + if( one_in( 900 / intense ) && !in_sleep_state() ) { + // Lack of iron impairs production of hemoglobin and therefore ability to carry + // oxygen by red blood cells. This triggers veriety of symptoms, focusing on weakness, + // fatigue, cold limbs, later in dizzyness, soreness, breathlessness, + // and severe maiaise and lethargy. + // Base anemia symptoms: fatigue, loss of stamina, loss of strength, impact on health + // are placed in effect JSON + + // level 1 symptoms are cold limbs, pale skin, and weakness + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your hands feel unusually cold." ) ); + temp_conv[bp_hand_l] -= 2000; + temp_conv[bp_hand_r] -= 2000; + break; + case 2: + add_msg_if_player( m_bad, _( "Your feet feel unusualy cold." ) ); + temp_conv[bp_foot_l] -= 2000; + temp_conv[bp_foot_r] -= 2000; + break; + case 3: + add_msg_if_player( m_bad, _( "Your skin looks very pale." ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You feel weak. Where has your strength gone?" ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "You feel feeble. A gust of wind could make you stumble." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "There is an overwhelming aura of tiredness inside of you." ) ); + mod_fatigue( intense * 3 ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + // level 2 anemia introduces dizzynes, shakes, headaches, cravings for non-comestibles, + // mouth and tongue soreness + if( intense > 1 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Rest is what you want. Rest is what you need." ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "You feel dizzy and can't grip your own feet movement." ) ); + add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "Your muscles quivering." ) ); + add_effect( effect_shakes, rng( 4_minutes, 8_minutes ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You crave for ice. Dirt under your feet looks tasty too." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Your whole mouth is sore, and your tongue is swollen." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You feel lightheaded. And a headache follows." ) ); + mod_pain( intense * 9 ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + // level 3 anemia introduces restless legs, severe tiredness, breathlessness + if( intense > 2 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your legs are restless. Urge to move them is so strong." ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "You feel like you'd sleep on a rock." ) ); + mod_fatigue( intense * 3 ); + break; + case 3: + add_msg_if_player( m_bad, _( "You gasp for air!" ) ); + stamina = 0; + add_effect( effect_winded, rng( 30_seconds, 3_minutes ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "Can't breathe. Must rest." ) ); + stamina = 0; + break; + case 5: + add_msg_if_player( m_bad, _( "You can't take it any more. Rest first, everything else later." ) ); + add_effect( effect_lying_down, rng( 2_minutes, 5_minutes ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You must sit down for a moment. Just a moment." ) ); + add_effect( effect_downed, rng( 1_minutes, 2_minutes ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + } + } else if( id == effect_hypocalcemia ) { + // Calcium regulates electric conductance in human body, and lack of ionized calcium + // in blood serum results in a variety of neuromuscular symptoms: numbness, twitches, + // contractions, cramps, at later stages becoming very violent and severe variations. + // Main symptoms: loss of dexterity and loss of speed are placed effect's JSON + + if( in_sleep_state() ) { + return; + } + + if( one_in( 900 / intense ) ) { + // level 1 symptoms are mostly numbness + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your hands are unusually numb." ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "Your feet feel numb." ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "You feel pins and needles in your hands and feet." ) ); + mod_pain( intense * 3 ); + break; + case 4: + add_msg_if_player( m_bad, _( "You have an odd tingling sensation in and around the mouth and lips." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Your muscles are more stiff then usual." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You observe your limbs developing conractures." ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + // level 2 calcium deficiency introduces more neuromuscular symptoms + if( intense > 1 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "The red dots thay you noticed recently on your skin has developed into a ill looking set of large purple spots." ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "Sudden contraction of your leg muscles sends you to the ground." ) ); + add_effect( effect_downed, rng( 1_minutes, 2_minutes ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "Your muscles twitch." ) ); + add_effect( effect_shakes, rng( 4_minutes, 8_minutes ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "Your hands cramp and contract to an odd position." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Your eyelids twitch violently." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "Violent cramp of one of your muscles sends you to a world of pain." ) ); + mod_pain( intense * 9 ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + // level 3 calcium deficiency introduces severe neuromuscular symptoms + if( intense > 2 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your heart beats irregularly." ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "You feel sudden pain in your chest." ) ); + mod_pain( intense * 3 ); + break; + case 3: + add_msg_if_player( m_bad, _( "Muscles in your throat contract violently. You gasp for air." ) ); + stamina = 0; + add_effect( effect_winded, rng( 30_seconds, 3_minutes ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You have a seizure." ) ); + add_effect( effect_downed, rng( 1_minutes, 2_minutes ) ); + add_effect( effect_shakes, rng( 4_minutes, 8_minutes ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "You are stumbling around, suffering heavy cramps throughout your body." ) ); + add_effect( effect_stunned, rng( 2_minutes, 5_minutes ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "A sudden contracture tumbles your stomach upside down." ) ); + vomit(); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + } + } else if( id == effect_hypovitB ) { + if( one_in( 900 / intense ) ) { + // Vit B12 deficiency causes B12-specific anemia, gastric symptoms (including loss of taste) + // and progressive neurodegeneration, starting from minor neurological symptoms, memory loss, + // ending (in more severe stages) in dementia, here represented by forced skill rust + // symptoms of anemia and health cap are placed in effect's JSON + + // brain fog + focus_pool -= intense * 3; + // depression + add_morale( MORALE_FEELING_BAD, -intense, -50 ); + + if( in_sleep_state() ) { + return; + } + // level 1 symptoms are mostly anemia related, plus loss of focus + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "You have trouble concentrating. You cannot focus on the problem at hand." ) ); + focus_pool -= intense * 3; + break; + case 2: + add_msg_if_player( m_bad, _( "Your skin looks pale and yellowish." ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "You have a headache and you don't feel well." ) ); + mod_pain( intense * 3 ); + break; + case 4: + add_msg_if_player( m_bad, _( "You feel fatigue creeping over you." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "You feel waves of weakness periodicaly owerwhelming your body." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You feel exhauseted to the core. You daydream of a good rest." ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + // level 2 B12 deficiency introduces more gastric and memory problems + // at this stage loss of taste activates and map memory is impaired (elsewhere) + if( intense == 2 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "You have sudden emptiness in your thoughts." ) ); + focus_pool -= intense * 3; + break; + case 2: + add_msg_if_player( m_bad, _( "You have problems walking. You stagger and fall." ) ); + add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, false, 0, true ); + break; + case 3: + add_msg_if_player( m_bad, _( "This area looks familliar. Have you been here, or is it your memory playing tricks on you?" ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "Your heart is pounding in your chest in a worringly fast pace." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Your tongue feels sore and your taste is impaired." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "Your tongue feels odd and your bowels ache." ) ); + vomit(); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + // level 3 B12 defficiency introduces dementia and force activates skill rust. + if( intense == 3 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "You have sudden emptiness in your thoughts. What was my name again?" ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "You stare blindly before you. What am I doing here?" ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "You forgot... something. You don't remember what you forgot." ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You don't recognize your surroundings. Is this the road home?." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Where did you put your red scarf? Oh... you never had one." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "Your memory is playing tricks on you. What day is it?" ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + } + } else if( id == effect_hypovitA ) { + //more often at higher levels of severity + if( one_in( 900 / intense ) ) { + // Vitamin A deficiency has two main symptoms/results: night blindness and xerophthalmia (dry eye syndrome). + // Night blindness is affecting sight elsewhere; here are mostly symptoms of xerophthalmia. + // Adding intensity to dice roll unlocks severe effects at higher levels of deficiency, + // while simultaneously locking cosmetic effects, shifting balance of overall severity: + // lvl 1 = 1d6 + 1 = trigger 2-7; lvl 2 = 1d6 + 2 = 3-8, lvl 3 = 1d6 + 3 = 4-9 + // Perception drop is placed in effect's JSON + + if( in_sleep_state() ) { + return; + } + + switch( dice( 1, 6 ) + intense ) { + case 2: + add_msg_if_player( m_bad, _( "You blink wildly. Something odd is going on with your eyes." ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "Your eyes feel dry. You blink more often but it doesn't help." ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "Shadows look more deep and darkness more encompassing. Your eyes start to fail in the dark." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Wherever it's dark you can't see the details. It wasn't always like that." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "Your eyes hurt. Rubbing makes it even worse." ) ); + mod_pain( intense * 2 ); + break; + case 7: + add_msg_if_player( m_bad, _( "You feel like there is sand in your eyes, but you cannot shed any tears." ) ); + mod_pain( intense * 3 ); + break; + case 8: + add_msg_if_player( m_bad, _( "You feel like you're might go blind any minute." ) ); + add_effect( effect_darkness, rng( 1_minutes, intense * 3_minutes ) ); + break; + case 9: + add_msg_if_player( m_bad, _( "You eyes fail you." ) ); + add_effect( effect_blind, rng( 1_seconds , intense * 3_minutes ) ); + break; + } + } + } else if( id == effect_scurvy ) { + if( one_in( 900 / intense ) ) { + // Vit C deficiency initial symptoms are malaise and lethargy, then progress into + // various health problems: moving teath, spontaneous bleeding, jaundice, gastric problems, + // swollen limbs, muscle twitches, etc. + // fatigue & poor wound healing are placedin effect's JSON + + // scurvy also causes mood changes and depresion + add_morale( MORALE_FEELING_BAD, -intense * 3, -50 ); + + if( in_sleep_state() ) { + return; + } + // level one scurvy focuses on malaise and lethargy symptoms + // (fatigue in game terms) + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, + _( "Your arms feel so heavy today. Moving a finger feels like weightlifting." ) ); + break; + case 2: + add_msg_if_player( m_bad, + _( "Your legs feel so heavy today. You don't feel like walking anymore today." ) ); + break; + case 3: + add_msg_if_player( m_bad, + _( "Your head feels heavy today. You think about a bed and a soft pillow." ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You feel tired. A day off perhaps?" ) ); + break; + case 5: + add_msg_if_player( m_bad, + _( "You feel apathetic. A short break wouldn't be bad. Or even a long one." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You wish you stayed in bad today." ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + // level two scurvy introduces petechiae, teeth and gum symptoms, dry mouth and eyes + if( intense > 1 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your teeth feel loose. Scurvy?" ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "Your notice some blotchy rash on your skin." ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "Your gums start to bleed." ) ); + add_effect( effect_bleed, 10_seconds, bp_head, false, 1 ); + break; + case 4: + add_msg_if_player( m_bad, _( "Your mouth is dry like a desert." ) ); + break; + case 5: + add_msg_if_player( m_bad, _( "Your eyes are dry. You try blink to keep them moistured." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "Your bones hurt. Odd and unpleasant feeling." ) ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + // level three scurvy introduces jaundice, edema, neuropathy & nausea, spontaneous bleeding + if( intense > 2 ) { + switch( dice( 1, 9 ) ) { + case 1: + add_msg_if_player( m_bad, _( "Your skin looks yellowish. Jaundice?" ) ); + break; + case 2: + add_msg_if_player( m_bad, _( "You notice that your limbs are unnaturaly swollen." ) ); + break; + case 3: + add_msg_if_player( m_bad, _( "Your muscles twitch." ) ); + add_effect( effect_shakes, rng( 4_minutes, 8_minutes ) ); + break; + case 4: + add_msg_if_player( m_bad, _( "You stomach turns upside down." ) ); + vomit(); + break; + case 5: + add_msg_if_player( m_bad, _( "You notice vast red blotches on your skin." ) ); + break; + case 6: + add_msg_if_player( m_bad, _( "You start bleeding from your nose." ) ); + add_effect( effect_bleed, 10_seconds, bp_head, false, 1 ); + break; + case 7: // 7-9 empty for variability, as messages stack on higher intensity + break; + case 8: + break; + case 9: + break; + } + } + } } } diff --git a/src/skill.cpp b/src/skill.cpp index 62116192b1b69..dcc353380d5b6 100644 --- a/src/skill.cpp +++ b/src/skill.cpp @@ -217,13 +217,13 @@ time_duration rustRate( int level ) } } //namespace -bool SkillLevel::isRusting() const +bool SkillLevel::isRusting( bool forced ) const { - return get_option( "SKILL_RUST" ) != "off" && ( _level > 0 ) && + return ( get_option( "SKILL_RUST" ) != "off" || forced ) && ( _level > 0 ) && calendar::turn - _lastPracticed > rustRate( _level ); } -bool SkillLevel::rust( bool charged_bio_mem ) +bool SkillLevel::rust( bool charged_bio_mem, bool forced ) { const time_duration delta = calendar::turn - _lastPracticed; if( _level <= 0 || delta <= 0_turns || delta % rustRate( _level ) != 0_turns ) { @@ -235,7 +235,10 @@ bool SkillLevel::rust( bool charged_bio_mem ) } _exercise -= _level; - const auto &rust_type = get_option( "SKILL_RUST" ); + std::string rust_type = get_option( "SKILL_RUST" ); + if( forced ) { + rust_type = "vanilla"; + } if( _exercise < 0 ) { if( rust_type == "vanilla" || rust_type == "int" ) { _exercise = ( 100 * _level * _level ) - 1; diff --git a/src/skill.h b/src/skill.h index 71a6771034ae2..a44a758bcd5f4 100644 --- a/src/skill.h +++ b/src/skill.h @@ -118,8 +118,8 @@ class SkillLevel } void train( int amount, bool skip_scaling = false ); - bool isRusting() const; - bool rust( bool charged_bio_mem ); + bool isRusting( bool forced ) const; + bool rust( bool charged_bio_mem, bool forced ); void practice(); bool can_train() const;