Player Resource Consortium

 

Author Topic: Adding Warlock invocation and eldritch blast level progression  (Read 530 times)

0 Members and 1 Guest are viewing this topic.

March 19, 2017, 09:58:08 PM

I'm trying to add and increase the invocation progression of some classes. For that I basically just adapted http://prc.athasreborn.com/index.php/topic,911.msg6678.html#msg6678 these steps and added

        nLevel +=  GetLevelByClass(CLASS_TYPE_ACOLYTE,              oCaster)
               +   GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_ASMODEUS, oCaster)
               +   GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST,      oCaster)
               +   GetLevelByClass(CLASS_TYPE_MAESTER,              oCaster)
               +  (GetLevelByClass(CLASS_TYPE_OCULAR,               oCaster) + 1) / 2
               +  (GetLevelByClass(CLASS_TYPE_SOUL_EATER,           oCaster) + 1) / 2
               +  (GetLevelByClass(CLASS_TYPE_JUDICATOR,            oCaster) + 1) / 2
               +   GetLevelByClass(CLASS_TYPE_DISC_BAALZEBUL,       oCaster)
               +  (GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_MEPH,     oCaster) + 1) / 2; 

in inv_inv_function.nss, compiled all inv_ files from the new spell book and added the files to the top hak instead of overwriting all files, but I don't get invocations with these classes and it doesn't seem to add to blast lvl, e.g. chain bounces. My test with Acolyte was weird too, I didn't get invocations on each lvl, but it seemed to enable full blast lvl progression and I got to choose multiple invocations when I continued leveling as Warlock.

I would appreciate any help.


March 19, 2017, 11:22:16 PM
Reply #1
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

You have to compile 'prc_amagsys_gain.nss' as well - this should enable new classes to gain invocations. If you switch PRC_DEBUG on it should display info regarding blast level etc. That way you can track files which may require recompilation...


March 19, 2017, 11:25:33 PM
Reply #2

Oh, I see. Thank you very much!

Edit:

It doesn't work with Baalzebul but Acolyte of the Skin gets invocations like a warlock now. The DEBUG doesn't show blast level, it only (from the relevant stats) displays his Invoker Class Level as 11 which is the number of warlock levels, though. Did I have to change anything other than the lines in inv_inv_function? Any 2das I need to change? It should be sufficient to put the compiled scripts into the tophak instead of replacing the files in the default PRC haks, right?

I'll have to go sleep now, but I appreciate the help.
« Last Edit: March 20, 2017, 12:24:27 AM by Mindflayer »


March 20, 2017, 07:42:00 AM
Reply #3
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

Actually there is one more check before adding new invoker levels:

if(GetLocalInt(oCaster, "INV_Caster") == 2)

This is set in prc_inc_function.nss and you have to add information about new classes there as well. No 2da edits are necessary. And yes - putting files in top hak will work.


March 20, 2017, 07:55:46 AM
Reply #4

Oh, is that it? Thanks a lot.

    // Classes an invoker can take
    if(GetLevelByClass(CLASS_TYPE_MAESTER                        , oPC)  ||
       GetLevelByClass(CLASS_TYPE_ACOLYTE                         , oPC)  ||
       GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST           , oPC)  ||
       GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_ASMODEUS, oPC)) ||
       GetLevelByClass(CLASS_TYPE_OCULAR                          , oPC)) ||
       GetLevelByClass(CLASS_TYPE_SOUL_EATER                   , oPC)) ||
       GetLevelByClass(CLASS_TYPE_JUDICATOR                     , oPC)) ||
       GetLevelByClass(CLASS_TYPE_DISC_BAALZEBUL            , oPC)) ||
       GetLevelByClass(CLASS_TYPE_DISC_MEPH                     , oPC))
        {
           //Set arcane or invocation bonus caster levels

           //Arcane caster first class position, take arcane
           if(GetFirstArcaneClassPosition(oPC) == 1)
               SetLocalInt(oPC, "INV_Caster", 1);
           //Invoker first class position. take invoker
           else if(GetClassByPosition(1, oPC) == CLASS_TYPE_WARLOCK || GetClassByPosition(1, oPC) == CLASS_TYPE_DRAGONFIRE_ADEPT)
               SetLocalInt(oPC, "INV_Caster", 2);
           //Non arcane first class position, invoker second.  Take invoker
           else if(GetFirstArcaneClassPosition(oPC) ==0 && (GetClassByPosition(2, oPC) == CLASS_TYPE_WARLOCK || GetClassByPosition(2, oPC) == CLASS_TYPE_DRAGONFIRE_ADEPT))
               SetLocalInt(oPC, "INV_Caster", 2);
           //last cas would be Non-invoker first class position, arcane second position. take arcane.
           else
               SetLocalInt(oPC, "INV_Caster", 1);
       }
}

