Jump to content

functions to allow multiple mods to edit HLA tables


subtledoctor

Recommended Posts

Did you forget that there's no such kit as RANGER ? It's the class name. The kit name is TRUECLASS ...

Nope. In luabbr.2da (which is the file we care about, here) its name is RANGER.

 

The function is meant to

1) match the given %kit_name% to a class/kit in luabbr.2da, and check what its HLA table is;

2) then it compares that with the associative array (which is simply based on the unmodded luabbr2da) to determine whether the HLA table has been changed.

3) If the table has not been changed, it copies the original, gives it a new name (the middle column of the associative array) and a 'd5' prefix for good measure,

4) and then applies the changes to the table as outlined in the add_hla function. (in this cases, INSERT_2DA_ROW.)

 

So it should be creating a new table for the trueclass ranger called "lud5ra0.2da" ... but that is not happening. So it is a problem in step 1, 2, or 3. Somewhere between BEGIN and ACTION_IF VARIABLE_IS_SET.

Link to comment

 

Did you forget that there's no such kit as RANGER ? It's the class name. The kit name is TRUECLASS ...

Nope. In luabbr.2da (which is the file we care about, here) its name is RANGER.

So ? It's still not the kits identifier, just the class variable perhaps, but definitely not anything in the "kit.ids" file, nor either in "kitlist.2da" -file.

Link to comment

The reason it's not doing anything is because when you are looping through luabbr.2da, you don't set l_table to the value of the the matching kit. l_table is being updated every iteration, so it will end up with the value for the last kit in the file.

 

That being said, there are some other things that could cause trouble:

 

- You don't check that orig_table and new_table are different before trying to create your custom prefix version of the table.

- When you create the custom prefix version of the table, you don't update luabbr.2da to refer to it.

 

I would recommend moving all of the "create unique HLA table" code into a separate function. The add_hla function would simply call that to fetch the .2da file associated with a kit and know that it would create a unique one if it didn't yet exist.

Link to comment

Nice! Just had to move

   READ_2DA_ENTRY_FORMER rows row 1 ~l_table~ // read column value

...up inside that PATCH_IF block

 

As for the other issues:

 

- When you create the custom prefix version of the table, you don't update luabbr.2da to refer to it.

 

Yeah - I hadn't gotten to that part yet, since I go stuck when testing the first part failed. That's easy enough.

 

- You don't check that orig_table and new_table are different before trying to create your custom prefix version of the table.

 

Intended. Sometimes they are indeed the same, as you can see in the array. I only need to make them different when there are kits involved (again, as you can see in the array). Now, after that ELSE BEGIN, when dealing with mod kits, I'll have to figure something out because many mod kits just use the default Fi0 or whatever for their HLA table. So probably loop through an add an integer that increases with each loop, or something, just to make sure they get differently-named tables. But for the vanilla classes and kits, the above should be fine and should not get in the way of any other HLA mod.

Link to comment

Okay: it occurred to me, why even bother preserving the original HLA table name? The aciton functions can simply replace a kit's HLA table with a new table named "lu" + "d5_" + "%the row number in luabbr.2da%"... this way they are guaranteed to be unique, and correspond to something you are already working with.

 

Here are examples of how the action functions work:

LAF action_remove_hla STR_VAR kit_name = ~RANGER~ remove_ability = ~GA_SPCL922~ END

LAF action_add_hla STR_VAR kit_name = ~RANGER~ ability = ~GA_SPCL923~ num_allowed = ~20~ END

LAF action_replace_hla STR_VAR kit_name = ~RANGER~ remove_ability = ~GA_SPCL900~ ability = ~GA_heya!~ num_allowed = ~1~ END

