Skip to content

Getting the name or type of a disease

I need a script that gets the type of disease a player is infected with.

Comments

  • ForSeriousForSerious Member Posts: 519
    This could be fun!
    I'll try and get some time to do this today. Pretty sure the names are in a 2da file. Not sure if each type of disease has an identifier once it's on the player though.
  • QuilistanQuilistan Member Posts: 200
    So what I am trying to do is make them harder to cure. I hate that it is a one stop spell to remove the effects for disease/poison.

    I am wanting to write it so that there is a DC that must be met for a spell or heal check to cure/remove the disease. I will probably be limiting the attempts a cleric can make with a time delay or time stamp. Thus making a PC have to take the disease seriously. This could even open up the door for reagents/remedies to give bonuses to the DC roll.

    I will eventually change the removeeffects spell, but for now I have my script adjusted for running off an item for testing.
    ForSerious wrote: »
    Not sure if each type of disease has an identifier once it's on the player though.
    this is where I am stuck I believe. I can't seem to detect what the player is actually infected with.

    please forgive if some the script is trashy. I am in trial and error mode of figuring this out. I am also learning so any advice on organizing better is always appreciated.
    #include "x2_inc_spellhook"
    // Used to report the name of the current and next Disease.
    string GetDiseaseName(int nCurrentEffect);
    
    void main()
    {
    object oItem = GetItemActivated();
    object oCaster = GetItemActivator();//OBJECT_SELF;
    object oTarget = GetItemActivatedTarget();//GetSpellTargetObject();
    string sPlayerID = GetName(oCaster);
    int nDC;
    
    int nCurrentEffect;
    //effect eDisease;
    
    nCurrentEffect = GetLocalInt(oTarget, "nCurrentEffect");
    //eDisease = EffectDisease(nCurrentEffect);
    //string sDisease = GetDiseaseName(nCurrentEffect);
        // Loop through effects on the creature
        effect eDisease = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eDisease))
        {
            // Check if the effect is a disease
            if (GetEffectType(eDisease) == EFFECT_TYPE_DISEASE)
            {
                // Get the disease name (resref) from the effect tag
                string sDiseaseName = GetEffectTag(eDisease);
                // Display the disease name as floating text
                AssignCommand(oTarget, ActionSpeakString("You are Infected with: " + sDiseaseName));
                break;
            }
            eDisease = GetNextEffect(OBJECT_SELF);
        }
    
    
    SendMessageToPC(oTarget, "Someone is attempting to cure your disease.");
    
    if(GetLocalInt(oTarget, "CureAttempt" + sPlayerID) >= 1) //Check to See if enough time has passed to attempt to heal again
    {
    SendMessageToPC(oCaster, "You will need to wait longer to attempt curing again.");
    return;
    }
    
    //Set Cure Check DC
    if(nCurrentEffect == 4 || 5)//"DISEASE_FILTH_FEVER" || "DISEASE_MINDFIRE")
                                        {nDC = 24;}
    
    if(nCurrentEffect == 8 || 16 || 13)//DISEASE_SHAKES || DISEASE_VERMIN_MADNESS || DISEASE_DREAD_BLISTERS)
                                        {nDC = 26;}
    
    if(nCurrentEffect == 2 || 9)//DISEASE_DEVIL_CHILLS || DISEASE_SLIMY_DOOM)
                                        {nDC = 28;}
    
    if(nCurrentEffect == 12)//DISEASE_ZOMBIE_CREEP)
                                        {nDC = 30;}
    
    if(nCurrentEffect == 0 || 1 || 7)//DISEASE_BLINDING_SICKNESS || DISEASE_CACKLE_FEVER || DISEASE_RED_ACHE)
                                        {nDC = 32;}
    
    if(nCurrentEffect == 14 || 10)//DISEASE_BURROWING_MAGGOTS || DISEASE_RED_SLAAD_EGGS)
                                        {nDC = 34;}
    
    if(nCurrentEffect == 3 || 11)//DISEASE_DEMON_FEVER || DISEASE_GHOUL_ROT)
                                        {nDC = 36;}
    
    if(nCurrentEffect == 6)//DISEASE_MUMMY_ROT)
                                        {nDC = 40;}
    
    if(nCurrentEffect == 15)//DISEASE_SOLDIER_SHAKES)
                                        {nDC = 50;}
    SendMessageToPC(oCaster, IntToString(nDC));
    SendMessageToPC(oTarget, "You are infected with " + IntToString(nCurrentEffect) + GetDiseaseName(nCurrentEffect) + " The DC to heal you is: " + IntToString(nDC));
    //Run Cure Check
    //Get Bonuses for the check
    int nSkill = GetSkillRank(SKILL_HEAL, oCaster)/5; //Get heal skill bonus/5
    if(nSkill <= 1){nSkill = 1;}
    int nLevel = GetHitDice(oCaster)/5; //Get level of caster/5
    if(nLevel <= 1){nLevel = 1;}
    int nAbility = GetAbilityModifier(ABILITY_WISDOM, oCaster); //Get ability bonus
    
    //Do Check
    int nCheck = d20(1) + nSkill + nLevel + nAbility;
    SendMessageToPC(oCaster, "You check roll totals " + IntToString(nCheck) + ".");
    if (!nCheck <= nDC-1)
    {
        SendMessageToPC(oCaster, IntToString(nCheck) + " You fail to cure the disease.");
        SetLocalInt(oTarget, "CureAttempt" + sPlayerID, 1);
        DelayCommand(10.0, DeleteLocalInt(oTarget, "CureAttempt" + sPlayerID));//24 hour delay before the player can attempt to remove disease again
    }return;
    
    //Do the curing
        int nSpellID = GetSpellId();
    
        int nEffect1;
        int nEffect2;
        int nEffect3;
        effect eVis = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
    
        if(nSpellID == SPELL_REMOVE_DISEASE || nSpellID == SPELLABILITY_REMOVE_DISEASE)
        {
            nEffect1 = EFFECT_TYPE_DISEASE;
            nEffect2 = EFFECT_TYPE_ABILITY_DECREASE;
        }
        //Fire cast spell at event for the specified target
        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpellID, FALSE));
        //Remove effects
        RemoveSpecificEffect(nEffect1, oTarget);
        if(nEffect2 != 0)
        {
            RemoveSpecificEffect(nEffect2, oTarget);
        }
        if(nEffect3 != 0)
        {
            RemoveSpecificEffect(nEffect3, oTarget);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
    
    
    }//End Main
    
    
    string GetDiseaseName(int nCurrentEffect)
    {
         string sDisease = "";
    
         switch (nCurrentEffect)
         {
            case 0:
                sDisease = "BLINDING_SICKNESS";
            break;
            case 1:
                sDisease = "CACKLE_FEVER";
            break;
            case 2:
                sDisease = "DEVIL_CHILLS";
            break;
            case 3:
                sDisease = "DEMON_FEVER";
            break;
            case 4:
                sDisease = "FILTH_FEVER";
            break;
            case 5:
                sDisease = "MINDFIRE";
            break;
            case 6:
                sDisease = "MUMMY_ROT";
            break;
            case 7:
                sDisease = "RED_ACHE";
            break;
            case 8:
                sDisease = "SHAKES";
            break;
            case 9:
                sDisease = "SLIMY_DOOM";
            break;
            case 10:
                sDisease = "RED_SLAAD_EGGS";
            break;
            case 11:
                sDisease = "GHOUL_ROT";
            break;
            case 12:
                sDisease = "ZOMBIE_CREEP";
            break;
            case 13:
                sDisease = "DREAD_BLISTERS";
            break;
            case 14:
                sDisease = "BURROW_MAGGOTS";
            break;
            case 15:
                sDisease = "SOLDIER_SHAKES";
            break;
            case 16:
                sDisease = "VERMIN_MADNESS";
            break;
         }
         return sDisease;
    }
    //Might be able to do a Time Stamp for the delay to try again check, to eliminate the counter running.
    
  • ForSeriousForSerious Member Posts: 519
    What does "AssignCommand(oTarget, ActionSpeakString("You are Infected with: " + sDiseaseName));" output?
    I'm seeing GetEffectString(effect eEffect, int nIndex), but no SetEffectString. Hopefully they set the name on one of them.
  • QuilistanQuilistan Member Posts: 200
    ForSerious wrote: »
    What does "AssignCommand(oTarget, ActionSpeakString("You are Infected with: " + sDiseaseName));" output?
    It returns nothing in the text. So you see "You are Infected with: "

    This one:
    SendMessageToPC(oTarget, "You are infected with " + IntToString(nCurrentEffect) + GetDiseaseName(nCurrentEffect) + " The DC to heal you is: " + IntToString(nDC));

    returns:
    "You are infected with 0BLINDING_SICKNESS
    The DC to heal you is: 36"

    It always comes up 0BLINDING_SICKNESS


  • ForSeriousForSerious Member Posts: 519
    edited October 8
    Ah because it's always null or 0.

    Okay, I tried GetEffectString(effect eEffect, int nIndex) with indexes 0 though 11. The lexicon says it only goes to 5. They were all empty. I'm able to get 'supernatural' (16) as the subtype, but that's probably just form how the effect was applied. (OnHit from a weapon.)

    It's looking like you're going to have to overwrite all places where disease effects are applied, and define the tag, or set it as a local variable somewhere. I won't be surprised if you cannot overwrite the item property onhit disease application.
  • ForSeriousForSerious Member Posts: 519
    edited October 8
    Wait! I found it:
    GetEffectInteger(eDisease, 0)
    This returns what you're looking for!

    In fact, lots of what you're trying to do is in the examples on the lexicon.
  • QuilistanQuilistan Member Posts: 200
    "overwrite all places where disease effects are applied"
    I was starting to think that also

    just found this:
    https://neverwintervault.org/project/nwn1/hakpak/poison-disease-type

    looks like ShadowM: added scripts associated with the disease.2da and poison.2da

    I assume to set variables on the PC at the beginning, so they can be retrieved.
    for poisons they are set in the script1 column
    for diseases they are set in the End_Incu_Script



  • ShadowMShadowM Member Posts: 575
    edited October 9
    Quilistan wrote: »
    "overwrite all places where disease effects are applied"
    I was starting to think that also

    just found this:
    https://neverwintervault.org/project/nwn1/hakpak/poison-disease-type

    looks like ShadowM: added scripts associated with the disease.2da and poison.2da

    I assume to set variables on the PC at the beginning, so they can be retrieved.
    for poisons they are set in the script1 column
    for diseases they are set in the End_Incu_Script



    That way old stuff for 1.69 try this if you have nwn ee. Put this in your include script or above you void main.
    Sorry for not being on the forum in ages, I mainly hang out on nwnvault discord.
    //Get the disease row id of the disease on oDiseased from disease.2da
    // -1 no disease
    int GetDiseaseID(object oDiseased);
    int GetDiseaseID(object oDiseased)
    {
    int iD_ID = -1;
    
     effect eEffect = GetFirstEffect(oDiseased);
        //Search for negative effects
        while(GetIsEffectValid(eEffect))
        {
         int iDiseaseID = GetEffectInteger(eEffect,0);
         int nEtype     = GetEffectType(eEffect);
            if (nEtype ==  EFFECT_TYPE_DISEASE)
                 {
                  iD_ID = iDiseaseID;
                 }
              eEffect = GetNextEffect(oDiseased);
         }
    return iD_ID;
    }
    
    
    //Get the disease name on oDiseased from disease.2da
    // "INVALID" on error / no disease
    string GetDiseaseName(object oDiseased);
    string GetDiseaseName(object oDiseased)
    {
    string sD_Name          = "INVALID / No Disease";
    int iD_Row              = GetDiseaseID(oDiseased);
    int iDiseasedNameC      = StringToInt(Get2DAString("disease","Name",iD_Row));
    if(iD_Row != -1)sD_Name = GetStringByStrRef(iDiseasedNameC,GENDER_MALE);
    
    return sD_Name;
    }
    
  • QuilistanQuilistan Member Posts: 200
    awesome ShadowM

    My test item and script seem to be running everything well now.
    #include "x2_inc_spellhook"
    
    //Get the disease row id of the disease on oDiseased from disease.2da
    // -1 no disease
    int GetDiseaseID(object oDiseased);
    int GetDiseaseID(object oDiseased)
    {
    int iD_ID = -1;
    
     effect eEffect = GetFirstEffect(oDiseased);
        //Search for negative effects
        while(GetIsEffectValid(eEffect))
        {
         int iDiseaseID = GetEffectInteger(eEffect,0);
         int nEtype     = GetEffectType(eEffect);
            if (nEtype ==  EFFECT_TYPE_DISEASE)
                 {
                  iD_ID = iDiseaseID;
                 }
              eEffect = GetNextEffect(oDiseased);
         }
    return iD_ID;
    }
    //Get the disease name on oDiseased from disease.2da
    // "INVALID" on error / no disease
    string GetDiseaseName(object oDiseased);
    string GetDiseaseName(object oDiseased)
    {
    string sD_Name          = "No Disease";
    int iD_Row              = GetDiseaseID(oDiseased);
    int iDiseasedNameC      = StringToInt(Get2DAString("disease","Name",iD_Row));
    if(iD_Row != -1)sD_Name = GetStringByStrRef(iDiseasedNameC,GENDER_MALE);
    
    return sD_Name;
    }
    
    void main()
    {
    object oItem = GetItemActivated();
    object oCaster = GetItemActivator();//OBJECT_SELF;
    object oTarget = GetItemActivatedTarget();//GetSpellTargetObject();
    string sPlayerID = GetName(oCaster);
    int nDC;
    int nDiseaseID = GetDiseaseID(oTarget);
    string sDiseaseName = GetDiseaseName(oTarget);
    
        // Loop through effects on the creature
        effect eDisease = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eDisease))
        {
            // Check if the effect is a disease
            if (GetEffectType(eDisease) == EFFECT_TYPE_DISEASE)
            {
                AssignCommand(oTarget, ActionSpeakString("You are Infected with: " + sDiseaseName));
                break;
            }
            eDisease = GetNextEffect(OBJECT_SELF);
        }
    
    
    SendMessageToPC(oTarget, "Someone is attempting to cure your disease.");
    
    if(GetLocalInt(oTarget, "CureAttempt" + sPlayerID) >= 1) //Check to See if enough time has passed to attempt to heal again
    {
    SendMessageToPC(oCaster, "You will need to wait longer to attempt curing again.");
    return;
    }
    
    //Set Cure Check DC
    if(nDiseaseID == 4 || nDiseaseID == 5)//"DISEASE_FILTH_FEVER" || "DISEASE_MINDFIRE")
                                        {nDC = 16;}//24
    
    if(nDiseaseID == 8 || nDiseaseID == 16 || nDiseaseID == 13)//DISEASE_SHAKES || DISEASE_VERMIN_MADNESS || DISEASE_DREAD_BLISTERS)
                                        {nDC = 18;}//26
    
    if(nDiseaseID == 2 || nDiseaseID == 9)//DISEASE_DEVIL_CHILLS || DISEASE_SLIMY_DOOM)
                                        {nDC = 20;}//28
    
    if(nDiseaseID == 12)//DISEASE_ZOMBIE_CREEP)
                                        {nDC = 22;}//30
    
    if(nDiseaseID == 0 || nDiseaseID == 1 || nDiseaseID == 7)//DISEASE_BLINDING_SICKNESS || DISEASE_CACKLE_FEVER || DISEASE_RED_ACHE)
                                        {nDC = 24;}//32
    
    if(nDiseaseID == 14 || nDiseaseID == 10)//DISEASE_BURROWING_MAGGOTS || DISEASE_RED_SLAAD_EGGS)
                                        {nDC = 26;}//34
    
    if(nDiseaseID == 3 || nDiseaseID == 11)//DISEASE_DEMON_FEVER || DISEASE_GHOUL_ROT)
                                        {nDC = 28;}//36
    
    if(nDiseaseID == 6)//DISEASE_MUMMY_ROT)
                                        {nDC = 32;}//40
    
    if(nDiseaseID == 15)//DISEASE_SOLDIER_SHAKES)
                                        {nDC = 42;}//50
    
    SendMessageToPC(oTarget, "You are infected with #" + IntToString(nDiseaseID) + " " + sDiseaseName + " The DC to heal you is: " + IntToString(nDC));
    
    //Run Cure Check
    //Get Bonuses for the check
    int nSkill = GetSkillRank(SKILL_HEAL, oCaster)/5; //Get heal skill bonus/5
    if(nSkill <= 1){nSkill = 1;}
    int nLevel = GetLevelByClass(CLASS_TYPE_CLERIC) + GetLevelByClass(CLASS_TYPE_DRUID) + GetLevelByClass(CLASS_TYPE_RANGER) + GetLevelByClass(CLASS_TYPE_PALADIN) + GetLevelByClass(CLASS_TYPE_BARD);//GetHitDice(oCaster)/5; Get level of caster/5 //Cleric, Druid, Ranger, Bard might make Bards worse with disease and better with poison?
    int nLevelMod = nLevel/5;
    if(nLevelMod <= 1){nLevelMod = 1;}
    int nAbility = GetAbilityModifier(ABILITY_WISDOM, oCaster); //Get ability bonus
    
    //Do Check
    int nRoll = d20(1);
    int nBonus = nSkill + nLevelMod + nAbility;
    int nCheck = nRoll + nBonus;
    SendMessageToPC(oCaster, "You roll " + IntToString(nRoll) + " and have " + IntToString(nBonus) + " bonus = " + IntToString(nCheck) + ".");
    
    if (nCheck <= nDC-1)
    {
        SendMessageToPC(oCaster, "You fail to cure the disease.");
        SetLocalInt(oTarget, "CureAttempt" + sPlayerID, 1);
        DelayCommand(6.0, DeleteLocalInt(oTarget, "CureAttempt" + sPlayerID));//24 hour delay before the player can attempt to remove disease again
        return;
    }
    
        //Do the curing
        int nSpellID = GetSpellId();
    
        int nEffect1;
        int nEffect2;
        int nEffect3;
        effect eVis = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
    
        //if(nSpellID == SPELL_REMOVE_DISEASE || nSpellID == SPELLABILITY_REMOVE_DISEASE)
        //{
            nEffect1 = EFFECT_TYPE_DISEASE;
            nEffect2 = EFFECT_TYPE_ABILITY_DECREASE;
        //}
        //Fire cast spell at event for the specified target
        SignalEvent(oTarget, EventSpellCastAt(oCaster, nSpellID, FALSE));
        //Remove effects
        RemoveSpecificEffect(nEffect1, oTarget);
        if(nEffect2 != 0)
        {
            RemoveSpecificEffect(nEffect2, oTarget);
        }
        if(nEffect3 != 0)
        {
            RemoveSpecificEffect(nEffect3, oTarget);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
    }
    

    Now I just need to go through the pain/joy of thinking through the system well

    Thank you everyone for the help.
  • ShadowMShadowM Member Posts: 575
    edited October 9
    Here DC one. You basically can grab any info from disease.2da (I have poison versions too.) These are with standard nwn ee poison and disease. In my base module I made my own poison/disease effect system that more flexible and more like D&D rules.
    //Get the disease DC of the disease on oDiseased from disease.2da
    // -1 on error.
    int GetDiseaseDC(object oDiseased);
    int GetDiseaseDC(object oDiseased)
    {
    int iD_DC        = -1;
    int iD_Row       = GetDiseaseID(oDiseased);
    string sDiseasedDC = Get2DAString("disease","First_Save",iD_Row);
    int iDiseasedDC    = StringToInt(sDiseasedDC);
    if(iDiseasedDC >= 1)iD_DC = iDiseasedDC;
    
    return iD_DC;
    }
    
  • QuilistanQuilistan Member Posts: 200
    I haven't dug in to the 3 or 3.5 rules for disease and poison yet. I just don't like that the cure spells are a one stop shop to fix the players situation so easily and immediately. Spam try to heal until you roll a 20 with heal skill, or just cast the spell (to easy and the effect is really just a nuisance that needs a scroll or spell slot to handle).

    I am going to put a timer or limit on how often a single player/character can attempt to cure a player. I put the DCs in just incase I want to make them harder to get rid of. I feel like if they are more difficult to remove, they are more of a threat and also more opportunity for a quest or role play. Wait it out, or search for a cure, or search for a NPC that specializes in a specific disease become a possibility.

    Still figuring it out in my head atm.

    Thank you for helping!
Sign In or Register to comment.