So this should be the last missing part? I'll try in a moment.


March 20, 2017, 07:58:21 AM
Reply #5
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

I should probably mention that you'll need to compile 'prc_levelup.nss', 'prc_onenter.nss' and 'prc_onleveldown.nss' for it to work :p

(actually all the scripts that use EvalPRCFeats(), but compiling those I mentioned before should do)
« Last Edit: March 20, 2017, 08:00:01 AM by xwarren »


March 20, 2017, 08:02:21 AM
Reply #6

You like toying with rookie scripters , huh? ;D

I'll use Grep to look for EvalPRCFeats() to make sure I get all of them

Yep, getting invocations with a Disciple of Mephistopheles now, and it increases chain bounces. Now I just need to put all the warlock feats into these classes 2das and maybe add a bit of synergy between their own abilities and the blast.

Thanks a lot!
« Last Edit: March 20, 2017, 08:54:20 AM by Mindflayer »


March 20, 2017, 12:47:34 PM
Reply #7
  • Jr. Associate
  • **
  • Posts: 69
  • Karma: +0/-0
    • View Profile

I think I've tried some time ago changing Acolyte of the Skin to give him full caster progression, and back then I just put a "1" instead of a "2" in classes.2da in its place... I believe it worked, but I cannot say for sure.

Xwarren, could you tell me where are the prerequsites for Epic Eldritch Blast? When I gave epic progressions to eldritch disciple and theurge they were not able to take epic eldritch blast despite having invoker level higher than 20 - I also couldnt do it with warlock 16/something 4 with practiced invoker, which leads me to believe it is coded to require 20 levels of warlock instead of 9d6 eldritch blast, which requires invoker level 20, unless you are also an enlightened spirit (continues eldritch blast but does not increase invoker level), which is not added to PRC.
Ideas are bulletproof.


March 20, 2017, 01:20:04 PM
Reply #8

prc_enforce_feat.nss

You can add other class levels to the blast lvl calculation.


Also, I get the feeling that the function GetInvokerLevel doesn't take anything but the main class into account.


    if(nSpecificClass != -1)
    {
        if(!GetIsInvocationClass(nSpecificClass))
            return 0;

        nLevel = GetLevelByClass(nSpecificClass, oInvoker);
        if(DEBUG) DoDebug("Invoker Class Level is: " + IntToString(nLevel));
        if(GetPrimaryInvocationClass(oInvoker) == nSpecificClass)
        {
            //Invoker level is class level + any arcane spellcasting or invoking levels in any PRCs
            nLevel += GetInvocationPRCLevels(oInvoker);
        }
        if(bPracticedInvoker)
            nLevel += PracticedInvoker(oInvoker, nSpecificClass, nLevel);
    }
    else
        nLevel = GetLevelByClass(GetPrimaryInvocationClass(oInvoker), oInvoker);



Based on a simple damage = 1 * GetInvokerLevel ability, where I only get my Warlock level, Acolyte, Mephistopheles and Practiced Invoker aren't taken into account. Am I calling the function wrong?


Nevermind, I had to actually invoke an invocation for the invoker level to register.

Odd: My invoker level keeps changing depending on which invocation/essence I last activated.

Edit:
Well, I can work around that.


Where are daily uses of abilities, eg. Fiendish Glare, defined?
« Last Edit: March 20, 2017, 06:17:48 PM by Mindflayer »


March 20, 2017, 09:03:21 PM
Reply #9
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

There is a 'USESPERDAY' field in feat.2da.


March 20, 2017, 09:26:00 PM
Reply #10
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

I think I've tried some time ago changing Acolyte of the Skin to give him full caster progression, and back then I just put a "1" instead of a "2" in classes.2da in its place... I believe it worked, but I cannot say for sure.
This would only affect spells per day for original NWN classes (wizard, cleric, druid etc) - no caster level increase though. New caster classes added by PRC require some more scripting.

Xwarren, could you tell me where are the prerequsites for Epic Eldritch Blast? When I gave epic progressions to eldritch disciple and theurge they were not able to take epic eldritch blast despite having invoker level higher than 20 - I also couldnt do it with warlock 16/something 4 with practiced invoker, which leads me to believe it is coded to require 20 levels of warlock instead of 9d6 eldritch blast, which requires invoker level 20, unless you are also an enlightened spirit (continues eldritch blast but does not increase invoker level), which is not added to PRC.
I just checked cls_feat*.2da for eldritch disciple and eldritch theurge - there are epic feats in there. I remember that I was working on epic progression for these classes (I am using files from SVN). I will test if it is working.

