diff options
| author | jc_gargma <jc_gargma@iserlohn-fortress.net> | 2023-10-02 19:19:40 -0700 | 
|---|---|---|
| committer | jc_gargma <jc_gargma@iserlohn-fortress.net> | 2023-10-02 19:19:40 -0700 | 
| commit | 8847061d07ba161a1a768f991fc64f9058ce3902 (patch) | |
| tree | 45c4709bb979c653b01c55008d2b5ab0becbd656 | |
| parent | Port out 8x40mm ammo to my ammo rebalance mod. (diff) | |
| download | cataclysm-bn-8847061d07ba161a1a768f991fc64f9058ce3902.tar.xz | |
Updated to 2023-09-23-0420
Port out shotpaper to my ammo rebalance mod.
Revert the easy mode limb repair commit.
Remove obsolete doc install.
| -rw-r--r-- | PKGBUILD | 25 | ||||
| -rw-r--r-- | revert-08_undo-rifle-balance-pass.patch | 2 | ||||
| -rw-r--r-- | revert-09_undo-yet-more-ammo-balancing.patch | 37 | ||||
| -rw-r--r-- | revert-18-Simplify-broken-limb-mending-3054.patch | 830 | 
4 files changed, 844 insertions, 50 deletions
@@ -17,9 +17,9 @@ pkgbase=cataclysm-bn  pkgname=(cataclysm-bn cataclysm-bn-tiles)  pkgname=cataclysm-bn  _pkgname=Cataclysm-BN-cbn-experimental -pkgver=202309171522 -_pkgver=2023-09-17-1522 -pkgrel=2 +pkgver=202309230420 +_pkgver=2023-09-23-0420 +pkgrel=1  pkgdesc="A post-apocalyptic roguelike."  #url="http://cataclysmrl.blogspot.com/"  #url="http://www.cataclysm.glyphgryph.com/" @@ -51,6 +51,7 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-          "revert-14_Removed-unrelated-references-2738.patch"          "revert-15_Fix-mutant-scenarios-adding-an-obsoleted-trait-2929.patch"          "revert-17_Rivtech-mainline-3092.patch" +        "revert-18-Simplify-broken-limb-mending-3054.patch"          "ammo-01_inconsistent-ammo-names.patch"          "ammo-03_fix-reloaded-50bmg.patch" @@ -155,7 +156,7 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-          "cataclysm-dda-soundpack_jcsoundpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-soundpack_jcsoundpack.git/snapshot/cataclysm-dda-soundpack_jcsoundpack-master.tar.xz"          "cataclysm-dda-musicpack_coag-musicpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-musicpack_coag-musicpack.git/snapshot/cataclysm-dda-musicpack_coag-musicpack-master.tar.xz"          ) -b2sums=('b3ec5268da460d8a1bfcbf24b52109dad611db181eba6759566bf532e3e2502f32db5d6d492408872c7a6d081e74d686338f0cee48a5a949cf30e50576150811' +b2sums=('6ecc687444378aa0ea4775b2efba1f2945d78220756261a1a67f2f2dc017ed47bcb2601ceb5be6e5e2d6c49110a26d60bd6b8f384824b04cbc2821112eae3ef4'          '069ecde58859b3d44cd687c4b6e718610cefb693ff86e66f199ebfb1b3072023ad2b6f0c28e27ef9c1ce4997f6a5b2ca0d45046996b3ff35a4aeaeb1a7cf9421'          'ad88bc6c1e3c8183a313b5eec42f98d6956afea349feff34a86e4536c9921fa99d2594282caf27de8ebb7ffb56376ed2e76d572227bfd6d8173c7bb1f01e23b8'          '6f70e90359a14e4839d9a2683debb88850e5dd387add911ad68fd87e5512cfcdd435da63e1e370358153673fd5a72a9b1e9c94f1979edb7948b4da8c82407bad' @@ -166,8 +167,8 @@ b2sums=('b3ec5268da460d8a1bfcbf24b52109dad611db181eba6759566bf532e3e2502f32db5d6          '2d197903715263628e767e867e9b20b9ebd3d85f8983ac8f1e2b534f2b6f8c0470886c79a409f117ad43348aa6aef2a6298925ae27faa32814183ad7677528ac'          'fe11304ee87f08f6691a77e5e814073fdb577d60a83df614c98cb05577375b03c979df1f1fa048c5d54798d0054cfc4f3f512d45009a85b6be228792482d5cd6'          'e6f0c25863074990ac54ec0a8fd05a3458c05bf41b7ebf9ec8e7ca302694b5a2fc89289d1a8818c44f0b879c61c2ecbd9d1defc9fc4a5a5fa0c98910859c8543' -        '43d89f815f7c7d7e57463174ad3bfa304a21c93dd34659dfa95824582f482fb97ef70f6d4c83be29b2b10b22c27ff1d19ce4ea1e2a0653fce35d53cdb30fb897' -        '0cc87fa8cb54b3001cc24f9c19a19bdc3933475cbe68a120099ecba3efdea5f1af777976cbe35ab7dfea0e51ed60ba0e3e1d9ff56702531f08ce0c0779c2555e' +        'cebd24bd72ace004972900eac56fc2b4d43d22d0fb7dbac014b55848f80067ba9c09e721543784bb9db19f28af3803288bd2be5821cbb97ebfac7a94868191a5' +        'c04a8b3df0d356d2a47eb9174af0851bf8687717d1240f3771f9cfacf08d5dc49900fe10ded6365fba87bc62b6de5d93810aa102693a1f3956382fae0d452d44'          '7311e7cfaf4c47ac2cc62ec2590c7f5b09b86615400f87f47bc62418d0028dc78ef88380022a70cbdb5e542becee9ad443cbf03e2793443d0e11656e91c0abc5'          '5df4497d779d6980a540f0f1dd54959ca403e8b00a9f4bd1a91fee3c41d351e216abb08f1ae6729ca0fcb04efda789804b5df5c86e0003d25998e988254712f7'          '68cc05b6224d873a2a5728e0120ce09e5c45f53f8c7bc03148a0ede00582975d740e42ddad1aa02c58fabf6d25aa649ddf73e3af2b7c98090e840c808e0742c8' @@ -175,6 +176,7 @@ b2sums=('b3ec5268da460d8a1bfcbf24b52109dad611db181eba6759566bf532e3e2502f32db5d6          '3999499f63c50ab9fb38edab7592bcba4f8ab9a51b63d96445a9a6af843d5c5a36f36838735528fc42e5eec5c9e375e704fab1aa55df03f5a804e54d247edaa5'          '2de96509a572c1eca36d63f1a049a27583cd0f2df53605b927c9b5112d4e2385bccc82ba1a37af06fe756f96cc1e8c9d4b6cd081ad70651ec09ac57b93cee84f'          '664d6d2d4427040b25d9971fa07b32d3c1343dd60a9702835568ba1e287422ab2659a4a4e324e422755b6c655e324ca203933b6815c7b2e512beb4f15c4a27d8' +        'ee3722ba1367d993605c0cee12e67b8e10dcda0401c4480d8915bd3ac587c8a3b84379ef6f98d6e93cf433b1dae7a0db35937271787bc6b893b373dc1d44ae7d'          'ea9e227eff0a9470a06effc35d8e991c0e21d5521e0325317ab36760b5bb3256676fee29dd948fcc7f4b09ce9235c2d859cd22d6839ebf14deb369cdf97b20f0'          '124893f23b7d865709fa87a9fade8fb01e596c1f31b0811ab32d5e730e1101c62af672eaf5fe9cdefa338fc25164407023f4c7dcc7cacdb0c86b4713180d345d'          '67cdb7e097bbb46da5cf04708bc2858b080d1a85742afc4c088da3e4e3fdeb6e4c51240fc5a6b9a1c7d927b30b3d251236e025ee4e5496142a7716d4ba51b82c' @@ -216,7 +218,7 @@ b2sums=('b3ec5268da460d8a1bfcbf24b52109dad611db181eba6759566bf532e3e2502f32db5d6          '9fbf8cf2aaa18c5cccca24783f40503cf7b7c66731f65450cc312e8b29145c56c23d31d19063dccdf3790ec06480d773d7d64de1672f38b7a4740a8aa0fd4f7d'          'abafa39e57cf04396b841833215aca427655dd3b56ebc260b8a57d6376360b31a4b1d4493da76ec4dc0129939ab9e23cada70dd6f49e647f02bce12c81f6451a'          'e6eda6cf4831df11facb124ab80972ddffabc8e2a61f8180275c7a95a8f00917301e9b8912f2418138c9dabd91c979d5d5b5d0b2b4b8eae3891f9c1880a4c526' -        'de272d4124994e707946255a2bb0c15de912f2d049e777487be962080f2e27463e61c6cd7f3d6d0b4b82002ef18baafdf4e64c8c42de82aff380c53d6eddba9c' +        '8eba2f66280defcc930424d695baff297cff32e91e73f01210bb3f26389ea9e93b4b4d9e2c5a5a048756eff219d51c3fbf3f05690c3c984afcc32c3928df91aa'          '80da2c341d8564a47bc460fcdaf9196ac3bb77f0f2ba56bd71089e80e7481728a3ccbdcfcbc3bf70a9c9e5d9d9b01f2ca6615b67c7ab61003808ce00f6545ba3'          'b8a64accada87ee5be989c5307805610c9b5c0327bc107aab237ac3225dd9e4c51b6c79a2a7de15fe187d3c32d7cbe1c462f9b0e9fb5d5a55a74236c7061e96e'          '85aeb5920ee5879848be4057324153a077fe907bed527ed8f9b80a3c5ee1ef64786f63ee2999f5ba74e80a43e99ded3280ce27759c1f7b73259a6e2b5e584aa8' @@ -285,7 +287,7 @@ prepare() {    sed -i 's|cataclysm-dda|cataclysm-bn|' src/path_info.cpp    # Fix version -  sed -i 's|VERSION = unstable|VERSION = "0.2-experimental 2023-09-17-1522"|' Makefile +  sed -i 's|VERSION = unstable|VERSION = "0.2-experimental 2023-09-23-0420"|' Makefile    # # # Hotfixes @@ -294,8 +296,10 @@ prepare() {    # # # Reverts    echo "Applying revert patches" +  # # Revert easy-mode limb mending +  patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-18-Simplify-broken-limb-mending-3054.patch +    # # Revert mainline craftable rivtech ammo -  #echo "Applying revert-17_Rivtech-mainline-3092.patch"    patch -NREp1 --no-backup-if-mismatch -i "$srcdir"/revert-17_Rivtech-mainline-3092.patch    # # More reverts for generic night vision @@ -729,9 +733,6 @@ package_cataclysm-bn() {    # Docs    install -d "$pkgdir/usr/share/doc/cataclysm-bn"    cp --reflink -r doc/* "$pkgdir/usr/share/doc/cataclysm-bn" -  # undo symlink -  rm "$pkgdir/usr/share/doc/cataclysm-bn/JSON_LOADING_ORDER.md" -  cp --reflink 'data/json/LOADING_ORDER.md' "$pkgdir/usr/share/doc/cataclysm-bn/JSON_LOADING_ORDER.md"    # License    install -Dm644 LICENSE.txt "$pkgdir/usr/share/licenses/$pkgname/LICENSE" diff --git a/revert-08_undo-rifle-balance-pass.patch b/revert-08_undo-rifle-balance-pass.patch index 45ca828..c93e339 100644 --- a/revert-08_undo-rifle-balance-pass.patch +++ b/revert-08_undo-rifle-balance-pass.patch @@ -11,7 +11,7 @@ Subject: [PATCH 074/177] Ammo rebalance project, part 6 (#1851)  * I knew I forgot one -* Revert shotshell and flintlock changes for now +* Revert shotshell changes for now  * Slight nudge to .233 and .308 per feedback diff --git a/revert-09_undo-yet-more-ammo-balancing.patch b/revert-09_undo-yet-more-ammo-balancing.patch index 596e33a..aa6efad 100644 --- a/revert-09_undo-yet-more-ammo-balancing.patch +++ b/revert-09_undo-yet-more-ammo-balancing.patch @@ -26,7 +26,6 @@ Doi   data/json/items/ammo/5x50.json                |  8 ++-   data/json/items/ammo/8x40mm.json              | 23 ++++----   data/json/items/ammo/flintlock.json           |  5 +- - data/json/items/ammo/shotpaper.json           |  2 +-   data/json/items/generic/casing.json           |  8 +--   data/json/items/handloaded_bullets.json       |  8 ++-   data/json/items/migration.json                | 15 +++++ @@ -326,42 +325,6 @@ index 25d9b16a37b..8ca62a1bfb3 100644     {       "id": "8mm_hvp",       "copy-from": "8mm_caseless", -diff --git a/data/json/items/ammo/flintlock.json b/data/json/items/ammo/flintlock.json -index f7fc54e73da..c51ab370e4a 100644 ---- a/data/json/items/ammo/flintlock.json -+++ b/data/json/items/ammo/flintlock.json -@@ -15,7 +15,8 @@ -     "stack_size": 10, -     "ammo_type": "flintlock", -     "range": 12, --    "damage": { "damage_type": "bullet", "amount": 50 }, -+    "//": "Balanced as FMJ", -+    "damage": { "damage_type": "bullet", "amount": 50, "armor_penetration": 22 }, -     "dispersion": 90, -     "recoil": 1500, -     "loudness": 70, -@@ -37,7 +38,7 @@ -     "stack_size": 10, -     "ammo_type": "flintlock", -     "range": 8, --    "damage": { "damage_type": "bullet", "amount": 45 }, -+    "damage": { "damage_type": "bullet", "amount": 63 }, -     "dispersion": 20, -     "recoil": 1500, -     "loudness": 90, -diff --git a/data/json/items/ammo/shotpaper.json b/data/json/items/ammo/shotpaper.json -index f9915b9cf2e..40ec4081298 100644 ---- a/data/json/items/ammo/shotpaper.json -+++ b/data/json/items/ammo/shotpaper.json -@@ -44,7 +44,7 @@ -     "type": "AMMO", -     "name": { "str": ".62 paper cartridge" }, -     "description": "A paper cartridge containing a premeasured amount of black powder and a .605 inch lead ball.", --    "relative": { "range": 12, "damage": { "damage_type": "bullet", "armor_penetration": 4 } }, -+    "relative": { "range": 12, "damage": { "damage_type": "bullet", "amount": -8, "armor_penetration": 14 } }, -     "delete": { "effects": [ "SHOT" ] }, -     "dispersion": 100 -   }  diff --git a/data/json/items/generic/casing.json b/data/json/items/generic/casing.json  index 510b4ba9c1f..f486ad3126a 100644  --- a/data/json/items/generic/casing.json diff --git a/revert-18-Simplify-broken-limb-mending-3054.patch b/revert-18-Simplify-broken-limb-mending-3054.patch new file mode 100644 index 0000000..dd3aa52 --- /dev/null +++ b/revert-18-Simplify-broken-limb-mending-3054.patch @@ -0,0 +1,830 @@ +From d8aa6d9696fbce4339edfccf96df85ae438a8fad Mon Sep 17 00:00:00 2001 +From: Coolthulhu <Coolthulhu@gmail.com> +Date: Thu, 21 Sep 2023 15:58:59 +0200 +Subject: [PATCH] Simplify broken limb mending (#3054) + +* Rework broken limbs and mending + +* Redesign mending_modifier: 1.0 is same as splint + +* Update comments + +* Update disabled effect description + +--------- + +Co-authored-by: Olanti <olanti-p@yandex.ru> +--- + data/json/effects.json             |  14 +--- + data/json/mutations/mutations.json |  33 ++++----- + data/json/obsoletion/effects.json  |   4 + + src/bionics.cpp                    |  24 ------ + src/character.cpp                  |  66 +++++++++-------- + src/character.h                    |   6 +- + src/creature.cpp                   |   4 +- + src/iexamine.cpp                   |  15 ++-- + src/iuse_actor.cpp                 |  12 --- + src/mutation.h                     |   6 +- + src/mutation_data.cpp              |   2 +- + src/npc.cpp                        |   3 +- + src/panels.cpp                     |  45 ++++++----- + src/player_hardcoded_effects.cpp   |   7 +- + src/suffer.cpp                     | 115 ----------------------------- + tests/player_helpers.cpp           |   3 + + 16 files changed, 96 insertions(+), 263 deletions(-) + +diff --git a/data/json/effects.json b/data/json/effects.json +index 394bfb1a915..969cafe5046 100644 +--- a/data/json/effects.json ++++ b/data/json/effects.json +@@ -1802,23 +1802,11 @@ +     "max_duration": "1 s", +     "rating": "bad" +   }, +-  { +-    "type": "effect_type", +-    "id": "mending", +-    "name": [ "Started recovery", "Recovering", "Mostly recovered" ], +-    "desc": [ "This damaged limb is slowly regaining its functions." ], +-    "//": "Duration is 10 days, but the actual time taken is probabilistic.", +-    "max_duration": "10 d", +-    "int_dur_factor": "60 h", +-    "max_intensity": 3, +-    "rating": "good", +-    "permanent": true +-  }, +   { +     "type": "effect_type", +     "id": "disabled", +     "name": [ { "ctxt": "physically", "str": "Disabled" } ], +-    "desc": [ "This limb is damaged beyond use and may require a splint to recover." ], ++    "desc": [ "This limb is damaged beyond use and must fully heal to recover.  Using a splint may speed up the process." ], +     "//": "This sounds weird. We need <bp_affected> tag or something", +     "apply_message": "Your limb breaks!", +     "remove_message": "The broken limb has mended.", +diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json +index 1fe217b8559..333a471d30e 100644 +--- a/data/json/mutations/mutations.json ++++ b/data/json/mutations/mutations.json +@@ -155,7 +155,7 @@ +     "category": [ "MEDICAL" ], +     "healing_awake": 0.2, +     "healing_resting": 0.5, +-    "mending_modifier": 2.0 ++    "mending_modifier": 0.5 +   }, +   { +     "type": "mutation", +@@ -722,37 +722,34 @@ +     "id": "SLOWHEALER", +     "name": { "str": "Slow Healer" }, +     "points": -2, +-    "description": "Your wounds heal a little slower than most.  Your HP whilst asleep, as well as your broken limbs, heal at 75% of the regular rate.", ++    "description": "Your wounds heal a little slower than most.  Your HP whilst asleep heals at 75% of the regular rate.", +     "starting_trait": true, +     "types": [ "HEALING" ], +-    "healing_resting": -0.25, +-    "mending_modifier": 0.5 ++    "healing_resting": -0.25 +   }, +   { +     "type": "mutation", +     "id": "SLOWHEALER2", +     "name": { "str": "Poor Healer" }, +     "points": -4, +-    "description": "Your health recovery is severely impaired.  Your HP whilst asleep, as well as your broken limbs, heal at 33% of the regular rate.", ++    "description": "Your health recovery is severely impaired.  Your HP whilst asleep heals at 33% of the regular rate.", +     "starting_trait": true, +     "valid": false, +     "purifiable": false, +     "types": [ "HEALING" ], +-    "healing_resting": -0.66, +-    "mending_modifier": 0.33 ++    "healing_resting": -0.66 +   }, +   { +     "type": "mutation", +     "id": "SLOWHEALER3", +     "name": { "str": "Imperceptive Healer" }, +     "points": -8, +-    "description": "Wounds are incredibly dangerous to you, as they barely heal at all.  Your HP whilst asleep, as well as your broken limbs, heal at 10% of the regular rate.", ++    "description": "Wounds are incredibly dangerous to you, as they barely heal at all.  Your HP whilst asleep heals at 10% of the regular rate.", +     "starting_trait": true, +     "valid": false, +     "purifiable": false, +     "types": [ "HEALING" ], +-    "healing_resting": -0.9, +-    "mending_modifier": 0.1 ++    "healing_resting": -0.9 +   }, +   { +     "type": "mutation", +@@ -1377,34 +1374,34 @@ +     "category": [ "PLANT", "LIZARD" ], +     "healing_awake": 0.66, +     "healing_resting": 0.5, +-    "mending_modifier": 4.0 ++    "mending_modifier": 0.5 +   }, +   { +     "type": "mutation", +     "id": "REGEN", +     "name": { "str": "Regeneration" }, +     "points": 6, +-    "description": "Your flesh regenerates from wounds incredibly quickly.  You heal 150% faster whilst asleep and 200% faster whilst awake.  Your broken limbs also heal 16 times faster than usual.", ++    "description": "Your flesh regenerates from wounds incredibly quickly.  You heal 150% faster whilst asleep and 200% faster whilst awake.  You do not require splints to heal broken limbs.", +     "types": [ "HEALING" ], +     "prereqs": [ "FASTHEALER2" ], +     "category": [ "SLIME", "TROGLOBITE" ], +     "healing_awake": 2.0, +     "healing_resting": 1.5, +-    "mending_modifier": 16.0 ++    "mending_modifier": 1.0 +   }, +   { +     "type": "mutation", +     "id": "REGEN_LIZ", +     "name": { "str": "Reptilian Healing" }, +-    "points": 5, ++    "//": "Not worth a point, barely more than flavor.", ++    "points": 0, +     "valid": false, +     "purifiable": false, +-    "description": "Your broken limbs mend themselves without significant difficulty.  You do not require splints and broken limbs heal 20 times faster than usual.", +-    "cancels": [ "ROT1", "ROT2", "ROT3" ], +-    "prereqs": [ "FASTHEALER2" ], ++    "description": "Your broken limbs mend themselves without significant difficulty.  You do not require splints.", ++    "prereqs": [ "FASTHEALER" ], +     "threshreq": [ "THRESH_LIZARD" ], +     "category": [ "LIZARD" ], +-    "mending_modifier": 20.0 ++    "mending_modifier": 1.0 +   }, +   { +     "type": "mutation", +diff --git a/data/json/obsoletion/effects.json b/data/json/obsoletion/effects.json +index 38c218728cd..bb666566f6b 100644 +--- a/data/json/obsoletion/effects.json ++++ b/data/json/obsoletion/effects.json +@@ -60,5 +60,9 @@ +   { +     "type": "effect_type", +     "id": "took_anticonvulsant_visible" ++  }, ++  { ++    "type": "effect_type", ++    "id": "mending" +   } + ] +diff --git a/src/bionics.cpp b/src/bionics.cpp +index 78827e780d7..bb2b2bd73e7 100644 +--- a/src/bionics.cpp ++++ b/src/bionics.cpp +@@ -101,7 +101,6 @@ static const efftype_id effect_fungus( "fungus" ); + static const efftype_id effect_hallu( "hallu" ); + static const efftype_id effect_heating_bionic( "heating_bionic" ); + static const efftype_id effect_iodine( "iodine" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_meth( "meth" ); + static const efftype_id effect_narcosis( "narcosis" ); + static const efftype_id effect_operating( "operating" ); +@@ -190,7 +189,6 @@ static const trait_id trait_MASOCHIST_MED( "MASOCHIST_MED" ); + 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_REGEN_LIZ( "REGEN_LIZ" ); + static const trait_id trait_THRESH_MEDICAL( "THRESH_MEDICAL" ); +  + static const std::string flag_ALLOWS_NATURAL_ATTACKS( "ALLOWS_NATURAL_ATTACKS" ); +@@ -1675,18 +1673,6 @@ void Character::process_bionic( bionic &bio ) +             } +             if( calendar::once_every( 2_minutes ) ) { +                 std::vector<bodypart_id> damaged_hp_parts; +-                std::vector<effect *> mending_list; +- +-                for( const bodypart_id &bp : get_all_body_parts( true ) ) { +-                    const int hp_cur = get_part_hp_cur( bp ); +-                    if( !is_limb_broken( bp ) && hp_cur < get_part_hp_max( bp ) ) { +-                        damaged_hp_parts.push_back( bp ); +-                    } else if( has_effect( effect_mending, bp.id() ) && +-                               ( has_trait( trait_REGEN_LIZ ) || worn_with_flag( flag_SPLINT, bp ) ) ) { +-                        effect *e = &get_effect( effect_mending, bp->token ); +-                        mending_list.push_back( e ); +-                    } +-                } +                 if( !damaged_hp_parts.empty() ) { +                     // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority. +                     // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor. +@@ -1703,16 +1689,6 @@ void Character::process_bionic( bionic &bio ) +                         mod_stored_kcal( -bio.info().kcal_trigger ); +                     } +                 } +-                if( !mending_list.empty() ) { +-                    for( effect *e : mending_list ) { +-                        if( !can_use_bionic() ) { +-                            return; +-                        } +-                        e->mod_duration( e->get_max_duration() / 100 ); +-                        mod_power_level( -bio.info().power_trigger ); +-                        mod_stored_kcal( -bio.info().kcal_trigger ); +-                    } +-                } +             } +         } +     } else if( bio.id == bio_painkiller ) { +diff --git a/src/character.cpp b/src/character.cpp +index 6cb10461791..761e0785f44 100644 +--- a/src/character.cpp ++++ b/src/character.cpp +@@ -140,6 +140,7 @@ static const efftype_id effect_cough_suppress( "cough_suppress" ); + static const efftype_id effect_crushed( "crushed" ); + static const efftype_id effect_darkness( "darkness" ); + static const efftype_id effect_deaf( "deaf" ); ++static const efftype_id effect_disabled( "disabled" ); + static const efftype_id effect_disinfected( "disinfected" ); + static const efftype_id effect_downed( "downed" ); + static const efftype_id effect_drunk( "drunk" ); +@@ -167,7 +168,6 @@ static const efftype_id effect_lying_down( "lying_down" ); + static const efftype_id effect_melatonin_supplements( "melatonin" ); + static const efftype_id effect_meth( "meth" ); + static const efftype_id effect_masked_scent( "masked_scent" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_narcosis( "narcosis" ); + static const efftype_id effect_nausea( "nausea" ); + static const efftype_id effect_no_sight( "no_sight" ); +@@ -287,7 +287,6 @@ static const trait_id trait_INFRARED( "INFRARED" ); + static const trait_id trait_LEG_TENT_BRACE( "LEG_TENT_BRACE" ); + static const trait_id trait_LIGHT_BONES( "LIGHT_BONES" ); + static const trait_id trait_LIZ_IR( "LIZ_IR" ); +-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" ); + static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" ); + static const trait_id trait_M_IMMUNE( "M_IMMUNE" ); + static const trait_id trait_M_SKIN2( "M_SKIN2" ); +@@ -1257,14 +1256,15 @@ int Character::get_working_leg_count() const +  + bool Character::is_limb_disabled( const bodypart_id &limb ) const + { +-    return get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * .125; ++    return is_limb_broken( limb ) || ++           ( get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * 0.125 ); + } +  + // this is the source of truth on if a limb is broken so all code to determine + // if a limb is broken should point here to make any future changes to breaking easier + bool Character::is_limb_broken( const bodypart_id &limb ) const + { +-    return get_part_hp_cur( limb ) <= 0; ++    return has_effect( effect_disabled, limb.id() ); + } +  + bool Character::can_run() +@@ -4580,8 +4580,17 @@ void Character::regen( int rate_multiplier ) +  +     float rest = rest_quality(); +     float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes ); ++    const float broken_regen_mod = clamp( mutation_value( "mending_modifier" ), 0.25f, 1.0f ); +     if( heal_rate > 0.0f ) { +-        healall( roll_remainder( rate_multiplier * heal_rate ) ); ++        const int base_heal = roll_remainder( rate_multiplier * heal_rate ); ++        const int broken_heal = roll_remainder( base_heal * broken_regen_mod ); ++ ++        for( const bodypart_id &bp : get_all_body_parts() ) { ++            const bool is_broken = is_limb_broken( bp ) && ++                                   !worn_with_flag( flag_SPLINT, bp ); ++            heal( bp, is_broken ? broken_heal : base_heal ); ++            mod_part_healed_total( bp, is_broken ? broken_heal : base_heal ); ++        } +     } else if( heal_rate < 0.0f ) { +         int rot_rate = roll_remainder( rate_multiplier * -heal_rate ); +         // Has to be in loop because some effects depend on rounding +@@ -4595,9 +4604,13 @@ void Character::regen( int rate_multiplier ) +         const bodypart_id &bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id(); +         float healing = healing_rate_medicine( rest, bp ) * to_turns<int>( 5_minutes ); +  +-        int healing_apply = roll_remainder( healing ); ++        const bool is_broken = is_limb_broken( bp ) && ++                               !worn_with_flag( flag_SPLINT, bp ); ++        const int healing_apply = roll_remainder( is_broken ? healing *broken_regen_mod : healing ); ++ +         healed_bp( i, healing_apply ); +         heal( bp, healing_apply ); ++ +         if( damage_bandaged[i] > 0 ) { +             damage_bandaged[i] -= healing_apply; +             if( damage_bandaged[i] <= 0 ) { +@@ -4707,9 +4720,6 @@ void Character::update_body( const time_point &from, const time_point &to ) +         check_needs_extremes(); +         update_needs( five_mins ); +         regen( five_mins ); +-        // Note: mend ticks once per 5 minutes, but wants rate in TURNS, not 5 minute intervals +-        // TODO: change @ref med to take time_duration +-        mend( five_mins * to_turns<int>( 5_minutes ) ); +     } +     if( ticks_between( from, to, 24_hours ) > 0 ) { +         enforce_minimum_healing(); +@@ -5800,15 +5810,11 @@ hp_part Character::body_window( const std::string &menu_header, +         const nc_color all_state_col = limb_color( bp, true, true, true ); +         // Broken means no HP can be restored, it requires surgical attention. +         const bool limb_is_broken = is_limb_broken( bp ); +-        const bool limb_is_mending = limb_is_broken && +-                                     ( worn_with_flag( flag_SPLINT, bp ) || has_trait( trait_REGEN_LIZ ) ); +  +         if( show_all ) { +             e.allowed = true; +         } else if( has_curable_effect ) { +             e.allowed = true; +-        } else if( limb_is_broken ) { +-            e.allowed = false; +         } else if( current_hp < maximal_hp && ( e.bonus != 0 || bandage_power > 0.0f  || +                                                 disinfectant_power > 0.0f ) ) { +             e.allowed = true; +@@ -5837,21 +5843,21 @@ hp_part Character::body_window( const std::string &menu_header, +  +         const auto &aligned_name = std::string( max_bp_name_len - utf8_width( e.name ), ' ' ) + e.name; +         std::string hp_str; +-        if( limb_is_mending ) { +-            desc += colorize( _( "It is broken but has been set and just needs time to heal." ), ++        if( limb_is_broken ) { ++            const nc_color color = worn_with_flag( flag_SPLINT, bp ) || ++                                   ( mutation_value( "mending_modifier" ) >= 1.0f ) ? ++                                   c_blue : ++                                   c_light_red; ++            desc += colorize( _( "It is broken and must heal fully before it becomes functional again." ), +                               c_blue ) + "\n"; +-            const auto &eff = get_effect( effect_mending, bp_token ); +-            const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration(); ++            const int mend_perc = 100 * current_hp / maximal_hp; +  +             if( precise ) { +-                hp_str = colorize( string_format( "=%2d%%=", mend_perc ), c_blue ); ++                hp_str = colorize( string_format( "=%2d%%=", mend_perc ), color ); +             } else { +                 const int num = mend_perc / 20; +-                hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), c_blue ); ++                hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), color ); +             } +-        } else if( limb_is_broken ) { +-            desc += colorize( _( "It is broken.  It needs a splint or surgical attention." ), c_red ) + "\n"; +-            hp_str = "==%=="; +         } else if( precise ) { +             hp_str = string_format( "%d", current_hp ); +         } else { +@@ -8431,11 +8437,6 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, +         put_into_vehicle_or_drop( *this, item_drop_reason::tumbling, { weapon } ); +         i_rem( &weapon ); +     } +-    if( has_effect( effect_mending, part_to_damage->token ) ) { +-        effect &e = get_effect( effect_mending, part_to_damage->token ); +-        float remove_mend = dam / 20.0f; +-        e.mod_duration( -e.get_max_duration() * remove_mend ); +-    } +  +     if( dam > get_painkiller() ) { +         on_hurt( source ); +@@ -8646,10 +8647,13 @@ int Character::reduce_healing_effect( const efftype_id &eff_id, int remove_med, +  + void Character::heal( const bodypart_id &healed, int dam ) + { +-    if( !is_limb_broken( healed ) ) { +-        int effective_heal = std::min( dam, get_part_hp_max( healed ) - get_part_hp_cur( healed ) ); +-        mod_part_hp_cur( healed, effective_heal ); +-        g->events().send<event_type::character_heals_damage>( getID(), effective_heal ); ++    const int max_hp = get_part_hp_max( healed ); ++    const int cur_hp = get_part_hp_cur( healed ); ++    const int effective_heal = std::min( dam, max_hp - cur_hp ); ++    mod_part_hp_cur( healed, effective_heal ); ++    g->events().send<event_type::character_heals_damage>( getID(), effective_heal ); ++    if( cur_hp + dam >= max_hp ) { ++        remove_effect( effect_disabled, healed.id() ); +     } + } +  +diff --git a/src/character.h b/src/character.h +index c3ff9d3f7eb..a84bf824865 100644 +--- a/src/character.h ++++ b/src/character.h +@@ -742,10 +742,8 @@ class Character : public Creature, public visitable<Character> +         int get_working_arm_count() const; +         /** Returns the number of functioning legs */ +         int get_working_leg_count() const; +-        /** Returns true if the limb is disabled(12.5% or less hp)*/ ++        /** Returns true if the limb is disabled (12.5% or less hp, or broken)*/ +         bool is_limb_disabled( const bodypart_id &limb ) const; +-        /** Returns true if the limb is hindered(40% or less hp) */ +-        bool is_limb_hindered( hp_part limb ) const; +         /** Returns true if the limb is broken */ +         bool is_limb_broken( const bodypart_id &limb ) const; +         /** source of truth of whether a Character can run */ +@@ -2063,8 +2061,6 @@ class Character : public Creature, public visitable<Character> +         void suffer(); +         /** Handles mitigation and application of radiation */ +         bool irradiate( float rads, bool bypass = false ); +-        /** Handles the chance for broken limbs to spontaneously heal to 1 HP */ +-        void mend( int rate_multiplier ); +  +         /** Creates an auditory hallucination */ +         void sound_hallu(); +diff --git a/src/creature.cpp b/src/creature.cpp +index 0d69db54329..d1c48950682 100644 +--- a/src/creature.cpp ++++ b/src/creature.cpp +@@ -1652,14 +1652,14 @@ void Creature::mod_part_healed_total( const bodypart_id &id, int mod ) + void Creature::set_all_parts_hp_cur( const int set ) + { +     for( std::pair<const bodypart_str_id, bodypart> &elem : body ) { +-        elem.second.set_hp_cur( set ); ++        set_part_hp_cur( elem.first, set ); +     } + } +  + void Creature::set_all_parts_hp_to_max() + { +     for( std::pair<const bodypart_str_id, bodypart> &elem : body ) { +-        elem.second.set_hp_to_max(); ++        set_part_hp_cur( elem.first, get_part_hp_max( elem.first ) ); +     } + } +  +diff --git a/src/iexamine.cpp b/src/iexamine.cpp +index cb1af8fb5a7..5295e4bf0ca 100644 +--- a/src/iexamine.cpp ++++ b/src/iexamine.cpp +@@ -123,7 +123,6 @@ static const efftype_id effect_bleed( "bleed" ); + static const efftype_id effect_disinfected( "disinfected" ); + static const efftype_id effect_earphones( "earphones" ); + static const efftype_id effect_infected( "infected" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_pblue( "pblue" ); + static const efftype_id effect_pkill2( "pkill2" ); + static const efftype_id effect_sleep( "sleep" ); +@@ -5081,11 +5080,7 @@ void iexamine::autodoc( player &p, const tripoint &examp ) +             for( int i = 0; i < num_hp_parts; i++ ) { +                 const bodypart_id &part = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id(); +                 const bool broken = patient.is_limb_broken( part ); +-                effect &existing_effect = patient.get_effect( effect_mending, part->token ); +-                // Skip part if not broken or already healed 50% +-                if( !broken || ( !existing_effect.is_null() && +-                                 existing_effect.get_duration() > +-                                 existing_effect.get_max_duration() - 5_days - 1_turns ) ) { ++                if( !broken ) { +                     continue; +                 } +                 broken_limbs_count++; +@@ -5116,9 +5111,11 @@ void iexamine::autodoc( player &p, const tripoint &examp ) +                     patient.add_msg_player_or_npc( m_good, _( "The machine rapidly sets and splints your broken %s." ), +                                                    _( "The machine rapidly sets and splints <npcname>'s broken %s." ), +                                                    body_part_name( part ) ); +-                    patient.add_effect( effect_mending, 0_turns, part->token ); +-                    effect &mending_effect = patient.get_effect( effect_mending, part->token ); +-                    mending_effect.set_duration( mending_effect.get_max_duration() - 5_days ); ++                    // TODO: Prevent exploits with hp draining stuff? ++                    int heal_amt = patient.get_part_hp_max( part ) / 2 - patient.get_part_hp_cur( part ); ++                    if( heal_amt > 0 ) { ++                        patient.heal( part, heal_amt ); ++                    } +                 } +             } +             if( broken_limbs_count == 0 ) { +diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp +index a0d6e66b7dc..4a0eb9befdb 100644 +--- a/src/iuse_actor.cpp ++++ b/src/iuse_actor.cpp +@@ -3903,18 +3903,6 @@ static hp_part pick_part_to_heal( +             return healed_part; +         } +  +-        if( patient.is_limb_broken( bp ) ) { +-            if( healed_part == hp_arm_l || healed_part == hp_arm_r ) { +-                add_msg( m_info, _( "That arm is broken.  It needs surgical attention or a splint." ) ); +-            } else if( healed_part == hp_leg_l || healed_part == hp_leg_r ) { +-                add_msg( m_info, _( "That leg is broken.  It needs surgical attention or a splint." ) ); +-            } else { +-                add_msg( m_info, "That body part is bugged.  It needs developer's attention." ); +-            } +- +-            continue; +-        } +- +         if( force || patient.get_part_hp_cur( bp ) < patient.get_part_hp_max( bp ) ) { +             return healed_part; +         } +diff --git a/src/mutation.h b/src/mutation.h +index 8e82983e2d7..8fe226d47b5 100644 +--- a/src/mutation.h ++++ b/src/mutation.h +@@ -115,8 +115,10 @@ struct mutation_branch { +         // Healing per turn +         float healing_awake = 0.0f; +         float healing_resting = 0.0f; +-        // Limb mending bonus +-        float mending_modifier = 1.0f; ++        // Multiplier on regen of broken limbs. ++        // Base regen of broken limbs is 25% and 25% the low cap. ++        // Capped at 1.0, which makes broken limbs regen at same rate as unbroken. ++        float mending_modifier = 0.0f; +         // Bonus HP multiplier. That is, 1.0 doubles hp, -0.5 halves it. +         float hp_modifier = 0.0f; +         // Second HP modifier that stacks with first but is otherwise identical. +diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp +index 9c95b97873e..a070de723d8 100644 +--- a/src/mutation_data.cpp ++++ b/src/mutation_data.cpp +@@ -377,7 +377,7 @@ void mutation_branch::load( const JsonObject &jo, const std::string & ) +     optional( jo, was_loaded, "pain_recovery", pain_recovery, 0.0f ); +     optional( jo, was_loaded, "healing_awake", healing_awake, 0.0f ); +     optional( jo, was_loaded, "healing_resting", healing_resting, 0.0f ); +-    optional( jo, was_loaded, "mending_modifier", mending_modifier, 1.0f ); ++    optional( jo, was_loaded, "mending_modifier", mending_modifier, 0.0f ); +     optional( jo, was_loaded, "hp_modifier", hp_modifier, 0.0f ); +     optional( jo, was_loaded, "hp_modifier_secondary", hp_modifier_secondary, 0.0f ); +     optional( jo, was_loaded, "hp_adjustment", hp_adjustment, 0.0f ); +diff --git a/src/npc.cpp b/src/npc.cpp +index 36b63dd2bb4..9c31869540d 100644 +--- a/src/npc.cpp ++++ b/src/npc.cpp +@@ -84,7 +84,6 @@ static const efftype_id effect_contacts( "contacts" ); + static const efftype_id effect_drunk( "drunk" ); + static const efftype_id effect_feral_killed_recently( "feral_killed_recently" ); + static const efftype_id effect_infection( "infection" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_npc_flee_player( "npc_flee_player" ); + static const efftype_id effect_npc_suspend( "npc_suspend" ); + static const efftype_id effect_pkill_l( "pkill_l" ); +@@ -1073,7 +1072,7 @@ bool npc::wear_if_wanted( const item &it, std::string &reason ) +         for( int i = 0; i < num_hp_parts; i++ ) { +             hp_part hpp = static_cast<hp_part>( i ); +             body_part bp = player::hp_to_bp( hpp ); +-            if( is_limb_broken( convert_bp( bp ) ) && !has_effect( effect_mending, bp ) && ++            if( is_limb_broken( convert_bp( bp ) ) && !worn_with_flag( flag_SPLINT, convert_bp( bp ).id() ) && +                 it.covers( convert_bp( bp ).id() ) ) { +                 reason = _( "Thanks, I'll wear that now." ); +                 return !!wear_item( it, false ); +diff --git a/src/panels.cpp b/src/panels.cpp +index 41983b82ae5..9c8ae1701bc 100644 +--- a/src/panels.cpp ++++ b/src/panels.cpp +@@ -61,7 +61,6 @@ + #include "vpart_position.h" + #include "weather.h" +  +-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" ); + static const trait_id trait_SELFAWARE( "SELFAWARE" ); + static const trait_id trait_THRESH_FELINE( "THRESH_FELINE" ); + static const trait_id trait_THRESH_BIRD( "THRESH_BIRD" ); +@@ -69,7 +68,7 @@ static const trait_id trait_THRESH_URSINE( "THRESH_URSINE" ); +  + static const efftype_id effect_got_checked( "got_checked" ); +  +-static const std::string flag_SPLINT( "SPLINT" ); ++static const flag_str_id flag_SPLINT( "SPLINT" ); +  + // constructor + window_panel::window_panel( std::function<void( avatar &, const catacurses::window & )> +@@ -771,36 +770,36 @@ static void draw_limb_health( avatar &u, const catacurses::window &w, int limb_i +             wprintz( w, color, sym ); +         } +     }; ++ +     const bodypart_id bp = convert_bp( avatar::hp_to_bp( static_cast<hp_part>( limb_index ) ) ).id(); ++    const int hp_cur = u.get_part_hp_cur( bp ); ++    const int hp_max = u.get_part_hp_max( bp ); ++ ++    std::optional<nc_color> color_override; ++ +     if( u.is_limb_broken( bp.id() ) && ( limb_index >= hp_arm_l && +                                          limb_index <= hp_leg_r ) ) { +         //Limb is broken +-        std::string limb = "~~%~~"; +-        nc_color color = c_light_red; +- +-        if( u.worn_with_flag( flag_SPLINT,  bp ) || u.has_trait( trait_REGEN_LIZ ) ) { +-            static const efftype_id effect_mending( "mending" ); +-            const auto &eff = u.get_effect( effect_mending, bp->token ); +-            const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration(); ++        const int mend_perc =  100 * hp_cur / hp_max; ++        bool splinted = u.worn_with_flag( flag_SPLINT.str(), bp ) || ++                        ( u.mutation_value( "mending_modifier" ) >= 1.0f ); ++        nc_color color = splinted ? c_blue : c_dark_gray; +  +-            if( is_self_aware || u.has_effect( effect_got_checked ) ) { +-                limb = string_format( "=%2d%%=", mend_perc ); +-                color = c_blue; +-            } else { +-                const int num = mend_perc / 20; +-                print_symbol_num( w, num, "#", c_blue ); +-                print_symbol_num( w, 5 - num, "=", c_blue ); +-                return; +-            } ++        if( is_self_aware || u.has_effect( effect_got_checked ) ) { ++            color_override = color; ++        } else { ++            const int num = mend_perc / 20; ++            print_symbol_num( w, num, "#", color ); ++            print_symbol_num( w, 5 - num, "=", color ); ++            return; +         } +- +-        wprintz( w, color, limb ); +-        return; +     } +  +-    const int hp_cur = u.get_part_hp_cur( bp ); +-    const int hp_max = u.get_part_hp_max( bp ); ++ +     std::pair<std::string, nc_color> hp = get_hp_bar( hp_cur, hp_max ); ++    if( color_override ) { ++        hp.second = *color_override; ++    } +  +     if( is_self_aware || u.has_effect( effect_got_checked ) ) { +         wprintz( w, hp.second, "%3d  ", hp_cur ); +diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp +index 2f74c64ccf4..88d7f83de8e 100644 +--- a/src/player_hardcoded_effects.cpp ++++ b/src/player_hardcoded_effects.cpp +@@ -73,7 +73,6 @@ static const efftype_id effect_hallu( "hallu" ); + static const efftype_id effect_hot( "hot" ); + static const efftype_id effect_infected( "infected" ); + static const efftype_id effect_lying_down( "lying_down" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_mutating( "mutating" ); + static const efftype_id effect_nausea( "nausea" ); + static const efftype_id effect_narcosis( "narcosis" ); +@@ -1292,12 +1291,8 @@ void Character::hardcoded_effects( effect &it ) +                 } +             } +         } +-    } else if( id == effect_mending ) { +-        if( !is_limb_broken( convert_bp( bp ) ) ) { +-            it.set_duration( 0_turns ); +-        } +     } else if( id == effect_disabled ) { +-        if( !is_limb_broken( convert_bp( bp ) ) ) { ++        if( get_part_hp_cur( convert_bp( bp ) ) >= get_part_hp_max( convert_bp( bp ) ) ) { +             remove_effect( effect_disabled ); +         } +     } else if( id == effect_panacea ) { +diff --git a/src/suffer.cpp b/src/suffer.cpp +index f752944f22b..acc6a8dc50e 100644 +--- a/src/suffer.cpp ++++ b/src/suffer.cpp +@@ -95,7 +95,6 @@ static const efftype_id effect_glowy_led( "glowy_led" ); + static const efftype_id effect_hallu( "hallu" ); + static const efftype_id effect_iodine( "iodine" ); + static const efftype_id effect_masked_scent( "masked_scent" ); +-static const efftype_id effect_mending( "mending" ); + static const efftype_id effect_meth( "meth" ); + static const efftype_id effect_narcosis( "narcosis" ); + static const efftype_id effect_nausea( "nausea" ); +@@ -143,7 +142,6 @@ static const trait_id trait_RADIOACTIVE1( "RADIOACTIVE1" ); + static const trait_id trait_RADIOACTIVE2( "RADIOACTIVE2" ); + static const trait_id trait_RADIOACTIVE3( "RADIOACTIVE3" ); + static const trait_id trait_RADIOGENIC( "RADIOGENIC" ); +-static const trait_id trait_REGEN_LIZ( "REGEN_LIZ" ); + static const trait_id trait_ROOTS3( "ROOTS3" ); + static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" ); + static const trait_id trait_SHARKTEETH( "SHARKTEETH" ); +@@ -174,16 +172,6 @@ static const std::string flag_RAD_RESIST( "RAD_RESIST" ); + static const std::string flag_SPLINT( "SPLINT" ); + static const std::string flag_SUN_GLASSES( "SUN_GLASSES" ); +  +-static float addiction_scaling( float at_min, float at_max, float add_lvl ) +-{ +-    // Not addicted +-    if( add_lvl < MIN_ADDICTION_LEVEL ) { +-        return 1.0f; +-    } +- +-    return lerp( at_min, at_max, ( add_lvl - MIN_ADDICTION_LEVEL ) / MAX_ADDICTION_LEVEL ); +-} +- + void Character::suffer_water_damage( const mutation_branch &mdata ) + { +     for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) { +@@ -1669,109 +1657,6 @@ bool Character::irradiate( float rads, bool bypass ) +     return false; + } +  +-void Character::mend( int rate_multiplier ) +-{ +-    // Wearing splints can slowly mend a broken limb back to 1 hp. +-    bool any_broken = false; +-    for( const bodypart_id &bp : get_all_body_parts() ) { +-        if( is_limb_broken( bp ) ) { +-            any_broken = true; +-            break; +-        } +-    } +- +-    if( !any_broken ) { +-        return; +-    } +- +-    double healing_factor = 1.0; +-    // Studies have shown that alcohol and tobacco use delay fracture healing time +-    // Being under effect is 50% slowdown +-    // Being addicted but not under effect scales from 25% slowdown to 75% slowdown +-    // The improvement from being intoxicated over withdrawal is intended +-    if( has_effect( effect_cig ) ) { +-        healing_factor *= 0.5; +-    } else { +-        healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::CIG ) ); +-    } +- +-    if( has_effect( effect_drunk ) ) { +-        healing_factor *= 0.5; +-    } else { +-        healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::ALCOHOL ) ); +-    } +- +-    if( get_rad() > 0 && !has_trait( trait_RADIOGENIC ) ) { +-        healing_factor *= clamp( ( 1000.0f - get_rad() ) / 1000.0f, 0.0f, 1.0f ); +-    } +- +-    // Bed rest speeds up mending +-    if( has_effect( effect_sleep ) ) { +-        healing_factor *= 4.0; +-    } else if( get_fatigue() > fatigue_levels::dead_tired ) { +-        // but being dead tired does not... +-        healing_factor *= 0.75; +-    } else { +-        // If not dead tired, resting without sleep also helps +-        healing_factor *= 1.0f + rest_quality(); +-    } +- +-    // Being healthy helps. +-    healing_factor *= 1.0f + get_healthy() / 200.0f; +- +-    // Very hungry starts lowering the chance +-    // square rooting the value makes the numbers drop off faster when below 1 +-    healing_factor *= std::sqrt( static_cast<float>( get_stored_kcal() ) / static_cast<float> +-                                 ( max_stored_kcal() ) ); +-    // Similar for thirst - starts at very thirsty, drops to 0 at parched +-    healing_factor *= 1.0f - clamp( 1.0f * ( get_thirst() - thirst_levels::very_thirsty ) / +-                                    +thirst_levels::parched, 0.0f, 1.0f ); +- +-    // Mutagenic healing factor! +-    bool needs_splint = true; +- +-    healing_factor *= mutation_value( "mending_modifier" ); +- +-    if( has_trait( trait_REGEN_LIZ ) ) { +-        needs_splint = false; +-    } +- +-    add_msg( m_debug, "Limb mend healing factor: %.2f", healing_factor ); +-    if( healing_factor <= 0.0f ) { +-        // The section below assumes positive healing rate +-        return; +-    } +- +-    for( const bodypart_id &bp : get_all_body_parts() ) { +-        const bool broken = is_limb_broken( bp ); +-        if( !broken ) { +-            continue; +-        } +- +-        if( needs_splint && !worn_with_flag( flag_SPLINT, bp ) ) { +-            continue; +-        } +- +-        const time_duration dur_inc = 1_turns * roll_remainder( rate_multiplier * healing_factor ); +-        auto &eff = get_effect( effect_mending, bp->token ); +-        if( eff.is_null() ) { +-            add_effect( effect_mending, dur_inc, bp->token ); +-            continue; +-        } +- +-        eff.set_duration( eff.get_duration() + dur_inc ); +- +-        if( eff.get_duration() >= eff.get_max_duration() ) { +-            set_part_hp_cur( bp, 1 ); +-            remove_effect( effect_mending, bp->token ); +-            g->events().send<event_type::broken_bone_mends>( getID(), bp->token ); +-            //~ %s is bodypart +-            add_msg_if_player( m_good, _( "Your %s has started to mend!" ), +-                               body_part_name( bp ) ); +-        } +-    } +-} +- + void Character::sound_hallu() + { +     // Random 'dangerous' sound from a random direction +diff --git a/tests/player_helpers.cpp b/tests/player_helpers.cpp +index fc95f1696d8..307b9a8834f 100644 +--- a/tests/player_helpers.cpp ++++ b/tests/player_helpers.cpp +@@ -98,6 +98,9 @@ void clear_character( player &dummy, bool debug_storage ) +     dummy.set_stamina( dummy.get_stamina_max() ); +     dummy.set_movement_mode( CMM_WALK ); +  ++    // Set HP to max here and also later, for disabled/broken limbs ++    dummy.set_all_parts_hp_to_max(); ++ +     // Make sure we don't carry around weird effects. +     dummy.clear_effects(); // mark effects for removal +     dummy.process_effects(); // actually remove them +--  +2.42.0 +  | 
