Razorgirl's friend painkiller [SPOILERS!]

TL;DR: how do the pkill effects in the json work?

I’m making a mod that provides an exact dosage for CBM installation, since I don’t want to keep accidentally killing my character, and I don’t want to fork the code to remove it, since I understand the idea behind it. Interestingly, the “Sensory dulling” CBM isn’t actually effective in installing other CBMs it seems. That might be an oversight however.

so, looking at bionics.cpp. the logic behind it is as follows: (bottom of the post for the actual code)

pain_cap is what your painkiller level needs to be at to install CBMs. This is 100 by default.

if you don’t feel pain through mutation, proceed to install the CBM.
If you’re pain resistant, reduce by half.
if you’re pain tolerant, reduce by 25%.
There is nothing that INCREASES the pain_cap amount. (this could actually be a trait btw, “wimp” or something). Thus, the amount of pain killers you need to install a CBM needs to be greater than or equal to 100.

Effects.json lists the following for painkillers (listed at bottom of post). The intention is to create a painkiller that will give you the exact dose using the actual chem that would be required for this process but with a description and flavor text that refers what you need. This could also be modified later on if/when Kevin wants to add to the effect.

Proposed item:

 {
        "id" : "Cust_Razorgirl",
        "type" : "COMESTIBLE",
        "comestible_type" : "MED",
        "name" : "Razorgirl's Friend",
        "description" : "An extremely strong narcotic designed by shady human chop shops before the cataclysm. The bottle has a skull and crossbones on it and reads: Take one pill 20 minutes before installing a CBM. Side effects include nausea, anal leakage, bloodshot eyes, addiction, insomnia, murderous rampages, and rarely ego death. Do not take more than 2 in a 24 hour period. Do not drive while on Razorgirl™ until you know how it will affect you.",
        "weight" : 1,
        "volume" : 1,
        "price" : 140,
        "charges" : 2,
        "stack_size" : 10,
        "symbol" : "!",
        "color" : "light_gray",
        "fun" : -30,
        "addiction_type" : "opiate",
        "use_action" : {
            "type" : "consume_drug",
            "activation_message" : "You pop the Razorgirl.",
            "effects" : [
                { "id" : "pkill3", "duration" : 80 },
                { "id" : "pkill2", "duration" : 200 },
                { "id" : "nausea", "duration" : 400 }
            ]
        }
    },

Recipe:

{
  "type" : "recipe",
  "result": "Cust_Razorgirl",
  "category": "CC_CHEM",
  "subcategory": "CSC_CHEM_DRUGS",
  "skill_used": "cooking",
  "difficulty": 5,
  "time": 20000,
  "book_learn": [["textbook_chemistry", 2] , ["adv_chemistry", 2] , [ "recipe_labchem", 2]],
  "qualities":[
    {"id":"CHEM","level":2}
  ], "tools": [
    [ [ "surface_heat", 15, "LIST" ] ]
  ],
  "components": [
 [
      [ "salt_water", 1 ],
      [ "salt", 10 ],
      [ "saline", 5 ]
    ],
    [
      [ "aspirin", 5 ]
    ],
    [
      [ "codeine", 2 ],
    ]
  ]
}

Bionics.cpp:

    const int pk = get_painkiller();
    int pain_cap = 100;
    if( has_trait( trait_id( "PAINRESIST_TROGLO" ) ) ) {
        pain_cap = pain_cap / 2;
    } else if( has_trait( trait_id( "PAINRESIST" ) ) ) {
        pain_cap = pain_cap / 1.5;
    }

    if( !has_trait( trait_id( "NOPAIN" ) ) && !has_trait( trait_id( "CENOBITE" ) ) ) {
        if( pk == 0 ) {
            popup( _( "You need to take painkillers to make installing bionics tolerable." ) );
            return false;
        } else if( pk < pain_cap / 2 ) {
            popup( _( "You need to be a lot more numb to tolerate installing bionics.  Note that painkillers you've already taken might not be fully working yet." ) );
            return false;
        } else if( pk < pain_cap ) {
            popup( _( "You aren't quite numb enough to tolerate installing bionics.  Note that painkillers you've already taken might not be fully working yet." ) );
            return false;
        }
    }

Effects.json:

   {
        "type": "effect_type",
        "id": "pkill1",
        "max_duration": 240,
        "base_mods": {
            "pkill_tick": [7],
            "pkill_min": [1],
            "pkill_max_val": [15]
        }
    },
    {
        "type": "effect_type",
        "id": "pkill2",
        "pkill_addict_reduces": true,
        "base_mods": {
            "pkill_tick": [7],
            "pkill_min": [2]
        }
    },
    {
        "type": "effect_type",
        "id": "pkill3",
        "pkill_addict_reduces": true,
        "base_mods": {
            "pkill_tick": [2],
            "pkill_min": [1]
        }
    },
    {
        "type": "effect_type",
        "id": "pkill_l",
        "pkill_addict_reduces": true,
        "base_mods": {
            "pkill_max_val": [40],
            "pkill_tick": [20],
            "pkill_min": [1]
        }
    },

For pkill1: “pkill_tick”: [7],
“pkill_min”: [1],
“pkill_max_val”: [15]

That means that pkill will increase every 7 ticks for amount of 1 up to amount of 15.

Pkill2: “pkill_tick”: [7],
“pkill_min”: [2]

Pkill will increase every 7 ticks for amount of 2 with no upper limit. Pkill2 is more intense than pkill1 because for, say, 100 ticks you will get for pkill1 100/71 = 14 pkill, and for pkill2 100/72 = 28 pkill.

Pkill 3: “pkill_tick”: [2],
“pkill_min”: [1]

Pkill3 is even more intense, as it increases pkill for amount of 1 every 2 ticks! That means that for 100 ticks it will give 100/2*1 = 50 pkill.

Pkill_l: “pkill_max_val”: [40],
“pkill_tick”: [20],
“pkill_min”: [1]

Pkill_l (‘l’ is for long) will increase pkill for amount of 1 every 20 ticks up to amount of 40. For 100 ticks it will give only 100/20*1 = 5 pkill.

As for your drug, with pkill3 duration 80 and pkill2 duration 200, at the maximum of pkill3 effect it will give 80/21 = 40 plus 80/72 = 22. Altogether is 40+22 = 62. After that pkill from pkill3 will begin to fade, while pkill from pkill2 will still be increasing. Maximum pkill from pkill2 at the end of its duration will be 200/7*2 = 57.

It will require further testing to calculate if overall effect of this drug will be 100 or more at the end of duration 200.