That series of commands will affect the trueclass ranger (only), and will remove Tracking, add Summon Deva, and replace Power Attack with a new HLA called "Heya!" (funny story, this is Noober's HLA).

 

Question: when remove_hla is run, should it also remove any HLAs that list it as a pre-requisite? Or should it leave them on the table (and they will simply be unchoosable in-game)?

 

Here is a link to the code and example .tp2:

https://github.com/subtledoctor/Modify_HLAs/releases/tag/0.61

 

And for the curious, here is the code for the 3 action functions:

 

 

DEFINE_ACTION_FUNCTION action_add_hla
  STR_VAR
    kit_name = ~~
    2da_row = ~1~
    ability = ~*~
    icon = ~*~
    strref = ~*~
    min_lev = ~1~
    max_level = ~99~
    num_allowed = ~*~
    prerequisite = ~*~
    excluded_by = ~*~
    alignment_restrict = ~*~
BEGIN
  COPY_EXISTING ~luabbr.2da~ ~override~
    COUNT_2DA_COLS l_cols // amount of columns
    READ_2DA_ENTRIES_NOW l_rows l_cols // read all file into memory  
    FOR (l_row = 1; l_row < l_rows; ++l_row) BEGIN // iterate over rows
      READ_2DA_ENTRY_FORMER l_rows l_row 0 ~l_kit~ // read column value
      PATCH_IF ~%l_kit%~ STRING_EQUAL_CASE ~%kit_name%~ BEGIN
        SET lu_row = %l_row%
        READ_2DA_ENTRY_FORMER l_rows lu_row 1 ~l_table~ // read column value
      END
    END
  BUT_ONLY
  ACTION_IF FILE_EXISTS_IN_GAME ~lu%l_table%.2da~ BEGIN
    COPY_EXISTING ~lu%l_table%.2da~ ~override/lud5_%lu_row%.2da~
        COUNT_2DA_COLS cols // amount of columns
        COUNT_2DA_ROWS cols rows // amount of rows
        READ_2DA_ENTRIES_NOW file cols // read all file into memory  
        first_empty_row = rows // default value to amount of rows in order to skip removal if the table is full
        FOR (i = 0; i < file; ++i) BEGIN // iterate over rows
          SET empty_col_count = 0 // amount of empty columns in the row
          FOR (j = 0; j < cols; ++j) BEGIN // iterate over columns in the row
            READ_2DA_ENTRY_FORMER file i j col_value // read column value
            PATCH_IF "%col_value%" STRING_EQUAL "*" BEGIN // asterisk symbolizes empty column
              empty_col_count += 1
            END
          END
          PATCH_IF "%empty_col_count%" = ("%cols%" - 1) BEGIN // first column in every row is its number, that's why (cols - 1)
            first_empty_row = i // remember the first empty row
            i = file // skip iterating over the rest of the rows
          END
        END  
        INSERT_2DA_ROW ("%first_empty_row%") %cols% ~%2da_row% %ability% %icon% %strref% %min_lev% %max_level% %num_allowed% %prerequisite% %excluded_by% %alignment_restrict%~
        PRETTY_PRINT_2DA
    ACTION_IF NOT (~%l_table%~ STRING_EQUAL_CASE ~d5_%lu_row%~) BEGIN
      COPY_EXISTING ~LUABBR.2DA~ ~override~
        SET_2DA_ENTRY %lu_row% 1 2 ~d5_%lu_row%~
    END
  END
END


DEFINE_ACTION_FUNCTION action_remove_hla
  STR_VAR
    kit_name = ~~
    remove_ability = ~*~
BEGIN
  COPY_EXISTING ~luabbr.2da~ ~override~
    COUNT_2DA_COLS l_cols // amount of columns
    READ_2DA_ENTRIES_NOW l_rows l_cols // read all file into memory  
    FOR (l_row = 1; l_row < l_rows; ++l_row) BEGIN // iterate over rows
      READ_2DA_ENTRY_FORMER l_rows l_row 0 ~l_kit~ // read column value
      PATCH_IF ~%l_kit%~ STRING_EQUAL_CASE ~%kit_name%~ BEGIN
        SET lu_row = %l_row%
        READ_2DA_ENTRY_FORMER l_rows lu_row 1 ~l_table~ // read column value
      END
    END
  BUT_ONLY
  ACTION_IF FILE_EXISTS_IN_GAME ~lu%l_table%.2da~ BEGIN
    COPY_EXISTING ~lu%l_table%.2da~ ~override/lud5_%lu_row%.2da~
      COUNT_2DA_COLS cols // amount of columns
      COUNT_2DA_ROWS cols rows // amount of rows
      READ_2DA_ENTRIES_NOW file cols // read all file into memory
      SET num_deleted = 0
      FOR (i = 0; i < file; ++i) BEGIN // iterate over rows
        READ_2DA_ENTRY_FORMER file i 1 col_value // read column value
        PATCH_IF "%col_value%" STRING_EQUAL_CASE "%remove_ability%" BEGIN // match .spl to be removed
          REMOVE_2DA_ROW (i - num_deleted) cols // kill the row
          SET num_deleted += 1
        END
      END
    ACTION_IF NOT (~%l_table%~ STRING_EQUAL_CASE ~d5_%lu_row%~) BEGIN
      COPY_EXISTING ~LUABBR.2DA~ ~override~
        SET_2DA_ENTRY %lu_row% 1 2 ~d5_%lu_row%~
    END
  END
END

DEFINE_ACTION_FUNCTION action_replace_hla
  STR_VAR
    kit_name = ~~
    remove_ability = ~*~
    2da_row = ~1~
    ability = ~*~
    icon = ~*~
    strref = ~*~
    min_lev = ~1~
    max_level = ~99~
    num_allowed = ~*~
    prerequisite = ~*~
    excluded_by = ~*~
    alignment_restrict = ~*~
BEGIN
  COPY_EXISTING ~luabbr.2da~ ~override~
    COUNT_2DA_COLS l_cols // amount of columns
    READ_2DA_ENTRIES_NOW l_rows l_cols // read all file into memory  
    FOR (l_row = 1; l_row < l_rows; ++l_row) BEGIN // iterate over rows
      READ_2DA_ENTRY_FORMER l_rows l_row 0 ~l_kit~ // read column value
      PATCH_IF ~%l_kit%~ STRING_EQUAL_CASE ~%kit_name%~ BEGIN
        SET lu_row = %l_row%
        READ_2DA_ENTRY_FORMER l_rows lu_row 1 ~l_table~ // read column value
      END
    END
  BUT_ONLY
  ACTION_IF FILE_EXISTS_IN_GAME ~lu%l_table%.2da~ BEGIN
    COPY_EXISTING ~lu%l_table%.2da~ ~override/lud5_%lu_row%.2da~
      COUNT_2DA_COLS cols // amount of columns
      COUNT_2DA_ROWS cols rows // amount of rows
      READ_2DA_ENTRIES_NOW file cols // read all file into memory
      SET num_deleted = 0
      FOR (i = 0; i < file; ++i) BEGIN // iterate over rows
        READ_2DA_ENTRY_FORMER file i 1 col_value // read column value
        PATCH_IF "%col_value%" STRING_EQUAL_CASE "%remove_ability%" BEGIN // match .spl to be removed
          REMOVE_2DA_ROW (i - num_deleted) cols // kill the row
          SET num_deleted += 1
        END
      END
      PATCH_IF NOT num_deleted = 0 BEGIN
        FOR (i = 0; i < file; ++i) BEGIN // iterate over rows
          SET empty_col_count = 0 // amount of empty columns in the row
          FOR (j = 0; j < cols; ++j) BEGIN // iterate over columns in the row
            READ_2DA_ENTRY_FORMER file i j col_value // read column value
            PATCH_IF "%col_value%" STRING_EQUAL "*" BEGIN // asterisk symbolizes empty column
              empty_col_count += 1
            END
          END
          PATCH_IF "%empty_col_count%" = ("%cols%" - 1) BEGIN // first column in every row is its number, that's why (cols - 1)
            first_empty_row = i // remember the first empty row
            i = file // skip iterating over the rest of the rows
          END
        END  
        INSERT_2DA_ROW ("%first_empty_row%" - 1) %cols% ~%2da_row% %ability% %icon% %strref% %min_lev% %max_level% %num_allowed% %prerequisite% %excluded_by% %alignment_restrict%~
      END
      PRETTY_PRINT_2DA
    ACTION_IF NOT (~%l_table%~ STRING_EQUAL_CASE ~d5_%lu_row%~) BEGIN
      COPY_EXISTING ~LUABBR.2DA~ ~override~
        SET_2DA_ENTRY %lu_row% 1 2 ~d5_%lu_row%~
    END
  END
END

 

 

Link to comment

Looks nice. I'll see if I can use these sometime in the future.

 

Question: when remove_hla is run, should it also remove any HLAs that list it as a pre-requisite? Or should it leave them on the table (and they will simply be unchoosable in-game)?

I wouldn't put that feature in. So just leave the other HLAs alone. You could make change_hla_requirement function or something alike instead. :devlook:

That is, if you see use for it. As it ought to be you that uses these at first stage, then others.

Link to comment

it ought to be you that uses these at first stage, then others.

I'm already using the patch functions in the new "Rogue Feats & HLAs" component of Might & Guile. And I'm 3/4 the way through putting them into Refinements... though I think in that case I will do the work over and use these action functions instead.

Link to comment

Archived

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

×
×
  • Create New...