diff --git a/data/json/mutations/mutation_jmath.json b/data/json/mutations/mutation_jmath.json
new file mode 100644
index 0000000000000..c14d82628cb3d
--- /dev/null
+++ b/data/json/mutations/mutation_jmath.json
@@ -0,0 +1,10 @@
+[
+ {
+ "type": "jmath_function",
+ "id": "alpha_stat_bonus",
+ "//": "the smaller your stat, the bigger the bonus, up to 16, plus 2 of the stat above",
+ "//_0": "your current base stat, like `u_val('intelligence_base')`",
+ "num_args": 1,
+ "return": "_0 < 16 ? (10)+(_0/2)-_0 : 2"
+ }
+]
diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json
index afd876054f778..85a37d7b75956 100644
--- a/data/json/mutations/mutations.json
+++ b/data/json/mutations/mutations.json
@@ -5928,7 +5928,7 @@
"prereqs": [ "STR_UP_2" ],
"threshreq": [ "THRESH_ALPHA" ],
"category": [ "ALPHA" ],
- "enchantments": [ { "values": [ { "value": "STRENGTH", "add": 2 } ] } ]
+ "enchantments": [ { "values": [ { "value": "STRENGTH", "add": { "math": [ "alpha_stat_bonus(u_val('strength_base'))" ] } } ] } ]
},
{
"type": "mutation",
@@ -6017,7 +6017,7 @@
"prereqs": [ "DEX_UP_2" ],
"threshreq": [ "THRESH_ALPHA" ],
"category": [ "ALPHA" ],
- "enchantments": [ { "values": [ { "value": "DEXTERITY", "add": 2 } ] } ]
+ "enchantments": [ { "values": [ { "value": "DEXTERITY", "add": { "math": [ "alpha_stat_bonus(u_val('dexterity_base'))" ] } } ] } ]
},
{
"type": "mutation",
@@ -6081,7 +6081,7 @@
"prereqs": [ "INT_UP_2" ],
"threshreq": [ "THRESH_ALPHA" ],
"category": [ "ALPHA" ],
- "enchantments": [ { "values": [ { "value": "INTELLIGENCE", "add": 2 } ] } ]
+ "enchantments": [ { "values": [ { "value": "INTELLIGENCE", "add": { "math": [ "alpha_stat_bonus(u_val('intelligence_base'))" ] } } ] } ]
},
{
"type": "mutation",
@@ -6098,6 +6098,7 @@
"prereqs2": [ "AMORPHOUS" ],
"threshreq": [ "THRESH_SLIME" ],
"category": [ "SLIME" ],
+ "enchantments": [ { "values": [ { "value": "INTELLIGENCE", "multiply": 1 } ] } ],
"armor": [
{
"parts": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth", "eyes" ],
@@ -6164,7 +6165,7 @@
"prereqs": [ "PER_UP_2" ],
"threshreq": [ "THRESH_ALPHA" ],
"category": [ "ALPHA" ],
- "enchantments": [ { "values": [ { "value": "PERCEPTION", "add": 2 } ] } ]
+ "enchantments": [ { "values": [ { "value": "PERCEPTION", "add": { "math": [ "alpha_stat_bonus(u_val('perception_base'))" ] } } ] } ]
},
{
"type": "mutation",
diff --git a/doc/NPCs.md b/doc/NPCs.md
index 90dc6b3f9ee15..7b48bfb1cd9a3 100644
--- a/doc/NPCs.md
+++ b/doc/NPCs.md
@@ -1411,7 +1411,7 @@ These can be read or written to with `val()`.
| `stored_kcal` | ✅ | Stored kcal in the character's body. 55'000 is considered healthy. |
| `stored_kcal_percentage` | ✅ | a value of 100 represents 55'000 kcal, which is considered healthy. |
| `strength`
`dexterity`
`intelligence`
`pereception` | ✅ | Current attributes |
-| `strength_base`
`dexterity_base`
`intelligence_base`
`pereception_base` | ✅ | Base attributes |
+| `strength_base`
`dexterity_base`
`intelligence_base`
`perception_base` | ✅ | Base attributes |
| `strength_bonus`
`dexterity_bonus`
`intelligence_bonus`
`pereception_bonus` | ✅ | Bonus attributes |
| `thirst` | ✅ | Current thirst. |
| `volume` | ❌ | Current volume in mL. Only works for monsters |
diff --git a/src/mutation.cpp b/src/mutation.cpp
index f7c57743b2910..f755bbe5cec97 100644
--- a/src/mutation.cpp
+++ b/src/mutation.cpp
@@ -69,22 +69,17 @@ static const trait_id trait_ARVORE_FOREST_MAPPING( "ARVORE_FOREST_MAPPING" );
static const trait_id trait_BURROW( "BURROW" );
static const trait_id trait_BURROWLARGE( "BURROWLARGE" );
static const trait_id trait_CHAOTIC_BAD( "CHAOTIC_BAD" );
-static const trait_id trait_DEX_ALPHA( "DEX_ALPHA" );
static const trait_id trait_ECHOLOCATION( "ECHOLOCATION" );
static const trait_id trait_GASTROPOD_EXTREMITY2( "GASTROPOD_EXTREMITY2" );
static const trait_id trait_GASTROPOD_EXTREMITY3( "GASTROPOD_EXTREMITY3" );
static const trait_id trait_GLASSJAW( "GLASSJAW" );
-static const trait_id trait_INT_ALPHA( "INT_ALPHA" );
-static const trait_id trait_INT_SLIME( "INT_SLIME" );
static const trait_id trait_LONG_TONGUE2( "LONG_TONGUE2" );
static const trait_id trait_M_BLOOM( "M_BLOOM" );
static const trait_id trait_M_FERTILE( "M_FERTILE" );
static const trait_id trait_M_PROVENANCE( "M_PROVENANCE" );
static const trait_id trait_NAUSEA( "NAUSEA" );
-static const trait_id trait_PER_ALPHA( "PER_ALPHA" );
static const trait_id trait_SLIMESPAWNER( "SLIMESPAWNER" );
static const trait_id trait_SNAIL_TRAIL( "SNAIL_TRAIL" );
-static const trait_id trait_STR_ALPHA( "STR_ALPHA" );
static const trait_id trait_TREE_COMMUNION( "TREE_COMMUNION" );
static const trait_id trait_VOMITOUS( "VOMITOUS" );
static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" );
@@ -464,31 +459,6 @@ void Character::mutation_effect( const trait_id &mut, const bool worn_destroyed_
{
if( mut == trait_GLASSJAW ) {
recalc_hp();
-
- } else if( mut == trait_STR_ALPHA ) {
- if( str_max < 16 ) {
- str_max = 8 + str_max / 2;
- }
- apply_mods( mut, true );
- recalc_hp();
- } else if( mut == trait_DEX_ALPHA ) {
- if( dex_max < 16 ) {
- dex_max = 8 + dex_max / 2;
- }
- apply_mods( mut, true );
- } else if( mut == trait_INT_ALPHA ) {
- if( int_max < 16 ) {
- int_max = 8 + int_max / 2;
- }
- apply_mods( mut, true );
- } else if( mut == trait_INT_SLIME ) {
- int_max *= 2; // Now, can you keep it? :-)
-
- } else if( mut == trait_PER_ALPHA ) {
- if( per_max < 16 ) {
- per_max = 8 + per_max / 2;
- }
- apply_mods( mut, true );
} else {
apply_mods( mut, true );
}
@@ -569,31 +539,6 @@ void Character::mutation_loss_effect( const trait_id &mut )
{
if( mut == trait_GLASSJAW ) {
recalc_hp();
-
- } else if( mut == trait_STR_ALPHA ) {
- apply_mods( mut, false );
- if( str_max < 16 ) {
- str_max = 2 * ( str_max - 8 );
- }
- recalc_hp();
- } else if( mut == trait_DEX_ALPHA ) {
- apply_mods( mut, false );
- if( dex_max < 16 ) {
- dex_max = 2 * ( dex_max - 8 );
- }
- } else if( mut == trait_INT_ALPHA ) {
- apply_mods( mut, false );
- if( int_max < 16 ) {
- int_max = 2 * ( int_max - 8 );
- }
- } else if( mut == trait_INT_SLIME ) {
- int_max /= 2; // In case you have a freak accident with the debug menu ;-)
-
- } else if( mut == trait_PER_ALPHA ) {
- apply_mods( mut, false );
- if( per_max < 16 ) {
- per_max = 2 * ( per_max - 8 );
- }
} else {
apply_mods( mut, false );
}