Skip to content

Modifying Spells Per Day

AmeranthftwAmeranthftw Member Posts: 57
edited October 2014 in General Modding
I've been trying to use the "Bonus wizard spells (42)" opcode to lower the spell progression of a kit I've been making. Essentially I used a single spell file, with different abilities that each have a different minimum level (1, 2, 3, ...). Each of these abilities have effects which lower the amount of spells cast per day for various spell levels as an Instant/Permanent effect.

Originally, I was simply applying these each level, stack them upon one another, but eventually (once I started adding spells per day to undo previous negative spells per day), the spell per day amounts got really crazy. This bug in mind, I tried to have each prospective effect level handle all of the negative spells per day of each level on its own (no more effect stacking), and I used the "Remove effects by resource (321)" opcode to undo previous levels of this effect before applying the new one.

Here is where I have my problem, even if I remove the effects of the ability (we'll call it NEGSPD.spl) before I apply the next one, the next one leaves no effect. Even if I use a second ability to first remove effects of NEGSPD.spl and cast NEGSPD.spl after a short delay (using opcode "Cast spell (146)" with delay/permanent duration of 1) , there is no effect from NEGSPD.spl.


Now I believe I could just use a different spell file for each level, but it's really an inelegant solution, so if anyone could help me figure it out without doing that, I would be really grateful :D

Comments

  • [Deleted User][Deleted User] Posts: 0
    edited October 2014
    The user and all related content has been deleted.
  • The user and all related content has been deleted.
  • AmeranthftwAmeranthftw Member Posts: 57
    edited October 2014
    Interesting, I'll give it a shot, thanks!

    EDIT: Unfortunately this doesn't seem to make a difference, even with the delayed application of the spell.
    Post edited by Ameranthftw on
  • The user and all related content has been deleted.
  • AmeranthftwAmeranthftw Member Posts: 57
    Thank you, I may end up doing that. I'm going to see if I can't first come up with something different instead, I think.
  • AstroBryGuyAstroBryGuy Member Posts: 3,437

    The very short answer is "no."

    1) Using a different spell file for each spell level *would be* the better way to do this. You need to know the spellcasting table, and apply it at the right time. Eg for bards, they get their first level 1 spell at character level 2, so that's when you would apply an opcode 42 effect for 1st level spells.

    Of course if the player has changed the spellcasting table this will not work well. If they apply a mod that lets bards cast spells from 1st level, then with this effect in your CLAB, they would get 1 spell at 1st level and then have it removed at 2nd level. Not good. This is how my mod reduces spells for Skalds, and to make it work I make sure to override the spell table with my own.

    2) BUT, even that doesn't work properly. Opcode 42 is terrible for reducing spells/day. It can cause memorized spells to disappear whenever you save/reload. You know how annoying Dakkon's Zerth Blade is? Something like that.

    SO, the really best solution is to change the spellcasting table itself, to your proposed numbers; and then give spell *increases* via opcode 42, to every kit other than your mod kit.

    Of course adding spells doesn't work when the level gives zero, so you have to apply it only when there are 2 spells for each level. And what about mod kits? They will use the new table, ending up reduced like your kit, unless you can identify them and append spell increases to their CLAB files...!

    Not for the faint of heart, but this is what the upcoming version of my mod has switched to.

    This would make your mod incompatible with any other spellcaster kit mod, wouldn't it?
  • AmeranthftwAmeranthftw Member Posts: 57
    edited October 2014
    If the other kit/mod wanted a different SPD table, then yes there would be adverse effects.

    What I would do is give compatibility with more well-known mods, BG2tweaks' components being the one that I think of. Other mods can be up to the prospective user to handle, or of course request for compatibility.
  • [Deleted User][Deleted User] Posts: 0
    edited October 2014
    The user and all related content has been deleted.
  • AmeranthftwAmeranthftw Member Posts: 57
    edited October 2014
    BG2tweaks has components for every spell table, I'm not certain if they provide specifically a marker file, but surely it must include *some* file specific to it that could be detected.
  • AmeranthftwAmeranthftw Member Posts: 57
    edited October 2014
    A slight update to this: I was tracking spell effects in EEKeeper, and I noticed that each spell effect also stores the resources that it is linked to in its own effects. This explains why "remove effects by resource" was causing even delayed casts of the same resource to do nothing--the resource was removed before it was even cast.

    I did manage to circumvent this--have a spell remove the spell-per-day-modifying spell's effects, as well as cast a second spell, which serves as only a bridge for casting the third spell that modifies spells per day.

    Using this method, it is possible to only use three spell files for modifying whatever amount of character levels, which I think beats the alternative to one spell file per character level.
  • [Deleted User][Deleted User] Posts: 0
    edited October 2014
    The user and all related content has been deleted.
    Post edited by [Deleted User] on
  • AmeranthftwAmeranthftw Member Posts: 57
    That is true, there is not huge differences early on. I think the biggest change is in higher levels where the spell progression is expanded much further than the original tables. Would it not be possible to scan the SPD table for, say, level 50's line, and if it's equivalent to BG2 tweak's, then assume BG2 tweaks.
  • [Deleted User][Deleted User] Posts: 0
    edited October 2014
    The user and all related content has been deleted.
  • kjeronkjeron Member Posts: 2,368
    Read the Spell table, create the file as needed:
    ...
    BEGIN ~NEGSPD~

    OUTER_SET spells_removed = 2 /* number of spells removed per spell level */
    OUTER_SET reverse_removal = 0 /* 0 = remove number of spells, 1 = remove all but number of spells */
    OUTER_SET min_spl = 1 /* minimum number of spells per spell level */
    OUTER_SPRINT spell_table ~MXSPLWIZ~

    COPY ~NEGSPD\NEGSPD.spl~ ~override~
    COPY_EXISTING_REGEXP GLOB ~%spell_table%.2da~ ~override~
    COUNT_2DA_ROWS 10 num_spl
    SET fx_off = 0x72 SET ab_num = 0 SET fx_tot = 0 SET fx_num = 0 min_spl = min_spl - 1
    FOR(cur_row = 0; cur_row < num_spl; ++cur_row) BEGIN fx_num = 0
    FOR(cur_splev = 1; cur_splev < 10; ++cur_splev) BEGIN
    READ_2DA_ENTRY cur_row cur_splev 10 cur_spl
    INNER_ACTION BEGIN COPY_EXISTING ~NEGSPD.spl~ ~override~
    PATCH_IF(cur_splev = 1) BEGIN fx_off = fx_off + 0x28
    WRITE_SHORT 0x6a (fx_off)
    INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1
    WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100
    WRITE_BYTE (0x82 + %ab_num% * 0x28) (cur_row + 1)
    READ_SHORT (0x90 + %ab_num% * 0x28) fx_print
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30) 0x30
    WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 321
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100
    WRITE_EVALUATED_ASCII (%fx_off% + %fx_tot% * 0x30 + 0x14) ~NEGSPD~ #8
    PATCH_IF(cur_row > 0) BEGIN
    READ_SHORT (0x68 + %ab_num% * 0x28) fx_pre READ_SHORT (0x6a + %ab_num% * 0x28) fx_idx
    WRITE_SHORT (0x92 + %ab_num% * 0x28) (fx_idx + fx_pre) END
    WRITE_SHORT 0x68 (ab_num + 1)
    ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + %ab_num% * 0x28) (fx_num)
    END
    FOR(spl_rmv = spells_removed; spl_rmv > 0; --spl_rmv) BEGIN
    PATCH_IF(cur_spl > (spl_rmv + min_spl)) BEGIN
    READ_SHORT (0x90 + (%ab_num% * 0x28)) fx_print
    fx_print = (%fx_off% + %fx_num% * 0x30 + 0x0)
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30
    WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1
    PATCH_IF(reverse_removal = 0) BEGIN WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) (0 - spl_rmv)
    END ELSE BEGIN WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) (spl_rmv - cur_spl) END
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(cur_splev - 1))
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100
    ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    spl_rmv = 0
    END END END END ++ab_num END

    I used his filename, "NEGSPD", as a placeholder, it can be replaced with whatever filename you want, it just needs to be an empty spell file - no abilities or effects. Setting a minimum value will only prevent it from removing all spells from a given level, it will not add spells if there are less.

    The current options, 2 0 1, will remove 2 spell slots per level, but not to less than 1 slot. Equivalent to getting 1 less slot per spell level for a Mage/Sorcerer kit, as they get a hardcoded +1 slot per level)

    Option: 0 1 0, will reduce all spell slots at every level to 0 (not including bonus slots from wisdom or equips).
  • The user and all related content has been deleted.
  • kjeronkjeron Member Posts: 2,368
    edited October 2014
    @subtledoctor, The code was to create the spell Amerantftw was trying to make, based on the current Spell Table, to remove the appropriate amount at each level.

    For what you proposed, to edit the spell table and give each kit a +1 bonus instead ... I can fix that. A bit of a quick mess, currently it will not work correctly if 2 or more spells reach their 2nd slot at the same level. Cleaned it up a little. But otherwise I think this is what you wanted:
    BACKUP ~POSSPLD\backup~ 
    AUTHOR ~none~
    VERSION ~1.0~
    BEGIN ~POSSPLD~

    OUTER_SPRINT spell_table ~MXSPLWIZ~
    OUTER_SET splev1off = 50 OUTER_SET splev2off = 50 OUTER_SET splev3off = 50
    OUTER_SET splev4off = 50 OUTER_SET splev5off = 50 OUTER_SET splev6off = 50
    OUTER_SET splev7off = 50 OUTER_SET splev8off = 50 OUTER_SET splev9off = 50

    COPY ~POSSPLD\POSSPLD.spl~ ~override~
    COPY_EXISTING_REGEXP GLOB ~%spell_table%.2da~ ~override~
    COUNT_2DA_ROWS 10 num_spl
    FOR(cur_row = 1; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 1 10 cur_spl
    pre_row = cur_row - 1
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 1 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev1off = cur_row END END
    READ_2DA_ENTRY cur_row 2 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 2 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev2off = cur_row END END
    READ_2DA_ENTRY cur_row 3 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 3 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev3off = cur_row END END
    READ_2DA_ENTRY cur_row 4 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 4 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev4off = cur_row END END
    READ_2DA_ENTRY cur_row 5 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 5 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev5off = cur_row END END
    READ_2DA_ENTRY cur_row 6 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 6 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev6off = cur_row END END
    READ_2DA_ENTRY cur_row 7 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 7 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev7off = cur_row END END
    READ_2DA_ENTRY cur_row 8 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 8 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev8off = cur_row END END
    READ_2DA_ENTRY cur_row 9 10 cur_spl
    PATCH_IF (cur_spl > 1) BEGIN READ_2DA_ENTRY pre_row 9 10 pre_spl
    PATCH_IF (pre_spl < 2) BEGIN splev9off = cur_row END END
    END
    FOR(cur_row = splev1off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 1 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 1 10 cur_spl END
    FOR(cur_row = splev2off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 2 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 2 10 cur_spl END
    FOR(cur_row = splev3off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 3 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 3 10 cur_spl END
    FOR(cur_row = splev4off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 4 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 4 10 cur_spl END
    FOR(cur_row = splev5off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 5 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 5 10 cur_spl END
    FOR(cur_row = splev6off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 6 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 6 10 cur_spl END
    FOR(cur_row = splev7off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 7 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 7 10 cur_spl END
    FOR(cur_row = splev8off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 8 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 8 10 cur_spl END
    FOR(cur_row = splev9off; cur_row < num_spl; ++cur_row) BEGIN
    READ_2DA_ENTRY cur_row 9 10 cur_spl cur_spl = (cur_spl - 1) SET_2DA_ENTRY cur_row 9 10 cur_spl END

    COPY_EXISTING ~POSSPLD.spl~ ~override~
    SET fx_off = 0x72 SET ab_num = 0 SET fx_tot = 0 SET fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev1off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(0)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    PATCH_IF (splev2off > splev1off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev2off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(1)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(1)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev3off > splev2off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev3off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(2)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(2)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev4off > splev3off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev4off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(3)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(3)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev5off > splev4off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev5off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(4)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(4)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev6off > splev5off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev6off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(5)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(5)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev7off > splev6off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev7off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(6)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(6)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev8off > splev7off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev8off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(7)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(7)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END
    PATCH_IF (splev9off > splev8off) BEGIN fx_num = 0
    fx_off = fx_off + 0x28 WRITE_SHORT 0x6a (fx_off) INSERT_BYTES (0x72 + %ab_num% * 0x28) 0x28
    WRITE_SHORT (0x72 + %ab_num% * 0x28) 1 WRITE_BYTE (0x7e + %ab_num% * 0x28) 5
    WRITE_SHORT (0x80 + %ab_num% * 0x28) 100 WRITE_BYTE (0x82 + %ab_num% * 0x28) (splev9off + 1)
    WRITE_BYTE (0x94 + %ab_num% * 0x28) 1 WRITE_SHORT 0x68 (ab_num + 1)
    WRITE_SHORT (0x90 + %ab_num% * 0x28) 1 WRITE_SHORT (0x92 + %ab_num% * 0x28) fx_tot
    ++ab_num
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(8)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + (%ab_num% * 0x28)) (fx_num)
    END ELSE BEGIN
    INSERT_BYTES (%fx_off% + %fx_tot% * 0x30 + 0x0) 0x30 WRITE_SHORT (%fx_off% + %fx_tot% * 0x30 + 0x0) 42
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x2) 1 WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x4) 1
    WRITE_LONG (%fx_off% + %fx_tot% * 0x30 + 0x8) (2**(8)) WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0xc) 9
    WRITE_BYTE (%fx_off% + %fx_tot% * 0x30 + 0x12) 100 ++fx_num ++fx_tot
    WRITE_SHORT (0x90 + ((%ab_num% - 1) * 0x28)) (fx_num) END

    BTW, that bug only occurs when combined with equipment that add/remove spell slots. Hardcoded kit bonuses and permanent effects combine just fine.
    Post edited by kjeron on
  • The user and all related content has been deleted.
Sign In or Register to comment.