Jump to content

quick question: way to detect altered spell tables?


subtledoctor

Recommended Posts

Posted

Background: from my investigations, it seems the least buggy way to apply a penalty to a class/kit's spells/day is to drop the whole spellcasting table by one (from the character level at which the second spell/day of each spell level becomes available) and then give a bonus spell per day of the appropriate levels to every kit *except* the one you want to penalize.

 

Problem: to do that, you have to make assumptions about the spellcasting table. If a player has installed BG2Teaks' altered tables before my mod, I want to respect that choice; but, I need to be able to find out if that has happened.

 

In my mod, when changing the spell tables, I drop a marker file in the override folder, so later components and later mods can identify and handle the change. Does BG2Tweaks do anything like that? (I'm away from my computer for a while, so I can't look at the .tp2 myself.) Any suggestion for the best way to identify the spell table in use?

 

(I'd prefer to stay away from REQUIRE_COMPONENT, since mods change, and indeed it appears that major changes are planned for Tweaks.)

 

Thanks in advance

Posted

Background: from my investigations, it seems the least buggy way to apply a penalty to a class/kit's spells/day is to drop the whole spellcasting table by one (from the character level at which the second spell/day of each spell level becomes available) and then give a bonus spell per day of the appropriate levels to every kit *except* the one you want to penalize.

 

Problem: to do that, you have to make assumptions about the spellcasting table. If a player has installed BG2Teaks' altered tables before my mod, I want to respect that choice; but, I need to be able to find out if that has happened.

 

Can't you just read from the spell tables to determine their contents when your mod is installing? BG2Tweaks might not be the only mod that alters them.

Posted

I don't think so. I can just use REPLACE_TEXTUALLY for each number in sequence to modify the table itself; but my (admittedly amateur) experience has not revealed an easy way to poll the table and return the first row on which the number '2' appears in each column. (Because those rows translate into the columns of CLAB files on which I would need to AP_ various opcode 42 spells.)

 

Incidentally I decided on this procedure after reading about spell penalty problems in the KR forum:

 

Spellslot penalties are impossible to implement without bugs. The game calculates how many spellslots of each level you should have in this order: Class, Kit (CLAB file), Stats, Items, Spells. Let's say you're a Level 14 Morninglord of Lathander with 17 WIS and the Ring of Holiness. So your number of Level 3 spellslots should be 6 (Level 14 Cleric) minus 1 (Kit) plus 1 (17 WIS) plus 1 (Ring), for a total of 7. When you Saved the game, you had a spell memorized in all 7 of those slots, but when you Reload, the game applies the Kit penalty before the WIS and Ring bonuses. The result is that the game drops your available spellslots down to 6, and bumps it back to 7 an instant later: That 7th memorized spell you had is now just an empty spellslot. The worst part is that this happens every time you Reload. As far as I know, nobody can find a way around this.

 

 

This is the closest I think I can come to proving SixofSpades wrong... unfortunately at the moment, it requires pre-knowledge of the spellcasting table. Which is possible only if there is a way to identify whether and how other mods alter the tables.

Posted

You want READ_2DA_ENTRY / READ_2DA_ENTRIES_NOW to fetch data from 2DA files.

 

Here's some code that records the changes in MXSPLPRS.2DA for all columns.

COPY_EXISTING ~mxsplprs.2da~ ~override~
  COUNT_2DA_COLS num_cols
  READ_2DA_ENTRIES_NOW ~r2en_mxsplprs~ (num_cols - 1)
  FOR (col = 1; col < num_cols; col += 1) BEGIN
    READ_2DA_ENTRY_FORMER ~r2en_mxsplprs~ 0 (col - 1) spell_level
    SET previous_spell_count = 0
    FOR (row = 1; row < r2en_mxsplprs; row += 1) BEGIN
      READ_2DA_ENTRY_FORMER ~r2en_mxsplprs~ row 0 class_level
      READ_2DA_ENTRY_FORMER ~r2en_mxsplprs~ row col spell_count
      SET spell_count_delta = (spell_count - previous_spell_count)
      PATCH_IF (spell_count_delta != 0) BEGIN
        SET previous_spell_count = spell_count
      END
      SET $mxsplprs_delta(~%class_level%~ ~%spell_level%~) = spell_count_delta
    END
  END
  BUT_ONLY

Here's some code that prints the saved values.

PRINT ~Spells Added Per Level (MXSPLPRS):~
OUTER_FOR (class_level = 1; class_level <= 50; class_level += 1) BEGIN
  OUTER_TEXT_SPRINT spells_added_per_level ~%class_level%: ~
  ACTION_IF (class_level < 10) BEGIN
    OUTER_TEXT_SPRINT spells_added_per_level ~%class_level%:  ~ // align columns
  END
  OUTER_FOR (spell_level = 1; spell_level <= 7; spell_level += 1) BEGIN
    OUTER_SET spells_added = 0
    ACTION_IF (VARIABLE_IS_SET $mxsplprs_delta(~%class_level%~ ~%spell_level%~)) BEGIN
      OUTER_SET spells_added = $mxsplprs_delta(~%class_level%~ ~%spell_level%~)
    END
    OUTER_TEXT_SPRINT spells_added_per_level ~%spells_added_per_level% %spells_added%~
  END
  PRINT ~%spells_added_per_level%~
END

It gives output like this.

 

 

 

Spells Added Per Level (MXSPLPRS):
1:   1 0 0 0 0 0 0
2:   1 0 0 0 0 0 0
3:   0 1 0 0 0 0 0
4:   1 1 0 0 0 0 0
5:   0 1 1 0 0 0 0
6:   0 0 1 0 0 0 0
7:   0 0 0 1 0 0 0
8:   0 0 1 1 0 0 0
9:   1 1 0 0 1 0 0
10:  0 0 0 1 1 0 0
11:  1 0 1 0 0 1 0
12:  1 1 1 0 0 1 0
13:  0 1 1 1 0 0 0
14:  0 0 0 1 1 0 1
15:  0 0 0 1 1 0 0
16:  1 1 1 0 0 1 0
17:  0 0 0 1 1 0 1
18:  1 1 1 1 1 1 0
19:  1 1 0 0 0 0 0
20:  0 0 1 0 1 1 0
21:  0 0 0 1 1 1 0
22:  0 0 0 0 0 0 1
23:  0 0 0 0 1 1 0
24:  0 0 0 0 0 0 0
25:  0 0 0 0 0 0 0
26:  0 0 0 0 0 1 0
27:  0 0 0 0 0 0 0
28:  0 0 0 0 0 0 1
29:  0 0 0 0 0 0 0
30:  0 0 0 0 0 0 1
31:  0 0 0 0 0 0 0
32:  0 0 0 0 0 0 0
33:  0 0 0 0 0 0 0
34:  0 0 0 0 0 0 1
35:  0 0 0 0 0 0 0
36:  0 0 0 0 0 0 0
37:  0 0 0 0 0 0 0
38:  0 0 0 0 0 0 1
39:  0 0 0 0 0 0 0
40:  0 0 0 0 0 0 0
41:  0 0 0 0 0 0 0
42:  0 0 0 0 0 0 0
43:  0 0 0 0 0 0 0
44:  0 0 0 0 0 0 0
45:  0 0 0 0 0 0 0
46:  0 0 0 0 0 0 0
47:  0 0 0 0 0 0 0
48:  0 0 0 0 0 0 0
49:  0 0 0 0 0 0 0
50:  0 0 0 0 0 0 0

 

Posted

Wow, sweet. (Like I said, I'm an amateur.)

 

That doesn't quite get me what I need but I'll wrestle with it a bit and see if I can't twist it into shape. Thank you (once again!)

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...