Skip to content

[Tool] QDMULTI: A Library for Multiclass Kits

123457

Comments

  •  TheArtisan TheArtisan Member Posts: 3,277
    @Henou

    Multi-class kits don't work like that.

    A multi-class kit is one kit. It's applied to a multi-class the same way a regular kit is applied to a single-class. You need to merge the two class ability .2da files together and use the Cleric/Mage's class number (14 CLERIC_MAGE) and add in the K_CM_* for it to show up under the Cleric/Mage class.
  • HenouHenou Member Posts: 3
    @AionZ

    Thank you so much for your help :) , I've been stuck on this for weeks.

    Being unstuck here only means I can finally...be stuck there :| , on the CLAB file.
    I do have another question if you have time for it. How must I merge my two clab files? I mean, if merge every ap_*** and ga_*** on the same file, how does the engine make the difference between what must be obtain on the cleric level up and on the mage one? Or do I still keep two separated files with one being used in the ADD_KIT function, and the other one in the qd_multiclass?

    Again, thank you for your time, you're really of a great help.
  •  TheArtisan TheArtisan Member Posts: 3,277
    how does the engine make the difference between what must be obtain on the cleric level up and on the mage one?
    It can’t. One of the limitations is that you have to pick one class that dictates the levels where you gain your abilities. Merging the 2das is as simple as copy pasting all rows of one CLAB into the other, there’s no limit to the amount of rows.
  • The user and all related content has been deleted.
  • FaydarkFaydark Member Posts: 279
    Following CrevsDaaks tutorial on kit mods from the forums here, I'm working on making an existing kit included with the game multiclass capable using qdmulti. (Basically, adding a fighter kit to FMC class). Is there a way to use that kits clab as my kits clab, or will I have to copy it (and presumably rename it)?

    I've tried just putting the existing clab name as my kits clab name, but Weidu fails to install it then because it can't find the clab (presumably in my mods install data). I've had a read of the Weidu docs, but nothing obvious is jumping out at me, so I thought I'd ask more experienced modders.

    Thanks.
  • AquadrizztAquadrizzt Member Posts: 1,069
    edited July 2019
    @AionZ, any bonuses in the provided kitclab will be granted on the level-up of the "base class" parameter. If you have a Cleric/Mage kit where you want bonuses on Cleric level-up, use "P" (for Priest). If you have bonuses that you want tied to Mage progression, use "M".

    If you want separate bonuses granted to two different classes (also relevant to @Henou), create two different clab files, with each one containing the associated kit bonuses for a one class' progression, and then call the QD_MULTI function twice, as shown in the code snippet below.
    LAF qd_multiclass
      STR_VAR 
          kit_name = ~MYKIT~  
          kit_clab = ~MYKITPRIEST~ 
          base_class = ~P~
    END 
    
    LAF qd_multiclass
      STR_VAR 
          kit_name = ~MYKIT~
          kit_clab = ~MYKITMAGE~ 
          base_class = ~M~ 
    END
    

    @Faydark, if you want to add an existing (either vanilla or modded) kit to a multiclass, you should just be able to call the QD_MULTI function and supply the CLAB file of the existing kit.

    I think the issue you're running into is that vanilla kits CLAB files are not considered to "exist" outside of the game data, so WeiDu sometimes has difficulty identifying them. For the CLAB file you provide to the ADD_KIT function, it doesn't matter what you give as long as the file exists in your mod structure (or the override directory). I package a BLANKCLAB.2da with my multiclass mods for this purpose, but any .2da file should be fine if I recall correctly.

    Basically, you can't pass a vanilla kit clab (e.g. CLABFI01.2da) to ADD_KIT, because it checks for real files, not game-packaged files, if that makes sense.



  • HenouHenou Member Posts: 3
    @Aquadrizzt @AionZ @subtledoctor , thank you very much for your answers, they have been quite insightful :-). It's even a great news for my project to know that using two clabfiles is possible.

    However, I encounter two problems :
    On one side, even though I'm using your method, the clabfile corresponding to the cleric kit is not being use on level up.
    And on the other hand, quite strangely, the installation can't even proceed if I use the cleric clabfile in ADD_KIT.

    Here's the first code, the installation does work. However, there is no impact upon levelling up with cleric class

    BEGIN ~MAGI~
    INCLUDE ~Elminster/lib/fl#add_kit_ee.tpa~
    INCLUDE ~Elminster/lib/qd_multiclass.tpa~


    ADD_KIT ~MAGI~

    //ajouté à la fin de CLASWEAP.2da

    ~MAGI 0 0 1 1 0 1 0 0~

    //ajouté en tant que colonne à la fin de WEAPPROF.2da

    ~MAGI 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0~

    //ajouté à la fin de ABCLASRQ.2da

    ~MAGI 0 0 0 9 9 0~

    //ajouté à la fin de ABCLSMOD.2da

    ~MAGI 0 0 0 0 0 0~

    //ajouté à la fin de ABDCDSRQ.2da

    ~MAGI 0 0 0 0 0 0~

    //ajouté à la fin de ABDCSCRQ.2da

    ~MAGI 0 0 0 0 0 0 ~

    //ajouté à la fin de ALIGNMNT.2da

    ~MAGI 1 1 1 1 1 1 1 1 1~

    //ajouté à la fin de DUALCLASS.2da

    ~MAGI 0 0 0 0 0 0~

    // chemin d'accès vers votre fichier 2da de type CLAB
    // FICHIER TEST-COPIE DE CLABF02 (berserker)
    // FICHIER A CREER
    // REFERENCE A MODIFIER

    ~Elminster/Chosen/COM.2da~

    // races et classes de PJ autorisées à utiliser ce kit, provenant de KITTABLE.2da

    ~K_CM_D K_CM_E K_CM_G K_CM_H K_CM_HE K_CM_HL K_CM_HO~

    // indicateurs d'utilisabilité, ajouté à la fin de la nouvelle ligne dans KITLIST.2da
    // 0x00004000 fait correspondre les flags du kit à ceux de sa classe mère, le chiffre suivant indique la classe mère : 1 mage, 2 guerrier, 3 clerc, 4 voleur, 5 barde, 6 paladin, 11 druide, 12 rôdeur

    ~0x00004000 14~

    // Table de CHN à utiliser. Voir LUABBR.2da
    // Pas de CHN pour le Clerc puisque sa progression est arrêtée au niveau 10

    ~Cl0~

    // Liste de l'équipement du PJ créé dans ToB. Ajouté en tant que colonne à 25STWEAP.2da
    // NONE CAUSE NO REASON TO BEGIN DIRECTLY IN TOB
    // 20 * si bug

    ~* * * * * * * * * * * * * * * * * * * *~

    // Nom du kit en lettres minuscules et mixtes, et description du kit, ajoutés à KITLIST.2da
    // DESCRIPTION A REDIGER DANS LA TROISIEME LIGNE

    SAY ~magister~
    SAY ~Magister~
    SAY ~MAGISTER~

    LAF fl#add_kit_ee
    STR_VAR
    kit_name = ~MAGI~
    END

    LAF qd_multiclass
    STR_VAR
    kit_name = ~MAGI~
    kit_clab = ~COM~
    base_class = ~M~
    END

    LAF qd_multiclass
    STR_VAR
    kit_name = ~MAGI~
    kit_clab = ~FOM~
    base_class = ~P~
    END

    Here's the second code that doesn't work on installation

    BEGIN ~MAGI~
    INCLUDE ~Elminster/lib/fl#add_kit_ee.tpa~
    INCLUDE ~Elminster/lib/qd_multiclass.tpa~


    ADD_KIT ~MAGI~

    //ajouté à la fin de CLASWEAP.2da

    ~MAGI 0 0 1 1 0 1 0 0~

    //ajouté en tant que colonne à la fin de WEAPPROF.2da

    ~MAGI 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0~

    //ajouté à la fin de ABCLASRQ.2da

    ~MAGI 0 0 0 9 9 0~

    //ajouté à la fin de ABCLSMOD.2da

    ~MAGI 0 0 0 0 0 0~

    //ajouté à la fin de ABDCDSRQ.2da

    ~MAGI 0 0 0 0 0 0~

    //ajouté à la fin de ABDCSCRQ.2da

    ~MAGI 0 0 0 0 0 0 ~

    //ajouté à la fin de ALIGNMNT.2da

    ~MAGI 1 1 1 1 1 1 1 1 1~

    //ajouté à la fin de DUALCLASS.2da

    ~MAGI 0 0 0 0 0 0~

    // chemin d'accès vers votre fichier 2da de type CLAB
    // FICHIER TEST-COPIE DE CLABF02 (berserker)
    // FICHIER A CREER
    // REFERENCE A MODIFIER

    ~Elminster/Chosen/FOM.2da~

    // races et classes de PJ autorisées à utiliser ce kit, provenant de KITTABLE.2da

    ~K_CM_D K_CM_E K_CM_G K_CM_H K_CM_HE K_CM_HL K_CM_HO~

    // indicateurs d'utilisabilité, ajouté à la fin de la nouvelle ligne dans KITLIST.2da
    // 0x00004000 fait correspondre les flags du kit à ceux de sa classe mère, le chiffre suivant indique la classe mère : 1 mage, 2 guerrier, 3 clerc, 4 voleur, 5 barde, 6 paladin, 11 druide, 12 rôdeur

    ~0x00004000 14~

    // Table de CHN à utiliser. Voir LUABBR.2da
    // Pas de CHN pour le Clerc puisque sa progression est arrêtée au niveau 10

    ~Cl0~

    // Liste de l'équipement du PJ créé dans ToB. Ajouté en tant que colonne à 25STWEAP.2da
    // NONE CAUSE NO REASON TO BEGIN DIRECTLY IN TOB
    // 20 * si bug

    ~* * * * * * * * * * * * * * * * * * * *~

    // Nom du kit en lettres minuscules et mixtes, et description du kit, ajoutés à KITLIST.2da
    // DESCRIPTION A REDIGER DANS LA TROISIEME LIGNE

    SAY ~magister~
    SAY ~Magister~
    SAY ~MAGISTER~

    LAF fl#add_kit_ee
    STR_VAR
    kit_name = ~MAGI~
    END

    LAF qd_multiclass
    STR_VAR
    kit_name = ~MAGI~
    kit_clab = ~COM~
    base_class = ~M~
    END

    LAF qd_multiclass
    STR_VAR
    kit_name = ~MAGI~
    kit_clab = ~FOM~
    base_class = ~P~
    END
    It ends up showing this message
    ERROR locating resource for 'COPY'
    Resource [COM.2da] not found in KEY file:
    [./chitin.key]
    Stopping installation because of error.
    Stopping installation because of error.

    So...any idea to definitely unstuck me on this one :# ?
    Once again, thank you all very much for your help until now.
  • AquadrizztAquadrizzt Member Posts: 1,069
    @Henou, you need to copy both of the CLAB files (FOM.2da and COM.2da) into the game files before you run the qd_multi function. The CLAB you pass with the ADD_KIT function is not referenced beyond the installer.

    I could be wrong, but my cursory glance at your code suggests that the reason the first one works but doesn't provide any bonuses on your Cleric is because the FOM.2da is blank (as far as WeiDU is concerned, I think). The reason the second one crashes is because the COM.2da is never added to the game files.

    For code clarity, I'd make a blankclab.2da file and pass it to the ADD_KIT function, then use two COPY commands to add your COM.2da and FOM.2da to the override directory, then run QD_MULTI twice.
  • CryosaurCryosaur Member Posts: 15
    @Aquadrizzt, would you please take the time to update the first post here and on the project page with some more details on why QD_MULTI is needed, and some examples for the various applications? I think I have the answer to all my questions below, but I had to poke around quite a bit to find them. As the search functionality of this forum is exceedingly rudimentary, it would be helpful for others to have them in one place. Here are some recommendations to consider.

    The Background section says, "any kit that would appear in the multiclass menus would not gain any of its unique class bonuses, due to the way that the engine handled multiclass kits." This does not explain that the game (currently) ignores CLABs in KITLIST for multiclass kits. There is also no brief explanation about what QD_MULTI actually does to get around the problem.

    The Usage section might explain that the base_class parameter is not really a base class (for kit of X/Y, picking X instead of Y does not make your kit "more X" or "less Y"). A short paragraph about how multiclass characters gain experience and level up (in contrast to single- and dual-class) would be helpful here.

    The Limitations section makes no mention about why only those six base classes are available. There should probably also be a Ramifications section that details hard-to-discover things the game hardcodes onto various multiclasses, things not applied by UNUSABLE and CLAB.

    For the Applications section, some examples of syntax for kits with two and three CLABs would be helpful, along with the reasons when you should do that (your single kit is composed from one or more already-existing kits with their own CLABs), and when it is unnecessary (your kit is separate from existing kits).

    Thanks for your work. I hope my suggestions are helpful. By the way, I noticed that @subtledoctor has recently forked your project. Will that eventually be pulled back into the "official" release?
  • AquadrizztAquadrizzt Member Posts: 1,069
    edited July 2019
    Sure, when I have a moment I can provide some more explanation. The reason there is so little technical explanation is that the methodology by which this library enables multiclass kits (namely, adding lines to the trueclass CLABs to check for specific kit ids on levelup) is pretty complex even among modern mods and pretty far removed from the interest or understanding of all but the more advanced modders.

    The six classes available for use as base classes are the only classes permitted to multiclass by the engine.

    For ramifications, Mage kits get an extra spell for being a kitted Mages that needs to be handled (I'll add a note about that), and you have to be careful about install orders with mods that add abilities to the six single classes of interest as they will be given to all qd_multi users of the relevant classes as well.

    I originally had various syntaxes written up, I'm not sure what happened to them tbh...
    As for SD's fork, no idea what he has in mind, probably a stability or modularity improvement.
    Post edited by Aquadrizzt on
  • FaydarkFaydark Member Posts: 279
    @Aquadrizzt Following up from my question about using an existing CLAB: yeah, that solution worked, thanks.
  •  TheArtisan TheArtisan Member Posts: 3,277
    Regarding this extremely useful tool - I've been using this modified version for all my multiclass kits with additional lines to prevent abilities from stacking when party members are kicked out and re-recruited, but I did this a while ago and I'm convinced I did things inefficiently, but don't know how I could do it better. Someone take a look at it and see if the same result can be accomplished with more efficient code?
  • AquadrizztAquadrizzt Member Posts: 1,069
    @AionZ, that's a bizarre bug to be running into... I could probably patch the base spells to remove themselves before applying other effects... that should fix it. My WeiDU is a bit rusty unfortunately.
  •  TheArtisan TheArtisan Member Posts: 3,277
    edited July 2019
    The thing is that effects and abilities aren't removed because their parent resources aren't the abilities in the CLAB files, since those (the QD_MCxxx.spl files) aren't the abilities themselves. Because of that, I have to block the QD_MCxxx.spl files from ever being applied more than once using Protection from Spell files.
  • AquadrizztAquadrizzt Member Posts: 1,069
    edited July 2019
    Oh that's a pretty simple solution. Easy to automate too (just a single add spell effect line). When I finish my research deadline crunch, I'll see if I can update it.
  • The user and all related content has been deleted.
  •  TheArtisan TheArtisan Member Posts: 3,277
    @subtledoctor

    So I tested the 0.6 version and unfortunately it still duplicates the spells because the parent resource of the opcode 206 effect is the QD_MCxxx.spl, which means the protection gets removed when the party member is kicked out. The QD_MCxxx.spl has to cast a secondary spell which is not in the CLAB.2da file, which then applies the protection for it to work.
  • The user and all related content has been deleted.
  • The user and all related content has been deleted.
  • argent77argent77 Member Posts: 3,478
    I have fixed a bug that triggered an error (and installation failure) if the kit's CLAB table contained entries with a length of 2 or less characters.

    New version (0.10) can be downloaded from my fork of QDMulti.
  • AbelAbel Member Posts: 785
    edited December 2019
    Thanks to you all, I've been able to implement a Kensai/Conjurer/Assassin. Everything seems to work flawlessly. Here's the code for those interested. I'll probably release a small mod with a few multikit combinations.

    @argent77 I wanted to use your ADD_KIT_EX function, but it doesn't seem like it can add several kits (CLAB) to a multiclass.

    Edit: by the way, I noticed that the backstab var cannot be used for non-Thief kits/classes. Why? The Stalker can backstab and is a Ranger kit.
    Edit 2: I found a way to go around it, using SPCL332 (opcode 263, Backstab bonus). Sadly, there's no equivalent for the sneak attack.
    Edit 3: apparently, only non-Thief multiclass cannot get the sneak attack. Other non-Thief monoclass can if the relevant 2da are appended.

    //KENSAI/CONJURER/ASSASSIN
    ADD_KIT ~BLKCA~
    	~BLKCA 1 1 1 1 1 1 1 1~ //clasweap.2da, not for EE
    	~BLKCA 2 2 0 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 2 0 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0~ //weapprof.2da
    	~BLKCA 9 9 15 9 0 0~ //abclasrq.2da
    	~BLKCA 0 0 0 0 0 0~ //abclsmod.2da
    	~BLKCA 0 0 0 0 0 0~ //abdcdsrq.2da
    	~BLKCA 0 0 0 0 0 0~ //abdcscrq.2da 
    	~BLKCA 0 1 1 1 1 1 0 0 0~ //alignmnt.2da
    	~BLKCA 0 0 0 0 0 0~ //dualclas.2da
    	~abel_multikit_mod/data/BLANKCLAB.2da~ //CLAB
    	~K_FMT_HE~ //Half-Elf only
    	~0x00040084 10~ //ACK FMT
    	~FMT~
    	~* * * * * * * * * * * * * * * * * * * *~
    	SAY ~kensai/conjurer/assassin~
    	SAY ~Kensai/Conjurer/Assassin~
    	SAY ~KENSAI/CONJURER/ASSASSIN: This character can use the abilities of a Kensai, Conjurer, and Assassin, though they cannot use their thieving skills while wearing more than studded leather armor and cannot cast spells while wearing any armor. They may Specialize in, but not Master, any weapon they can use.~
    
    LAF fl#add_kit_ee
    	INT_VAR
    		briefdesc = RESOLVE_STR_REF (~KENSAI/CONJURER/ASSASSIN: This character can use the abilities of a Kensai, Conjurer, and Assassin, though they cannot use their thieving skills while wearing more than studded leather armor and cannot cast spells while wearing any armor. They may Specialize in, but not Master, any weapon they can use.~)
    	STR_VAR
    		kit_name = ~BLKCA~
    		clsrcreq = ~0 0 1 0 0 0 0~
    		//clswpbon = ~1 0 2~
    		//hpclass = ~HPFMT~
    		//numwslot = ~2~
    		clascolr = ~182 118 136 184 72~ //ACAAK
    		//clasiskl = ~0 0 0 10 0 0 0~
    		//clasthac = ~0~
    		//thiefscl = ~100 100 100 100 100 100 100 0~
    		backstab = ~1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7~ //Assassin
    		sneakatt = ~1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14~ //Assassin
    		crippstr = ~0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13~ //Assassin
    		thiefskl = ~40 15~ //Assassin
    		traplimt = 6
    END
    
    COPY_EXISTING ~CLABFI04.2DA~ ~override~ //Kensai
    LAF qd_multiclass
    	STR_VAR
    		kit_name = ~BLKCA~
    		kit_clab = ~CLABFI04~
    		base_class = ~F~
    END
    
    ACTION_IF (FILE_EXISTS_IN_GAME ~CLABMA06.2da~) BEGIN
    	COPY_EXISTING ~CLABMA06.2DA~ ~override~ //Conjurer
    	LAF qd_multiclass
    		STR_VAR
    			kit_name = ~BLKCA~
    			kit_clab = ~CLABMA06~
    			base_class = ~M~
    	END
    END
    
    COPY_EXISTING ~CLABTH02.2DA~ ~override~ //Assassin
    LAF qd_multiclass
    	STR_VAR
    		kit_name = ~BLKCA~
    		kit_clab = ~CLABTH02~
    		base_class = ~T~
    END
    
    Post edited by Abel on
  • The user and all related content has been deleted.
  • AbelAbel Member Posts: 785
    edited December 2019
    Thanks, @subtledoctor for your input on this! That's a nice way of doing it. Which of your mod does that? I'd like to give it a look.

    Also, I edited my previous post with further feedback on the backstab problem. Apparently, among non-Thieves only single classes can get the whole backstab/sneak attack from appending the 2da files. It would probably be a good idea to update the fl#add_kit_ee to allow the relevant variables modification for these classes.

    By the way, did you manage to display the kit name(s) in the character screen left panel? Mine just shows the normal multiclass names.
  • [Deleted User][Deleted User] Posts: 0
    edited December 2019
    The user and all related content has been deleted.
  • AbelAbel Member Posts: 785
    Thanks, that's a lot of lines!
    All right, this is what I see as well. So the kits aren't displayed in that panel.

    I gave a go at the ADD_KIT_EX function but sadly, I experienced various problems.
    1° The kittable variable is not able to identify a tripleclass because of a bad regexp. Line 1370, [A-Z][A-Z]? should be [A-Z][A-Z]?[A-Z]?.
    2° The readme says that clab_path can be the filename of an existing file but it doesn't work.
    3° After adding a kit, the description in the class panel of the character screen doesn't show the custom description.
    So, for now, better stick with the common method.
  • The user and all related content has been deleted.
  • AbelAbel Member Posts: 785
    @subtledoctor Have you noticed that it's not possible to scroll down the kit selection list on character creation? So, if there are too many lines, the last kits cannot be seen or selected...
  • The user and all related content has been deleted.
  • AbelAbel Member Posts: 785
    edited December 2019
    Oh, I see! I was using SoD to debug... Thanks for the information, it's really helpful. I'm almost done with the mod.
    Yes, I was wondering about the patch as well. I only came back recently and thought for sure they would have released one or two by now. I guess they're busy with NWN which I'll probably never play again unless the graphics are overhauled.

    Edit: apparently, assigning a kit to a Mage multiclass always grants one more spell, even if the Mage is not a specialist....
    Post edited by Abel on
Sign In or Register to comment.