From 98e6019a709cd331ac3901c91bf144343a27b34a Mon Sep 17 00:00:00 2001 From: Dan1ss1mo Date: Thu, 23 Mar 2023 21:12:57 +0300 Subject: [PATCH] Squashed commit of the following: commit 81dfd3a77f873c37693a5e316979b3337d652609 Merge: d1953234f4 4ad1388df4 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Thu Mar 23 20:46:11 2023 +0300 Merge branch 'master' into painres commit d1953234f4c299913ccb6b28160a1410dd50606e Merge: d0292a78e8 53f91463c6 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Thu Mar 16 10:58:40 2023 +0300 Merge branch 'CleverRaven:master' into painres commit d0292a78e88811e2d6311aad77835f2291f12e26 Author: Dan1ss1mo Date: Wed Mar 15 22:30:19 2023 +0300 Update MUTATIONS.md commit a09ce3126c9131e25553335915f6e9e89bab6bdc Author: Dan1ss1mo Date: Wed Mar 15 22:27:34 2023 +0300 docs commit d240fd4ceb05f5e183cea73b117e238666895949 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Tue Mar 14 15:33:11 2023 +0300 Update src/activity_handlers.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> commit f2a3a635105f9dfc295360df2c26fe249c62f811 Author: Dan1ss1mo Date: Wed Mar 8 22:51:44 2023 +0300 Squashed commit of the following: commit c6d7d314b5900cdaeb2723ead8e5f8200f9911bf Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 19:34:50 2023 +0300 Update torso_armor.json commit 6d44c3a4a9334f256a85736fe83198374772c26b Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 19:34:02 2023 +0300 Update torso_armor.json commit f1531053d5ec576b22d4bdca4a1e5ecb86c5b1ef Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 19:29:10 2023 +0300 Update suits_protection.json commit 2f71c08df21be86657a19fe7fc2616f74bde1332 Author: KHeket <102726167+KHeket@users.noreply.github.com> Date: Wed Mar 8 18:12:52 2023 +0300 Freezer recipe and disassemble (#63895) Recipe for freezer and disassemble functionality for it commit 07827cf28621f715383b8a1e8660d9df955b7405 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 17:54:34 2023 +0300 Update character.cpp commit fb2832518746edb0e1d3ce63c4cf4608059f99e9 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 17:53:54 2023 +0300 Update character.cpp commit cd96311f11cd18688509b68da3f0d74065f90f6f Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 17:14:20 2023 +0300 Update src/character.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> commit b53ea936c2e940b6adc813e0d449189d6da60a3e Author: Dan1ss1mo Date: Wed Mar 8 17:13:30 2023 +0300 more fixes commit bab702c8f1ecc0129ae49466e56f7fc2ac3ad571 Author: Dan1ss1mo Date: Wed Mar 8 17:07:41 2023 +0300 some fixes commit f3ab69d8822ad28c7f81d6fb9583e0e46abaeff6 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 16:56:55 2023 +0300 Update character.cpp commit f178740e64912186ed3033b6c4dc41a56df5684f Merge: 9e352aa93f 25793968f2 Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Wed Mar 8 16:44:50 2023 +0300 Merge branch 'master' into painres commit 9e352aa93f63afe984710e1edaf6dce68ad7f545 Author: Dan1ss1mo Date: Sun Feb 19 20:01:10 2023 +0300 Update character.cpp commit 460e05a775c4d0b6d5fc8826cb53a3c0cfa84c0d Author: Dan1ss1mo Date: Sun Feb 19 15:04:24 2023 +0300 linting linting commit eab3f079caa66fff7b4d5cb0b9531eb4eef27515 Author: Dan1ss1mo Date: Sun Feb 19 14:58:40 2023 +0300 Update character.cpp commit 684d1742dfa2b66750473aefddaea66be0a7625c Merge: 4e5a4cfee7 19cdc7464c Author: Dan1ss1mo Date: Fri Feb 17 22:03:13 2023 +0300 Merge branch 'painres' of https://github.com/Dan1ss1mo/Cataclysm-DDA into painres commit 4e5a4cfee756260064157513ba73a7b0052d8d59 Author: Dan1ss1mo Date: Fri Feb 17 22:02:25 2023 +0300 more linting commit 19cdc7464c0796677b6369a8ecab7ad222c5f59f Author: Dan1ss1mo <112878543+Dan1ss1mo@users.noreply.github.com> Date: Fri Feb 17 21:48:31 2023 +0300 linting commit db14729052e0d4e585aa6aa1840b1e09c74d9868 Merge: 53d2559f20 17a74447fd Author: Dan1ss1mo Date: Fri Feb 17 21:41:05 2023 +0300 Merge branch 'painres' of https://github.com/Dan1ss1mo/Cataclysm-DDA into painres commit 53d2559f2044b224d802d6d039c19d04f3fd6d8e Author: Dan1ss1mo Date: Fri Feb 17 21:40:26 2023 +0300 jsonized suffering --- data/json/flags.json | 4 ++++ data/json/mutations/mutations.json | 3 ++- doc/MUTATIONS.md | 1 + src/activity_handlers.cpp | 5 +++-- src/avatar.cpp | 4 ++-- src/bionics.cpp | 12 ++++++------ src/character.cpp | 15 +++++++++++---- src/character_body.cpp | 4 ++-- src/flag.cpp | 1 + src/flag.h | 1 + src/game_inventory.cpp | 5 +++-- src/iexamine.cpp | 4 ++-- src/iuse.cpp | 9 +++++---- src/medical_ui.cpp | 4 ++-- src/mutation.h | 3 ++- src/mutation_data.cpp | 1 + src/player_hardcoded_effects.cpp | 4 ++-- src/sounds.cpp | 5 +++-- src/suffer.cpp | 10 +++++----- 19 files changed, 58 insertions(+), 37 deletions(-) diff --git a/data/json/flags.json b/data/json/flags.json index 6397e8d103ea9..c4c8f7b170e7a 100644 --- a/data/json/flags.json +++ b/data/json/flags.json @@ -1760,6 +1760,10 @@ "id": "TOUGH_FEET", "type": "json_flag" }, + { + "id": "PAIN_IMMUNE", + "type": "json_flag" + }, { "id": "TOURNIQUET", "type": "json_flag" diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index 957560fb2e579..115d775827c33 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -4462,7 +4462,8 @@ "prereqs2": [ "PAINREC3" ], "threshreq": [ "THRESH_MEDICAL" ], "//": "MASOCHIST_MED, CENOBITE, and NOPAIN don't cancel each other. By design. Poor painless people...", - "category": [ "MEDICAL" ] + "category": [ "MEDICAL" ], + "flags": [ "PAIN_IMMUNE" ] }, { "type": "mutation", diff --git a/doc/MUTATIONS.md b/doc/MUTATIONS.md index 9d4c1dc2db2d0..6583fff5bfcc6 100644 --- a/doc/MUTATIONS.md +++ b/doc/MUTATIONS.md @@ -238,6 +238,7 @@ Note that **all new traits that can be obtained through mutation must be purifia "deactivated_eocs": [ "eoc_id_1" ], // List of effect_on_conditions that attempt to activate when this mutation is successfully deactivated. "enchantments": [ "ench_id_1" ], // List of enchantments granted by this mutation. Can be either IDs or an inline definition of the enchantment (see MAGIC.md) "temperature_speed_modifier": 0.5, // If nonzero, become slower when cold, and faster when hot (1.0 gives +/-1% speed for each degree above or below 65 F). + "pain_modifier": 5, // Flat increase (for positive numbers)\ reduction (for negative) to the amount of pain recived. Reduction can go all the way to 0. Applies after pain enchantment. (so if you have Pain Resistant trait along with 5 flat pain reduction and recive 20 pain, you would gain 20*(1-0.25)-5=10 pain) "mana_modifier": 100, // Positive or negative change to total mana pool. "flags": [ "UNARMED_BONUS" ] // List of flag_IDs and json_flag_IDs granted by the mutation. Note: trait_IDs can be set and generate no errors, but they're not actually "active". } diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index c405291d64ee3..e748e0b2a41c9 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -191,6 +191,7 @@ static const itype_id itype_burnt_out_bionic( "burnt_out_bionic" ); static const itype_id itype_muscle( "muscle" ); static const json_character_flag json_flag_CANNIBAL( "CANNIBAL" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_PSYCHOPATH( "PSYCHOPATH" ); static const json_character_flag json_flag_SAPIOVORE( "SAPIOVORE" ); @@ -208,7 +209,6 @@ static const species_id species_HUMAN( "HUMAN" ); static const species_id species_ZOMBIE( "ZOMBIE" ); static const trait_id trait_DEBUG_HS( "DEBUG_HS" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_SPIRITUAL( "SPIRITUAL" ); static const trait_id trait_STOCKY_TROGLO( "STOCKY_TROGLO" ); @@ -2860,7 +2860,8 @@ void activity_handlers::operation_do_turn( player_activity *act, Character *you Character &player_character = get_player_character(); const bool u_see = player_character.sees( you->pos() ) && ( !player_character.has_effect( effect_narcosis ) || - player_character.has_bionic( bio_painkiller ) || player_character.has_trait( trait_NOPAIN ) ); + player_character.has_bionic( bio_painkiller ) || + player_character.has_flag( json_flag_PAIN_IMMUNE ) ); const int difficulty = act->values.front(); diff --git a/src/avatar.cpp b/src/avatar.cpp index 3b8d3ff79a755..ac7ee4f17cae8 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -108,6 +108,7 @@ static const itype_id itype_guidebook( "guidebook" ); static const itype_id itype_mut_longpull( "mut_longpull" ); static const json_character_flag json_flag_ALARMCLOCK( "ALARMCLOCK" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_WEBBED_HANDS( "WEBBED_HANDS" ); static const move_mode_id move_mode_crouch( "crouch" ); @@ -129,7 +130,6 @@ static const trait_id trait_DEBUG_CLOAK( "DEBUG_CLOAK" ); static const trait_id trait_INSECT_ARMS( "INSECT_ARMS" ); static const trait_id trait_INSECT_ARMS_OK( "INSECT_ARMS_OK" ); static const trait_id trait_M_SKIN3( "M_SKIN3" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PROF_DICEMASTER( "PROF_DICEMASTER" ); static const trait_id trait_SHELL2( "SHELL2" ); static const trait_id trait_SHELL3( "SHELL3" ); @@ -1793,7 +1793,7 @@ void avatar::reassign_item( item &it, int invlet ) void avatar::add_pain_msg( int val, const bodypart_id &bp ) const { - if( has_trait( trait_NOPAIN ) ) { + if( has_flag( json_flag_PAIN_IMMUNE ) ) { return; } if( bp == bodypart_id( "bp_null" ) ) { diff --git a/src/bionics.cpp b/src/bionics.cpp index 48554acf897a8..c1f6a3dffc548 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -163,6 +163,7 @@ static const json_character_flag json_flag_BIONIC_POWER_SOURCE( "BIONIC_POWER_SO static const json_character_flag json_flag_BIONIC_TOGGLED( "BIONIC_TOGGLED" ); static const json_character_flag json_flag_BIONIC_WEAPON( "BIONIC_WEAPON" ); static const json_character_flag json_flag_ENHANCED_VISION( "ENHANCED_VISION" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const material_id fuel_type_metabolism( "metabolism" ); static const material_id fuel_type_sun_light( "sunlight" ); @@ -190,7 +191,6 @@ static const trait_id trait_DEBUG_BIONICS( "DEBUG_BIONICS" ); static const trait_id trait_MASOCHIST( "MASOCHIST" ); static const trait_id trait_MASOCHIST_MED( "MASOCHIST_MED" ); static const trait_id trait_NONE( "NONE" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PROF_AUTODOC( "PROF_AUTODOC" ); static const trait_id trait_PROF_MED( "PROF_MED" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); @@ -1800,7 +1800,7 @@ void Character::bionics_uninstall_failure( int difficulty, int success, float ad std::set bp_hurt; switch( fail_type ) { case 1: - if( !has_trait( trait_NOPAIN ) ) { + if( !has_flag( json_flag_PAIN_IMMUNE ) ) { add_msg_if_player( m_bad, _( "It really hurts!" ) ); mod_pain( rng( 10, 30 ) ); } @@ -1887,7 +1887,7 @@ void Character::bionics_uninstall_failure( monster &installer, Character &patien std::set bp_hurt; switch( fail_type ) { case 1: - if( !has_trait( trait_NOPAIN ) ) { + if( !has_flag( json_flag_PAIN_IMMUNE ) ) { patient.add_msg_if_player( m_bad, _( "It really hurts!" ) ); patient.mod_pain( rng( 10, 30 ) ); } @@ -1940,7 +1940,7 @@ bool Character::has_enough_anesth( const itype &cbm, Character &patient ) const return false; } - if( patient.has_bionic( bio_painkiller ) || patient.has_trait( trait_NOPAIN ) || + if( patient.has_bionic( bio_painkiller ) || patient.has_flag( json_flag_PAIN_IMMUNE ) || has_trait( trait_DEBUG_BIONICS ) ) { return true; } @@ -1954,7 +1954,7 @@ bool Character::has_enough_anesth( const itype &cbm, Character &patient ) const bool Character::has_enough_anesth( const itype &cbm ) const { - if( has_bionic( bio_painkiller ) || has_trait( trait_NOPAIN ) || + if( has_bionic( bio_painkiller ) || has_flag( json_flag_PAIN_IMMUNE ) || has_trait( trait_DEBUG_BIONICS ) ) { return true; } @@ -2562,7 +2562,7 @@ void Character::bionics_install_failure( const bionic_id &bid, const std::string switch( fail_type ) { case 1: - if( !has_trait( trait_NOPAIN ) ) { + if( !has_flag( json_flag_PAIN_IMMUNE ) ) { add_msg_if_player( m_bad, _( "It really hurts!" ) ); mod_pain( rng( 10, 30 ) ); } diff --git a/src/character.cpp b/src/character.cpp index bdaf6e4e483db..4e1c80b8d4369 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -313,6 +313,7 @@ static const json_character_flag json_flag_NON_THRESH( "NON_THRESH" ); static const json_character_flag json_flag_NO_DISEASE( "NO_DISEASE" ); static const json_character_flag json_flag_NO_RADIATION( "NO_RADIATION" ); static const json_character_flag json_flag_NO_THIRST( "NO_THIRST" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_PRED2( "PRED2" ); static const json_character_flag json_flag_PRED3( "PRED3" ); static const json_character_flag json_flag_PRED4( "PRED4" ); @@ -435,7 +436,6 @@ static const trait_id trait_NIGHTVISION3( "NIGHTVISION3" ); static const trait_id trait_NOMAD( "NOMAD" ); static const trait_id trait_NOMAD2( "NOMAD2" ); static const trait_id trait_NOMAD3( "NOMAD3" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PACIFIST( "PACIFIST" ); static const trait_id trait_PADDED_FEET( "PADDED_FEET" ); static const trait_id trait_PARAIMMUNE( "PARAIMMUNE" ); @@ -4653,7 +4653,7 @@ void Character::update_needs( int rate_multiplier ) // Huge folks take penalties for cramming themselves in vehicles if( in_vehicle && get_size() == creature_size::huge && - !( has_trait( trait_NOPAIN ) || has_effect( effect_narcosis ) ) ) { + !( has_flag( json_flag_PAIN_IMMUNE ) || has_effect( effect_narcosis ) ) ) { vehicle *veh = veh_pointer_or_null( get_map().veh_at( pos() ) ); // it's painful to work the controls, but passengers in open topped vehicles are fine if( veh && ( veh->enclosed_at( pos() ) || veh->player_in_control( *this ) ) ) { @@ -4797,7 +4797,7 @@ void Character::check_needs_extremes() get_event_bus().send( getID(), efftype_id() ); set_part_hp_cur( body_part_torso, 0 ); } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) { - if( !has_trait( trait_NOPAIN ) ) { + if( !has_flag( json_flag_PAIN_IMMUNE ) ) { add_msg_player_or_npc( m_bad, _( "Your heart spasms painfully and stops." ), _( "'s heart spasms painfully and stops." ) ); @@ -5797,6 +5797,7 @@ float calc_mutation_value_multiplicative( const std::vector )>> mutation_value_map = { { "healing_awake", calc_mutation_value<&mutation_branch::healing_awake> }, + { "pain_modifier", calc_mutation_value<&mutation_branch::pain_modifier> }, { "healing_multiplier", calc_mutation_value_multiplicative<&mutation_branch::healing_multiplier> }, { "mending_modifier", calc_mutation_value_multiplicative<&mutation_branch::mending_modifier> }, { "hp_modifier", calc_mutation_value<&mutation_branch::hp_modifier> }, @@ -11022,7 +11023,7 @@ void Character::mod_pain( int npain ) { if( npain > 0 ) { double mult = enchantment_cache->get_value_multiply( enchant_vals::mod::PAIN ); - if( has_trait( trait_NOPAIN ) || has_effect( effect_narcosis ) ) { + if( has_flag( json_flag_PAIN_IMMUNE ) || has_effect( effect_narcosis ) ) { return; } // if there is a positive multiplier we always want to add at least 1 pain @@ -11032,6 +11033,12 @@ void Character::mod_pain( int npain ) if( mult < 0 ) { npain = roll_remainder( npain * ( 1 + mult ) ); } + if( mutation_value( "pain_modifier" ) != 0 ) { + npain = roll_remainder( npain + mutation_value( "pain_modifier" ) ); + if( npain < 0 ) { + return; + } + } npain += enchantment_cache->get_value_add( enchant_vals::mod::PAIN ); // no matter how powerful the enchantment if we are gaining pain we always gain at least a little/don't lose any diff --git a/src/character_body.cpp b/src/character_body.cpp index 826f109aa0229..e6a1b866baf4c 100644 --- a/src/character_body.cpp +++ b/src/character_body.cpp @@ -62,6 +62,7 @@ static const json_character_flag json_flag_HEAT_IMMUNE( "HEAT_IMMUNE" ); static const json_character_flag json_flag_IGNORE_TEMP( "IGNORE_TEMP" ); static const json_character_flag json_flag_LIMB_LOWER( "LIMB_LOWER" ); static const json_character_flag json_flag_NO_THIRST( "NO_THIRST" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const trait_id trait_BARK( "BARK" ); static const trait_id trait_CHITIN_FUR( "CHITIN_FUR" ); @@ -74,7 +75,6 @@ static const trait_id trait_FUR( "FUR" ); static const trait_id trait_LIGHTFUR( "LIGHTFUR" ); static const trait_id trait_LUPINE_FUR( "LUPINE_FUR" ); static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); static const trait_id trait_SLIMY( "SLIMY" ); static const trait_id trait_URSINE_FUR( "URSINE_FUR" ); @@ -1100,7 +1100,7 @@ bodypart_id Character::body_window( const std::string &menu_header, // If this is an NPC, the player is the one examining them and so the fact // that they can't self-diagnose effectively doesn't matter - bool no_feeling = is_avatar() && has_trait( trait_NOPAIN ); + bool no_feeling = is_avatar() && has_flag( json_flag_PAIN_IMMUNE ); for( size_t i = 0; i < parts.size(); i++ ) { const healable_bp &e = parts[i]; diff --git a/src/flag.cpp b/src/flag.cpp index d54960af76116..412ee9de2a89a 100644 --- a/src/flag.cpp +++ b/src/flag.cpp @@ -228,6 +228,7 @@ const flag_id flag_ORGANIC( "ORGANIC" ); const flag_id flag_OUTER( "OUTER" ); const flag_id flag_OVERSIZE( "OVERSIZE" ); const flag_id flag_PADDED( "PADDED" ); +const flag_id flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); const flag_id flag_PALS_LARGE( "PALS_LARGE" ); const flag_id flag_PALS_MEDIUM( "PALS_MEDIUM" ); const flag_id flag_PALS_SMALL( "PALS_SMALL" ); diff --git a/src/flag.h b/src/flag.h index a3f566f460acb..54b454ea4dde0 100644 --- a/src/flag.h +++ b/src/flag.h @@ -234,6 +234,7 @@ extern const flag_id flag_ORGANIC; extern const flag_id flag_OUTER; extern const flag_id flag_OVERSIZE; extern const flag_id flag_PADDED; +extern const flag_id flag_PAIN_IMMUNE; extern const flag_id flag_PALS_SMALL; extern const flag_id flag_PALS_MEDIUM; extern const flag_id flag_PALS_LARGE; diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index f8438da290cc6..29bc6f1874da3 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -69,6 +69,8 @@ static const activity_id ACT_EAT_MENU( "ACT_EAT_MENU" ); static const bionic_id bio_fitnessband( "bio_fitnessband" ); static const bionic_id bio_painkiller( "bio_painkiller" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); + static const flag_id json_flag_CALORIES_INTAKE( "CALORIES_INTAKE" ); static const itype_id itype_fitness_band( "fitness_band" ); @@ -78,7 +80,6 @@ static const quality_id qual_ANESTHESIA( "ANESTHESIA" ); static const requirement_id requirement_data_anesthetic( "anesthetic" ); static const trait_id trait_DEBUG_BIONICS( "DEBUG_BIONICS" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_SAPROPHAGE( "SAPROPHAGE" ); static const trait_id trait_SAPROVORE( "SAPROVORE" ); @@ -2227,7 +2228,7 @@ static item_location autodoc_internal( Character &you, Character &patient, int drug_count = 0; if( !surgeon ) {//surgeon use their own anesthetic, player just need money - if( patient.has_trait( trait_NOPAIN ) ) { + if( patient.has_flag( json_flag_PAIN_IMMUNE ) ) { hint = _( "Patient has deadened nerves. Anesthesia unneeded." ); } else if( patient.has_bionic( bio_painkiller ) ) { hint = _( "Patient has Sensory Dulling CBM installed. Anesthesia unneeded." ); diff --git a/src/iexamine.cpp b/src/iexamine.cpp index aefd3caf833dd..740b8d805a5e8 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -178,6 +178,7 @@ static const itype_id itype_unfinished_cac2( "unfinished_cac2" ); static const itype_id itype_unfinished_charcoal( "unfinished_charcoal" ); static const json_character_flag json_flag_ATTUNEMENT( "ATTUNEMENT" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_SUPER_HEARING( "SUPER_HEARING" ); static const json_character_flag json_flag_WALL_CLING( "WALL_CLING" ); @@ -237,7 +238,6 @@ static const trait_id trait_M_DEFENDER( "M_DEFENDER" ); static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" ); static const trait_id trait_M_FERTILE( "M_FERTILE" ); static const trait_id trait_M_SPORES( "M_SPORES" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PROBOSCIS( "PROBOSCIS" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); static const trait_id trait_SHELL2( "SHELL2" ); @@ -5178,7 +5178,7 @@ void iexamine::autodoc( Character &you, const tripoint &examp ) bool needs_anesthesia = true; std::vector anesth_kit; - if( patient.has_trait( trait_NOPAIN ) || patient.has_bionic( bio_painkiller ) || + if( patient.has_flag( json_flag_PAIN_IMMUNE ) || patient.has_bionic( bio_painkiller ) || amenu.ret > 1 ) { needs_anesthesia = false; } else { diff --git a/src/iuse.cpp b/src/iuse.cpp index 68dbd2cbb2333..008efeb70e579 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -236,6 +236,8 @@ static const efftype_id effect_weak_antibiotic_visible( "weak_antibiotic_visible static const efftype_id effect_webbed( "webbed" ); static const efftype_id effect_weed_high( "weed_high" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); + static const flag_id json_flag_POWER_CORD( "POWER_CORD" ); static const furn_str_id furn_f_translocator_buoy( "f_translocator_buoy" ); @@ -376,7 +378,6 @@ static const trait_id trait_MARLOSS_AVOID( "MARLOSS_AVOID" ); static const trait_id trait_MARLOSS_BLUE( "MARLOSS_BLUE" ); static const trait_id trait_MARLOSS_YELLOW( "MARLOSS_YELLOW" ); static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); static const trait_id trait_SPIRITUAL( "SPIRITUAL" ); @@ -772,7 +773,7 @@ std::optional iuse::antiparasitic( Character *p, item *, bool, const tripoi if( p->has_effect( effect_tapeworm ) ) { p->remove_effect( effect_tapeworm ); p->guts.mod_nutr( -1 ); // You just digested the tapeworm. - if( p->has_trait( trait_NOPAIN ) ) { + if( p->has_flag( json_flag_PAIN_IMMUNE ) ) { p->add_msg_if_player( m_good, _( "Your bowels clench as something inside them dies." ) ); } else { p->add_msg_if_player( m_mixed, _( "Your bowels spasm painfully as something inside them dies." ) ); @@ -789,7 +790,7 @@ std::optional iuse::antiparasitic( Character *p, item *, bool, const tripoi } if( p->has_effect( effect_brainworms ) ) { p->remove_effect( effect_brainworms ); - if( p->has_trait( trait_NOPAIN ) ) { + if( p->has_flag( json_flag_PAIN_IMMUNE ) ) { p->add_msg_if_player( m_good, _( "The pressure inside your head feels better already." ) ); } else { p->add_msg_if_player( m_mixed, @@ -799,7 +800,7 @@ std::optional iuse::antiparasitic( Character *p, item *, bool, const tripoi } if( p->has_effect( effect_paincysts ) ) { p->remove_effect( effect_paincysts ); - if( p->has_trait( trait_NOPAIN ) ) { + if( p->has_flag( json_flag_PAIN_IMMUNE ) ) { p->add_msg_if_player( m_good, _( "The stiffness in your joints goes away." ) ); } else { p->add_msg_if_player( m_good, _( "The pain in your joints goes away." ) ); diff --git a/src/medical_ui.cpp b/src/medical_ui.cpp index 870b1f123deb2..021cd60174090 100644 --- a/src/medical_ui.cpp +++ b/src/medical_ui.cpp @@ -27,8 +27,8 @@ static const efftype_id effect_infected( "infected" ); static const efftype_id effect_mending( "mending" ); static const json_character_flag json_flag_ECTOTHERM( "ECTOTHERM" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_SUNLIGHT_DEPENDENT( "SUNLIGHT_DEPENDENT" ); static const trait_id trait_TROGLO( "TROGLO" ); static const trait_id trait_TROGLO2( "TROGLO2" ); @@ -353,7 +353,7 @@ static medical_column draw_health_summary( const int column_count, avatar *playe const bool bleeding = bleed_intensity > 0; const bool bitten = player->has_effect( effect_bite, part.id() ); const bool infected = player->has_effect( effect_infected, part.id() ); - const bool no_feeling = player->has_trait( trait_NOPAIN ); + const bool no_feeling = player->has_flag( json_flag_PAIN_IMMUNE ); const int maximal_hp = player->get_part_hp_max( part ); const int current_hp = player->get_part_hp_cur( part ); const bool limb_is_broken = player->is_limb_broken( part ); diff --git a/src/mutation.h b/src/mutation.h index 5e20e60cabc1b..c66ce3dd37dda 100644 --- a/src/mutation.h +++ b/src/mutation.h @@ -203,7 +203,8 @@ struct mutation_branch { std::optional healing_awake = std::nullopt; std::optional healing_multiplier = std::nullopt; // Limb mending bonus - std::optional mending_modifier = std::nullopt; + std::optional mending_modifier = cata::nullopt; + std::optional pain_modifier = cata::nullopt; // Bonus HP multiplier. That is, 1.0 doubles hp, -0.5 halves it. std::optional hp_modifier = std::nullopt; // Second HP modifier that stacks with first but is otherwise identical. diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index e4677538bd185..def74170a7f78 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -387,6 +387,7 @@ void mutation_branch::load( const JsonObject &jo, const std::string & ) } optional( jo, was_loaded, "healing_awake", healing_awake, std::nullopt ); + optional( jo, was_loaded, "pain_modifier", pain_modifier, std::nullopt ); optional( jo, was_loaded, "healing_multiplier", healing_multiplier, std::nullopt ); optional( jo, was_loaded, "mending_modifier", mending_modifier, std::nullopt ); optional( jo, was_loaded, "hp_modifier", hp_modifier, std::nullopt ); diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index ca8455c23c633..3fd19b9e8d42b 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -102,6 +102,7 @@ static const efftype_id effect_weak_antibiotic( "weak_antibiotic" ); static const efftype_id effect_winded( "winded" ); static const json_character_flag json_flag_ALARMCLOCK( "ALARMCLOCK" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_SEESLEEP( "SEESLEEP" ); static const mongroup_id GROUP_NETHER( "GROUP_NETHER" ); @@ -123,7 +124,6 @@ static const trait_id trait_HIBERNATE( "HIBERNATE" ); static const trait_id trait_INFRESIST( "INFRESIST" ); static const trait_id trait_M_IMMUNE( "M_IMMUNE" ); static const trait_id trait_M_SKIN3( "M_SKIN3" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" ); static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" ); static const trait_id trait_WATERSLEEP( "WATERSLEEP" ); @@ -721,7 +721,7 @@ static void eff_fun_datura( Character &u, effect &it ) } if( dur > 1800_minutes && one_in( 300 * 512 ) ) { - if( !u.has_trait( trait_NOPAIN ) ) { + if( !u.has_flag( json_flag_PAIN_IMMUNE ) ) { u.add_msg_if_player( m_bad, _( "Your heart spasms painfully and stops, dragging you back to reality as you die." ) ); } else { diff --git a/src/sounds.cpp b/src/sounds.cpp index 3b81e1584d59c..e712c8fe2543f 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -181,9 +181,10 @@ static const ter_str_id ter_t_underbrush_harvested_spring( "t_underbrush_harvest static const ter_str_id ter_t_underbrush_harvested_summer( "t_underbrush_harvested_summer" ); static const ter_str_id ter_t_underbrush_harvested_winter( "t_underbrush_harvested_winter" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); + static const trait_id trait_HEAVYSLEEPER( "HEAVYSLEEPER" ); static const trait_id trait_HEAVYSLEEPER2( "HEAVYSLEEPER2" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); struct monster_sound_event { int volume; @@ -565,7 +566,7 @@ void sounds::process_sound_markers( Character *you ) if( is_sound_deafening && !you->is_immune_effect( effect_deaf ) ) { you->add_effect( effect_deaf, std::min( 4_minutes, time_duration::from_turns( felt_volume - 130 ) / 8 ) ); - if( !you->has_trait( trait_NOPAIN ) ) { + if( !you->has_flag( json_flag_PAIN_IMMUNE ) ) { you->add_msg_if_player( m_bad, _( "Your eardrums suddenly ache!" ) ); if( you->get_pain() < 10 ) { you->mod_pain( rng( 0, 2 ) ); diff --git a/src/suffer.cpp b/src/suffer.cpp index db1058ed87947..e3e431650bf1d 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -123,6 +123,7 @@ static const json_character_flag json_flag_GLARE_RESIST( "GLARE_RESIST" ); static const json_character_flag json_flag_MEND_ALL( "MEND_ALL" ); static const json_character_flag json_flag_MEND_LIMB( "MEND_LIMB" ); static const json_character_flag json_flag_NYCTOPHOBIA( "NYCTOPHOBIA" ); +static const json_character_flag json_flag_PAIN_IMMUNE( "PAIN_IMMUNE" ); static const json_character_flag json_flag_RAD_DETECT( "RAD_DETECT" ); static const mtype_id mon_zombie( "mon_zombie" ); @@ -151,7 +152,6 @@ static const trait_id trait_M_BLOSSOMS( "M_BLOSSOMS" ); static const trait_id trait_M_SPORES( "M_SPORES" ); static const trait_id trait_NARCOLEPTIC( "NARCOLEPTIC" ); static const trait_id trait_NONADDICTIVE( "NONADDICTIVE" ); -static const trait_id trait_NOPAIN( "NOPAIN" ); static const trait_id trait_PER_SLIME( "PER_SLIME" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); static const trait_id trait_RADIOACTIVE1( "RADIOACTIVE1" ); @@ -464,7 +464,7 @@ void suffer::while_awake( Character &you, const int current_stim ) void suffer::from_chemimbalance( Character &you ) { - if( one_turn_in( 6_hours ) && !you.has_trait( trait_NOPAIN ) ) { + if( one_turn_in( 6_hours ) && !you.has_flag( json_flag_PAIN_IMMUNE ) ) { you.add_msg_if_player( m_bad, _( "You suddenly feel sharp pain for no reason." ) ); you.mod_pain( 3 * rng( 1, 3 ) ); } @@ -472,7 +472,7 @@ void suffer::from_chemimbalance( Character &you ) int pkilladd = 5 * rng( -1, 2 ); if( pkilladd > 0 ) { you.add_msg_if_player( m_bad, _( "You suddenly feel numb." ) ); - } else if( ( pkilladd < 0 ) && ( !you.has_trait( trait_NOPAIN ) ) ) { + } else if( ( pkilladd < 0 ) && ( !you.has_flag( json_flag_PAIN_IMMUNE ) ) ) { you.add_msg_if_player( m_bad, _( "You suddenly ache." ) ); } you.mod_painkiller( pkilladd ); @@ -1377,7 +1377,7 @@ void suffer::from_bad_bionics( Character &you ) if( you.has_bionic( bio_dis_shock ) && you.get_power_level() > bio_dis_shock->power_trigger && one_turn_in( 2_hours ) && !you.has_effect( effect_narcosis ) ) { - if( !you.has_trait( trait_NOPAIN ) ) { + if( !you.has_flag( json_flag_PAIN_IMMUNE ) ) { you.add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) ); you.mod_pain( 1 ); } else { @@ -1399,7 +1399,7 @@ void suffer::from_bad_bionics( Character &you ) sfx::play_variant_sound( "bionics", "elec_discharge", 100 ); } if( you.has_bionic( bio_dis_acid ) && one_turn_in( 150_minutes ) ) { - if( !you.has_trait( trait_NOPAIN ) ) { + if( !you.has_flag( json_flag_PAIN_IMMUNE ) ) { you.add_msg_if_player( m_bad, _( "You suffer a burning acidic discharge!" ) ); } else { you.add_msg_if_player( m_bad, _( "You experience an acidic discharge!" ) );