Jump to content

Fix missing entries in 2DA files


argent77

Recommended Posts

I'm trying to add missing entries to a 2DA file, so that every line contains the same number of columns.

Example:

2DA V1.0
*
        1     2     3
NAME1   VAL1  VAL2  VAL3
NAME2   VAL1
NAME3   VAL1  VAL2
NAME4   VAL1  VAL2  VAL3

should be transformed into this:

2DA V1.0
*
        1     2     3
NAME1   VAL1  VAL2  VAL3
NAME2   VAL1  *     *
NAME3   VAL1  VAL2  *
NAME4   VAL1  VAL2  VAL3

I couldn't find any WeiDU commands that allow me to add new columns or detect the actual number of entries in a given row.

 

Any ideas?

Link to comment
COPY_EXISTING ~7EYES.2DA~ override
 COUNT_2DA_COLS cols
 READ_2DA_ENTRIES_NOW ~READ_7EYES~ 1
 FOR (i = 3; i < READ_7EYES; ++i) BEGIN  // i = first row of data
  FOR (j = 0; j < cols; ++j) BEGIN
   PATCH_IF !VARIABLE_IS_SET EVAL ~READ_7EYES_%i%_%j%~ BEGIN
    SET j = cols
    READ_2DA_ENTRY_FORMER ~READ_7EYES~ i 0 newrow
    FOR (k = 1; k < cols; ++k) BEGIN
     PATCH_IF VARIABLE_IS_SET EVAL ~READ_7EYES_%i%_%k%~ BEGIN
      READ_2DA_ENTRY_FORMER ~READ_7EYES~ i k text
      TEXT_SPRINT newrow ~%newrow% %text%~
     END ELSE BEGIN
      TEXT_SPRINT newrow ~%newrow% *~
     END
    END
    REMOVE_2DA_ROW i 1
    INSERT_2DA_ROW i 1 ~%newrow%~
   END
  END
 END
 PRETTY_PRINT_2DA
BUT_ONLY

It requires that you know how many header rows the file has, so that it can skip them, but that number should never change per file.

Use different ~READ_~ variable for every file.

Link to comment

@kjeron Your code works nicely, thanks!

 

The REMOVE_2DA_ROW / INSERT_2DA_ROW operation is a trick I haven't thought of. Instead I tried to extend the structure created by READ_2DA_ENTRIES_NOW directly, but SET_2DA_ENTRIES_NOW didn't catch any of these changes.

 

I have slightly expanded the code and put it into a function if anyone is interested:

 

// Fixes malformed 2DA files. Can also be used to add new columns.
DEFINE_PATCH_FUNCTION FILL_2DA_COLS
INT_VAR
  expand_header = 1     // Whether to expand header row
  num_cols      = "-1"  // Default: Count table columns
STR_VAR
  def_value     = ~~    // Default: Read from table
BEGIN
  PATCH_IF (num_cols < 0) BEGIN
    COUNT_2DA_COLS num_cols
  END

  READ_2DA_ENTRIES_NOW ~table~ 1

  PATCH_IF (~%def_value%~ STR_EQ ~~) BEGIN
    READ_2DA_ENTRY_FORMER ~table~ 1 0 def_value
  END

  PATCH_IF (expand_header) BEGIN
    // processing header
    FOR (col = 0; col < num_cols; ++col) BEGIN
      PATCH_IF (NOT VARIABLE_IS_SET EVAL ~table_2_%col%~) BEGIN
        SET col = num_cols
        READ_2DA_ENTRY_FORMER ~table~ 2 0 line
        FOR (col = 1; col < num_cols - 1; ++col) BEGIN
          PATCH_IF (VARIABLE_IS_SET EVAL ~table_2_%col%~) BEGIN
            READ_2DA_ENTRY_FORMER ~table~ 2 col value
          END ELSE BEGIN
            SET value = col + 1
          END
          TEXT_SPRINT line ~%line% %value%~
        END
        REMOVE_2DA_ROW 2 1
        INSERT_2DA_ROW 2 1 ~%line%~
        SET col = num_cols
      END
    END
  END

  // processing data
  FOR (row = 3; row < table; ++row) BEGIN
    FOR (col = 0; col < num_cols; ++col) BEGIN
      PATCH_IF (NOT VARIABLE_IS_SET EVAL ~table_%row%_%col%~) BEGIN
        READ_2DA_ENTRY_FORMER ~table~ row 0 line
        FOR (col = 1; col < num_cols; ++col) BEGIN
          PATCH_IF (VARIABLE_IS_SET EVAL ~table_%row%_%col%~) BEGIN
            READ_2DA_ENTRY_FORMER ~table~ row col value
          END ELSE BEGIN
            TEXT_SPRINT value ~%def_value%~
          END
          TEXT_SPRINT line ~%line% %value%~
        END
        REMOVE_2DA_ROW row 1
        INSERT_2DA_ROW row 1 ~%line%~
        SET col = num_cols
      END
    END
  END
  PRETTY_PRINT_2DA
END

// Example use:
COPY_EXISTING_REGEXP ~clab.*\.2da~ ~override~
  LPF FILL_2DA_COLS
    INT_VAR num_cols = 51
  END
BUT_ONLY

 

Edited by argent77
Link to comment

Any ideas?

You do know that this is completely unneeded if you only want to insert the *'s into the table ? As the second rows same symbol is the default... meaning that the file is actually filled to without there needing to be those in place. Now of course if you then need to replace sets of those with legitimate replacement values, your solution can have a valid stance, but not in the default case.

Thias can be seen for example in cases which the mx...2da file setting the default to 0 instead of something else.

Link to comment

 

Any ideas?

You do know that this is completely unneeded if you only want to insert the *'s into the table ? As the second rows same symbol is the default... meaning that the file is actually filled to without there needing to be those in place. Now of course if you then need to replace sets of those with legitimate replacement values, your solution can have a valid stance, but not in the default case.

Thias can be seen for example in cases which the mx...2da file setting the default to 0 instead of something else.

 

In my case it seems to be needed. I want to expand tooltip.2da to have individual names for the 4th and 5th ability of an item, which doesn't appear to work if some entries contain less columns. Besides, it improves compatibility with other mods that try to process the file. Otherwise, a COUNT_2DA_COLS followed by COUNT_2DA_ROWS would return a misleading number of rows.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...