Edit: I have tested this a with a following character: Warlock 6/Dread Necromancer 4/Eldritch Theurge 10+
- epic Eldritch Theurge progression is enabled - I didn't have to change anything to get 11th level ;)
- You can select Epic Eldritch Blast feats on Eldrith Theurge levels
- The scripts will make sure that you have at least 9d6 blast damage - I couldn't take this as my first epic feat because of that (so I took Practiced Invoker instead) - after that I could select this feat on following levels (with only 6 levels of Warlock).
- a function i prc_enforce_feat.nss checks for blast damage:
Code: [Select]
    if(GetHasFeat(FEAT_EPIC_ELDRITCH_BLAST_I))
    {
        int nInvLvl = GetInvokerLevel(OBJECT_SELF, CLASS_TYPE_WARLOCK);
        int nEldBlast;
        if(nInvLvl < 13)
            nEldBlast = (nInvLvl + 1) / 2;
        else if(nInvLvl < 20)
            nEldBlast = (nInvLvl + 7) / 3;
        else
            nEldBlast = 9 + (nInvLvl - 20) / 2;

        if(nEldBlast < 9)
        {
            FloatingTextStringOnCreature("You must have 9d6 eldritch blast to take Epic Eldritch Blast.", OBJECT_SELF, FALSE);
            return TRUE;
        }
    }
« Last Edit: March 20, 2017, 11:26:18 PM by xwarren »


March 21, 2017, 08:17:47 AM
Reply #11

There is a 'USESPERDAY' field in feat.2da.
Oh, I see, thanks.

**** is unlimited uses, but what exactly does -1 like with stunning fist do? And if I wanted to add a use per day every couple of levels I would need to automatically grant the feat again at those levels or could I use some value to emulate 1/4 class(or character) levels? "Bard Songs" has 44 uses per day, is there some other variable that Determines how the uses are actually gained?


March 21, 2017, 08:29:51 AM
Reply #12
  • Developer
  • *****
  • Posts: 1437
  • Karma: +27/-0
  • Gender: Male
    • View Profile

I'm not really sure what -1 do - in case of stunning fist the uses per day are hard coded into game engine (different value for monks, different for everyone else).

We have a script which sets desired number of uses. It is located in prc_inc_function.nss. You will have to set maximum uses in feat.2da and modify the script. For bard song it looks like this:
Code: [Select]
void BardSong(object oPC)
{
    // This is used to set the number of bardic song uses per day, as bardic PrCs can increase it
    // or other classes can grant it on their own
    if(!GetHasFeat(FEAT_BARD_SONGS, oPC)) return;

    int nTotal = GetLevelByClass(CLASS_TYPE_BARD, oPC);
    nTotal += GetLevelByClass(CLASS_TYPE_DIRGESINGER, oPC);
    nTotal += GetLevelByClass(CLASS_TYPE_VIRTUOSO, oPC);
    nTotal += GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oPC) / 2;

    if(GetHasFeat(FEAT_EXTRA_MUSIC, oPC)) nTotal += 4;

    FeatUsePerDay(oPC, FEAT_BARD_SONGS, -1, nTotal);
}[code]


March 21, 2017, 08:39:46 AM
Reply #13

I see, that's good to know. If I changed bard song uses granted by classes, I would again need to recompile a bunch of scripts, right? The on-rest, on-lvlup/down and the bardsong I can guess, but is there a set of general rules I can apply to any other ability I affect through the includes? Well, aside from spells/powers/invocations needing to be recompiled to calculate caster level properly.

If I want to add a damage modifier to eldritch blast, say I want Disciple of Asmodeus to add 2d6 divine damage if he has dread might, do I only need to change and recompile the includes and the blast scripts?


Edit:
Something rather different: I am trying to buff summons by using a modified version of the AugmentSummonedCreature() function, it works even though I had to rewrite some scripts so they give me a string for the resref to use with it. But the Gate spell behaves oddly. It only works for the PRC custom creatures and the elementals, but the balor, slaadi and vrock are unaffected.

Greater Planar Binding seems to have the same issue. Is there something going on that overrides the PRC spell for creatures from the standard nwn spells? It seems to apply to all the creatures that are in my localized language (except for elementals). But the summon I-IX spells work properly, as far as I have tested.


Or are they not qualifying for this?

    object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oSelf);
    while(GetIsObjectValid(oSummon))
    {
        if(GetResRef(oSummon) == sResRef && !GetLocalInt(oSummon, "Augmented"))

...


UPDATE:

I have managed to fix the summon issue, resrefs were uppercase which messes with ==.
By the way, the Marilith in TRUE GATE is the Thrall of Grazz't Marilith who is stuck at lvl 1.
« Last Edit: March 23, 2017, 06:39:44 PM by Mindflayer »