diff --git a/tod/PVRZ/v#00100.PVRZ b/tod/PVRZ/v#00100.PVRZ new file mode 100644 index 0000000..7cf4001 Binary files /dev/null and b/tod/PVRZ/v#00100.PVRZ differ diff --git a/tod/PVRZ/v#00101.PVRZ b/tod/PVRZ/v#00101.PVRZ new file mode 100644 index 0000000..b54a608 Binary files /dev/null and b/tod/PVRZ/v#00101.PVRZ differ diff --git a/tod/PVRZ/v#00102.PVRZ b/tod/PVRZ/v#00102.PVRZ new file mode 100644 index 0000000..8942f9c Binary files /dev/null and b/tod/PVRZ/v#00102.PVRZ differ diff --git a/tod/PVRZ/v#00103.PVRZ b/tod/PVRZ/v#00103.PVRZ new file mode 100644 index 0000000..6c1ee5c Binary files /dev/null and b/tod/PVRZ/v#00103.PVRZ differ diff --git a/tod/PVRZ/v#00104.PVRZ b/tod/PVRZ/v#00104.PVRZ new file mode 100644 index 0000000..6726e46 Binary files /dev/null and b/tod/PVRZ/v#00104.PVRZ differ diff --git a/tod/PVRZ/v#00105.PVRZ b/tod/PVRZ/v#00105.PVRZ new file mode 100644 index 0000000..99afc4d Binary files /dev/null and b/tod/PVRZ/v#00105.PVRZ differ diff --git a/tod/PVRZ/v#00200.PVRZ b/tod/PVRZ/v#00200.PVRZ new file mode 100644 index 0000000..0ad9052 Binary files /dev/null and b/tod/PVRZ/v#00200.PVRZ differ diff --git a/tod/PVRZ/v#00300.PVRZ b/tod/PVRZ/v#00300.PVRZ new file mode 100644 index 0000000..bef77d3 Binary files /dev/null and b/tod/PVRZ/v#00300.PVRZ differ diff --git a/tod/PVRZ/v#00400.PVRZ b/tod/PVRZ/v#00400.PVRZ new file mode 100644 index 0000000..7164ab3 Binary files /dev/null and b/tod/PVRZ/v#00400.PVRZ differ diff --git a/tod/PVRZ/v#00500.PVRZ b/tod/PVRZ/v#00500.PVRZ new file mode 100644 index 0000000..b671634 Binary files /dev/null and b/tod/PVRZ/v#00500.PVRZ differ diff --git a/tod/PVRZ/v#00600.PVRZ b/tod/PVRZ/v#00600.PVRZ new file mode 100644 index 0000000..1e281d7 Binary files /dev/null and b/tod/PVRZ/v#00600.PVRZ differ diff --git a/tod/PVRZ/v#00700.PVRZ b/tod/PVRZ/v#00700.PVRZ new file mode 100644 index 0000000..fb55385 Binary files /dev/null and b/tod/PVRZ/v#00700.PVRZ differ diff --git a/tod/PVRZ/v#00701.PVRZ b/tod/PVRZ/v#00701.PVRZ new file mode 100644 index 0000000..6bb189d Binary files /dev/null and b/tod/PVRZ/v#00701.PVRZ differ diff --git a/tod/PVRZ/v#00702.PVRZ b/tod/PVRZ/v#00702.PVRZ new file mode 100644 index 0000000..e8fe915 Binary files /dev/null and b/tod/PVRZ/v#00702.PVRZ differ diff --git a/tod/PVRZ/v#00703.PVRZ b/tod/PVRZ/v#00703.PVRZ new file mode 100644 index 0000000..fc0bcee Binary files /dev/null and b/tod/PVRZ/v#00703.PVRZ differ diff --git a/tod/PVRZ/v#00704.PVRZ b/tod/PVRZ/v#00704.PVRZ new file mode 100644 index 0000000..050857a Binary files /dev/null and b/tod/PVRZ/v#00704.PVRZ differ diff --git a/tod/PVRZ/v#00705.PVRZ b/tod/PVRZ/v#00705.PVRZ new file mode 100644 index 0000000..252c846 Binary files /dev/null and b/tod/PVRZ/v#00705.PVRZ differ diff --git a/tod/PVRZ/v#00800.PVRZ b/tod/PVRZ/v#00800.PVRZ new file mode 100644 index 0000000..17f24e7 Binary files /dev/null and b/tod/PVRZ/v#00800.PVRZ differ diff --git a/tod/PVRZ/v#00900.PVRZ b/tod/PVRZ/v#00900.PVRZ new file mode 100644 index 0000000..5029451 Binary files /dev/null and b/tod/PVRZ/v#00900.PVRZ differ diff --git a/tod/PVRZ/v#01000.PVRZ b/tod/PVRZ/v#01000.PVRZ new file mode 100644 index 0000000..b03e65e Binary files /dev/null and b/tod/PVRZ/v#01000.PVRZ differ diff --git a/tod/PVRZ/v#01100.PVRZ b/tod/PVRZ/v#01100.PVRZ new file mode 100644 index 0000000..91d2f46 Binary files /dev/null and b/tod/PVRZ/v#01100.PVRZ differ diff --git a/tod/PVRZ/v#mov00.PVRZ b/tod/PVRZ/v#mov00.PVRZ new file mode 100644 index 0000000..121f6a8 Binary files /dev/null and b/tod/PVRZ/v#mov00.PVRZ differ diff --git a/tod/PVRZ/v#mov01.PVRZ b/tod/PVRZ/v#mov01.PVRZ new file mode 100644 index 0000000..3d98cb6 Binary files /dev/null and b/tod/PVRZ/v#mov01.PVRZ differ diff --git a/tod/PVRZ/va#001.tis b/tod/PVRZ/va#001.tis new file mode 100644 index 0000000..b0cbf85 Binary files /dev/null and b/tod/PVRZ/va#001.tis differ diff --git a/tod/PVRZ/va#002.tis b/tod/PVRZ/va#002.tis new file mode 100644 index 0000000..977f428 Binary files /dev/null and b/tod/PVRZ/va#002.tis differ diff --git a/tod/PVRZ/va#003.tis b/tod/PVRZ/va#003.tis new file mode 100644 index 0000000..71b4acd Binary files /dev/null and b/tod/PVRZ/va#003.tis differ diff --git a/tod/PVRZ/va#004.tis b/tod/PVRZ/va#004.tis new file mode 100644 index 0000000..71b4acd Binary files /dev/null and b/tod/PVRZ/va#004.tis differ diff --git a/tod/PVRZ/va#005.tis b/tod/PVRZ/va#005.tis new file mode 100644 index 0000000..cc7d28c Binary files /dev/null and b/tod/PVRZ/va#005.tis differ diff --git a/tod/PVRZ/va#006.tis b/tod/PVRZ/va#006.tis new file mode 100644 index 0000000..0318357 Binary files /dev/null and b/tod/PVRZ/va#006.tis differ diff --git a/tod/PVRZ/va#007.tis b/tod/PVRZ/va#007.tis new file mode 100644 index 0000000..2c3e118 Binary files /dev/null and b/tod/PVRZ/va#007.tis differ diff --git a/tod/PVRZ/va#008.tis b/tod/PVRZ/va#008.tis new file mode 100644 index 0000000..2fa26dc Binary files /dev/null and b/tod/PVRZ/va#008.tis differ diff --git a/tod/PVRZ/va#009.tis b/tod/PVRZ/va#009.tis new file mode 100644 index 0000000..aab58b8 Binary files /dev/null and b/tod/PVRZ/va#009.tis differ diff --git a/tod/PVRZ/va#010.tis b/tod/PVRZ/va#010.tis new file mode 100644 index 0000000..ce06c54 Binary files /dev/null and b/tod/PVRZ/va#010.tis differ diff --git a/tod/PVRZ/va#011.tis b/tod/PVRZ/va#011.tis new file mode 100644 index 0000000..f28a81e Binary files /dev/null and b/tod/PVRZ/va#011.tis differ diff --git a/tod/PVRZ/va#mov.tis b/tod/PVRZ/va#mov.tis new file mode 100644 index 0000000..4b84230 Binary files /dev/null and b/tod/PVRZ/va#mov.tis differ diff --git a/tod/lib/a7_pvrz_tis.tpa b/tod/lib/a7_pvrz_tis.tpa new file mode 100644 index 0000000..20a3e01 --- /dev/null +++ b/tod/lib/a7_pvrz_tis.tpa @@ -0,0 +1,520 @@ +/* +Author: argent77. TIS support by argent77 and Sam. + +Summary: +Functions for installing custom PVRZ-based BAM, MOS, and TIS resources in Enhanced Edition games. + +Available functions: +TIS_RES_TO_PVRZ PATCH or ACTION function. Returns the PVRZ filename prefix based on the specified TIS + filename. +UPDATE_PVRZ_INDICES PATCH function. Updates PVRZ references in the BAM V2, MOS V2, or pvrz-based TIS file to + the next contiguous block of free PVRZ indices. +INSTALL_PVRZ ACTION function. Installs a PVRZ file and updates their PVRZ index. Use in conjunction + with "UPDATE_PVRZ_INDICES". +FIND_FREE_PVRZ_INDEX PATCH or ACTION function. Attempts to find a contiguous block of free PVRZ indices + in the game installation. + +Examples +~~~~~~~~ + +Example 1: Installing the file "mypic.bam" and associated mos0000.pvrz, mos0001.pvrz, mos0002.pvrz + located in the folder "mymod/bam". + +// Installing BAM resource +COPY ~mymod/bam/mypic.bam~ ~override~ + LPF UPDATE_PVRZ_INDICES + RET + original_base_index + new_base_index + END + +// It is strongly recommended to check the return values of "UPDATE_PVRZ_INDICES". +ACTION_IF (new_base_index >= 0) BEGIN + // Installing associated PVRZ resources + ACTION_FOR_EACH file IN ~mos0000.pvrz~ ~mos0001.pvrz~ ~mos0002.pvrz~ + LAF INSTALL_PVRZ + INT_VAR + original_base_index + new_base_index + STR_VAR + source_file = EVAL ~mymod/bam/%file%~ + RET + success + DEST_FILE + END + ACTION_IF (success) BEGIN + PRINT ~Successfully installed file %file% as %DEST_FILE%.~ + END ELSE BEGIN + WARN ~Could not install file %file%!~ + END + END +END + +In a clean game installation, this script portion will copy all files into the override folder of the game, +rename the PVRZ files to mos1000.pvrz, mos1001.pvrz, mos1002.pvrz and update the PVRZ references in +"mypic.bam" accordingly. + + +Example 2: Installing the files "mypic1.mos" and "mypic2.mos" which share a single PVRZ file. + "mypic1.mos" references mos0000.pvrz, mos0001.pvrz and mos0002.pvrz. + "mypic2.mos" references mos0002.pvrz and mos0003.pvrz. + +// Installing MOS resource 1 +COPY ~mymod/mos/mypic1.mos~ ~override~ + LPF UPDATE_PVRZ_INDICES + RET + original_base_index + new_base_index + END + +ACTION_IF (new_base_index >= 0) BEGIN + // Installing PVRZ resources associated with "mypic1.mos" + ACTION_FOR_EACH file IN ~mos0000.pvrz~ ~mos0001.pvrz~ ~mos0002.pvrz~ + LAF INSTALL_PVRZ + INT_VAR + original_base_index + new_base_index + STR_VAR + source_file = EVAL ~mymod/mos/%file%~ + RET + success + END + ACTION_IF (NOT success) BEGIN + WARN ~Could not install file %file%!~ + END + END +END + +// Installing MOS resource 2 +COPY ~mymod/mos/mypic2.mos~ ~override~ + LPF UPDATE_PVRZ_INDICES + RET + original_base_index + new_base_index + END + +ACTION_IF (new_base_index >= 0) BEGIN + // Installing PVRZ resources associated with "mypic2.mos" + ACTION_FOR_EACH file IN ~mos0002.pvrz~ ~mos0003.pvrz~ + LAF INSTALL_PVRZ + INT_VAR + original_base_index + new_base_index + STR_VAR + source_file = EVAL ~mymod/mos/%file%~ + RET + success + END + ACTION_IF (NOT success) BEGIN + WARN ~Could not install file %file%!~ + END + END +END + +The function "UPDATE_PVRZ_INDICES" does not directly support MOS or BAM files with shared PVRZ files. +As a result, copies of the shared PVRZ files will be installed for each affected MOS or BAM file. +*/ + +/** + * This PATCH function returns the PVRZ resource prefix based on the given TIS filename. + * + * STR_VAR tis_res The TIS filename with or without .tis extension. + * RET prefix The PVRZ resource prefix associated with the specified TIS filename. + * Returns empty string on error. + */ +DEFINE_PATCH_FUNCTION TIS_RES_TO_PVRZ + STR_VAR + tis_res = ~~ + RET + prefix +BEGIN + // Make sure only filename without extension is specified + PATCH_IF (~%tis_res%~ STRING_CONTAINS_REGEXP ~\.TIS$~ = 0) BEGIN + LPF RES_OF_FILESPEC STR_VAR filespec = EVAL ~%tis_res%~ RET tis_res = res END + END + + PATCH_IF (STRING_LENGTH ~%tis_res%~ > 1) BEGIN + INNER_PATCH_SAVE prefix ~%tis_res%~ BEGIN DELETE_BYTES 1 1 END + END ELSE BEGIN + TEXT_SPRINT prefix ~~ + END +END + +/** + * This ACTION function returns the PVRZ resource prefix based on the given TIS filename. + * + * STR_VAR tis_res The TIS filename with or without .tis extension. + * RET prefix The PVRZ resource prefix associated with the specified TIS filename. + * Returns empty string on error. + */ +DEFINE_ACTION_FUNCTION TIS_RES_TO_PVRZ + STR_VAR + tis_res = ~~ + RET + prefix +BEGIN + OUTER_PATCH ~foo~ BEGIN + LPF TIS_RES_TO_PVRZ STR_VAR tis_res RET prefix END + END +END + + +/** + * This patch function updates all PVRZ references in the BAM V2, MOS V2, or TIS V1 file to the next unoccupied block + * of PVRZ indices. This function is intended to be used in combination with the action function "INSTALL_PVRZ". + * + * INT_VAR target_base_index Optional parameter. When specified, the function attempts to use a block of free PVRZ + * indices starting at the specified value. + * (default: 0 for TIS-related PVRZ files, 1000 otherwise) + * RET original_base_index Returns the lowest PVRZ index used by the source BAM, MOS, or TIS. Returns -1 on error. + * RET new_base_index Returns the lowest PVRZ index used by the target BAM, MOS, or TIS. Returns -1 on error. + * RET index_range Returns the range of reserved PVRZ indices, i.e. the difference between the smallest + * and biggest PVRZ index inclusive. Returns 0 on error. + */ +DEFINE_PATCH_FUNCTION UPDATE_PVRZ_INDICES + INT_VAR + target_base_index = "-1" + RET + original_base_index + new_base_index + index_range +BEGIN + SET original_base_index = "-1" + SET new_base_index = "-1" + SET index_range = 0 + SET max_base_index = 99999 + SET def_base_index = 1000 + TEXT_SPRINT prefix ~MOS~ + PATCH_IF (ENGINE_IS ~bgee bg2ee iwdee pstee~) BEGIN + // initializations + SET is_valid = 0 + READ_ASCII 0 sig (8) + PATCH_MATCH ~%sig%~ WITH + ~BAM V2 ~ BEGIN + READ_LONG 0x10 num_blocks + READ_LONG 0x1c ofs_blocks + SET block_size = 28 + SET is_valid = 1 + END + ~MOS V2 ~ BEGIN + READ_LONG 0x10 num_blocks + READ_LONG 0x14 ofs_blocks + SET block_size = 28 + SET is_valid = 1 + END + ~TIS V1 ~ BEGIN + READ_LONG 0xc block_size + PATCH_IF (block_size = 12) BEGIN + READ_LONG 0x08 num_blocks + READ_LONG 0x10 ofs_blocks + // getting tis resref... + PATCH_IF (DIRECTORY_EXISTS ~%DEST_FILESPEC%~) BEGIN + TEXT_SPRINT tis_res ~%SOURCE_RES%~ + END ELSE BEGIN + LPF RES_OF_FILESPEC STR_VAR filespec = EVAL ~%DEST_FILESPEC%~ RET tis_res = res END + END + // ...to derive pvrz prefix + LPF TIS_RES_TO_PVRZ STR_VAR tis_res RET prefix END + PATCH_IF (NOT ~%prefix%~ STR_EQ ~~) BEGIN + SET max_base_index = 99 + SET def_base_index = 0 + SET is_valid = 1 + END + END + END + DEFAULT + END + + PATCH_IF (is_valid) BEGIN + PATCH_IF (target_base_index < 0) BEGIN SET target_base_index = def_base_index END + PATCH_IF (target_base_index > max_base_index) BEGIN + PATCH_LOG ~Target base index (%target_base_index%) is out of range. Using default value (%def_base_index%).~ + SET target_base_index = def_base_index + END + + // finding minimum and maximum pvrz index + SET min = max_base_index + 1 + SET max = "-1" + FOR (i = 0; i < num_blocks; ++i) BEGIN + SET ofs = ofs_blocks + i * block_size + READ_LONG ofs page + PATCH_IF (page >= 0) BEGIN + PATCH_IF (page < min) BEGIN SET min = page END + PATCH_IF (page > max) BEGIN SET max = page END + END + END + + PATCH_IF (min >= 0 && max >= min) BEGIN + SET index_range = max - min + 1 + LPF FIND_FREE_PVRZ_INDEX INT_VAR num_to_reserve = index_range start_index = target_base_index STR_VAR prefix RET free_index END + PATCH_IF (free_index >= 0) BEGIN + SET original_base_index = min + SET new_base_index = free_index + SET offset = new_base_index - original_base_index + // updating pvrz references + FOR (i = 0; i < num_blocks; ++i) BEGIN + SET ofs = ofs_blocks + i * block_size + WRITE_LONG ofs (THIS >= 0) ? (THIS + offset) : THIS + END + SET success = 1 + END ELSE BEGIN + PATCH_WARN ~Unable to find free block of PVRZ indices. No changes have been made.~ + END + END ELSE BEGIN + PATCH_WARN ~File contains no pvrz references. No changes have been made.~ + END + END ELSE BEGIN + PATCH_WARN ~Unsupported resource type or corrupted BAM V2, MOS V2, or pvrz-based TIS detected. No changes have been made.~ + END + END ELSE BEGIN + PATCH_WARN ~Game is not supported.~ + END +END + + +/** + * Copies the specified PVRZ file into the target folder and updates the PVRZ index. + * This function should be used in conjunction with "UPDATE_PVRZ_INDICES". + * + * INT_VAR original_base_index The current base index (returned by the function "UPDATE_PVRZ_INDICES" as + * "original_base_index"). + * INT_VAR new_base_index The new base index (returned by the function "UPDATE_PVRZ_INDICES" as + * "new_base_index"). + * INT_VAR backup Set to non-zero to have WeiDU create a backup that is restored when the mod is + * uninstalled. Set to zero to forbid restoring the file when the mod is uninstalled. + * (Default: 1 - create backup) + * STR_VAR source_file The source file to copy. For BAM and MOS files, the filename must match the regular + * expression "MOS[0-9]{4,5}\.PVRZ" (e.g. MOS0000.PVRZ, mos1592.pvrz or Mos12345.PVRZ). + * For TIS files, the filename must match the regular expression "%prefix%[0-9][0-9]\.PVRZ" + * Case is ignored. + * STR_VAR target_folder The target folder to copy the source file into. (Default: override) + * RET success Set to non-zero if the function returned successfully and set to zero on error. + * RET SOURCE_*, DEST_* Returns all variables that are automatically set by a WeiDU COPY operation on success. + */ +DEFINE_ACTION_FUNCTION INSTALL_PVRZ + INT_VAR + original_base_index = "-1" + new_base_index = "-1" + backup = 1 + STR_VAR + source_file = ~~ + target_folder = ~override~ + RET + success + SOURCE_DIRECTORY SOURCE_FILESPEC SOURCE_FILE SOURCE_RES SOURCE_EXT SOURCE_SIZE + DEST_DIRECTORY DEST_FILESPEC DEST_FILE DEST_RES DEST_EXT +BEGIN + OUTER_SET success = 0 + ACTION_IF (ENGINE_IS ~bgee bg2ee iwdee pstee~) BEGIN + ACTION_IF (original_base_index >= 0 && new_base_index >= 0 && FILE_EXISTS ~%source_file%~) BEGIN + // Making sure that target points to a directory + ACTION_IF (~%target_folder%~ STR_EQ ~~) BEGIN OUTER_TEXT_SPRINT target_folder ~.~ END + ACTION_IF (DIRECTORY_EXISTS ~%target_folder%~) BEGIN + LAF EXT_OF_FILESPEC STR_VAR filespec = EVAL ~%source_file%~ RET ext END + LAF RES_OF_FILESPEC STR_VAR filespec = EVAL ~%source_file%~ RET res END + END ELSE BEGIN + LAF EXT_OF_FILESPEC STR_VAR filespec = EVAL ~%target_folder%~ RET ext END + LAF RES_OF_FILESPEC STR_VAR filespec = EVAL ~%target_folder%~ RET res END + LAF DIRECTORY_OF_FILESPEC STR_VAR filespec = EVAL ~%target_folder%~ RET target_folder = directory END + END + + // initializations + OUTER_SET failed = 0 + ACTION_IF (~%res%~ STRING_MATCHES_REGEXP ~MOS[0-9][0-9][0-9][0-9][0-9]?$~ = 0) BEGIN + OUTER_SET max_index = 99999 + OUTER_TEXT_SPRINT fmt_index ~-4~ + // separate pvrz prefix and index + OUTER_PATCH_SAVE res_index ~%res%~ BEGIN + READ_ASCII 0 res_prefix (3) + DELETE_BYTES 0 3 + END + END ELSE ACTION_IF (~%res%~ STRING_MATCHES_REGEXP ~.+[0-9][0-9]$~ = 0) BEGIN + OUTER_SET max_index = 99 + OUTER_TEXT_SPRINT fmt_index ~-2~ + // separate pvrz prefix and index + OUTER_SET len = STRING_LENGTH ~%res%~ + OUTER_PATCH_SAVE res_index ~%res%~ BEGIN + READ_ASCII 0 res_prefix (len - 2) + DELETE_BYTES 0 (len - 2) + END + END ELSE BEGIN + OUTER_SET failed = 1 + WARN ~Invalid source file specified: %source_file%. Skipping operation.~ + END + + // update filename and install pvrz file + ACTION_IF (NOT failed) BEGIN + OUTER_SET offset = new_base_index - original_base_index + OUTER_SET old_index = res_index + OUTER_SET new_index = old_index + offset + ACTION_IF (new_index >= 0 && new_index <= max_index) BEGIN + // ensure required number of digits + OUTER_SNPRINT ~%fmt_index%~ new_index ~0000%new_index%~ + OUTER_TEXT_SPRINT new_res ~%res_prefix%%new_index%~ + OUTER_TEXT_SPRINT target_filespec ~%target_folder%/%new_res%.%ext%~ + ACTION_IF (backup) BEGIN + COPY ~%source_file%~ ~%target_filespec%~ + END ELSE BEGIN + COPY + ~%source_file%~ ~%target_filespec%~ + END + OUTER_SET success = 1 + END ELSE BEGIN + WARN ~New PVRZ index is out of range: %new_index%. Skipping file.~ + END + END + END ELSE BEGIN + FAIL ~One or more required parameters are undefined.~ + END + END ELSE BEGIN + WARN ~Game is not supported.~ + END +END + + +/** + * This PATCH function attempts to find the first available free PVRZ index of a contiguous block + * which guarantees to fit at least "num_to_reserve" indices. + * + * INT_VAR num_to_reserve Find a contiguous block of at least this number of free indices + * (range: [1..100] for TIS-related PVRZ files, [1..999] otherwise, default: 1) + * INT_VAR start_index Index to start looking for (default: 0 for TIS-related PVRZ files, 1000 otherwise) + * STR_VAR prefix Prefix of the PVRZ files associated with the BAM, MOS, or TIS file. For BAM and MOS files, + * the prefix will be "MOS". For TIS files it will be the TIS filename minus the second + * character. Use function TIS_RES_TO_PVRZ to derive the PVRZ prefix from a TIS filename. + * (default: MOS) + * RET free_index Returns the first available index matching the specified parameters if successful. + * Returns -1 if no sufficiently large block of free slots could be found. + */ +DEFINE_PATCH_FUNCTION FIND_FREE_PVRZ_INDEX + INT_VAR + num_to_reserve = 1 + start_index = "-1" + STR_VAR + prefix = ~MOS~ + RET + free_index +BEGIN + SET free_index = "-1" + + SET failed = 0 + PATCH_IF (~%prefix%~ STR_EQ ~MOS~) BEGIN + SET max_to_reserve = 999 + SET max_start_index = 100000 + PATCH_IF (start_index < 0) BEGIN SET start_index = 1000 END + END ELSE PATCH_IF (STRING_LENGTH ~%prefix%~ > 0 && STRING_LENGTH ~%prefix%~ <= 6) BEGIN + SET max_to_reserve = 100 + SET max_start_index = 100 + PATCH_IF (start_index < 0) BEGIN SET start_index = 0 END + END ELSE BEGIN + PATCH_WARN ~Invalid prefix specified: "%prefix%"~ + SET failed = 1 + END + + PATCH_IF (NOT failed && ENGINE_IS ~bgee bg2ee iwdee pstee~) BEGIN + PATCH_IF (num_to_reserve < 1) BEGIN + SET num_to_reserve = 1 + PATCH_LOG ~Block size too small. Using default of 1.~ + END ELSE PATCH_IF (num_to_reserve > max_to_reserve) BEGIN + SET num_to_reserve = max_to_reserve + PATCH_LOG ~Block size too big. Truncating to %max_to_reserve%.~ + END + PATCH_IF (start_index + num_to_reserve > max_start_index) BEGIN + SET start_index = max_start_index - num_to_reserve + PATCH_LOG ~Start index too big. Setting start index to %start_index%.~ + END + + SET count = 0 + FOR (index = start_index; index < max_start_index; ++index) BEGIN + LPF a7#__is_free_pvrz INT_VAR index STR_VAR prefix RET is_free_index END + PATCH_IF (is_free_index) BEGIN + PATCH_IF (count = 0) BEGIN + SET free_index = index + END + SET count += 1 + + // block found? + PATCH_IF (count >= num_to_reserve) BEGIN + SET index = max_start_index + END + END ELSE BEGIN + // start counting anew + SET count = 0 + END + END + + PATCH_IF (count < num_to_reserve) BEGIN + SET free_index = "-1" + END + END ELSE BEGIN + PATCH_WARN ~Game is not supported.~ + END +END + + +/** + * This ACTION function attempts to find the first available free PVRZ index of a contiguous block + * which guarantees to fit at least "num_to_reserve" indices. + * + * INT_VAR num_to_reserve Find a contiguous block of at least this number of free indices + * (range: [1..100] for TIS-related PVRZ files, [1..999] otherwise, default: 1) + * INT_VAR start_index Index to start looking for (default: 0 for TIS-related PVRZ files, 1000 otherwise) + * STR_VAR prefix Prefix of the PVRZ files associated with the BAM, MOS, or TIS file. For BAM and MOS files, + * the prefix will be "MOS". For TIS files it will be the TIS filename minus the second + * character. Use function TIS_RES_TO_PVRZ to derive the PVRZ prefix from a TIS filename. + * (default: MOS) + * RET free_index Returns the first available index matching the specified parameters if successful. + * Returns -1 if no sufficiently large block of free slots could be found. + */ +DEFINE_ACTION_FUNCTION FIND_FREE_PVRZ_INDEX + INT_VAR + num_to_reserve = 1 + start_index = "-1" + STR_VAR + prefix = ~MOS~ + RET + free_index +BEGIN + OUTER_PATCH ~foo~ BEGIN + LPF FIND_FREE_PVRZ_INDEX + INT_VAR + num_to_reserve + start_index + STR_VAR + prefix + RET + free_index + END + END +END + + +// Used internally. Determines whether the file MOSxxxx.PVRZ or %prefix%xx.PVRZ is still unoccupied, +// where xxxx and xx are numeric indices. +DEFINE_PATCH_FUNCTION a7#__is_free_pvrz + INT_VAR + index = 0 + STR_VAR + prefix = ~MOS~ + RET + is_free_index +BEGIN + SET max = (~%prefix%~ STR_EQ ~MOS~) ? 99999 : 99 + PATCH_IF (index < 0) BEGIN + SET index = 0 + END ELSE PATCH_IF (index > max) BEGIN + SET index = max + END + + PATCH_IF (~%prefix%~ STR_EQ ~MOS~) BEGIN + PATCH_IF (index <= 9999) BEGIN + SNPRINT "-4" index ~0000%index%~ + END + END ELSE BEGIN + SNPRINT "-2" index ~00%index%~ + END + TEXT_SPRINT cur_file ~%prefix%%index%.PVRZ~ + + SET is_free_index = (FILE_EXISTS_IN_GAME ~%cur_file%~ || + FILE_EXISTS ~%USER_DIRECTORY%/override/%cur_file%~ || + FILE_EXISTS ~lang/%EE_LANGUAGE%/override/%cur_file%~) ? 0 : 1 +END diff --git a/tod/tod.tp2 b/tod/tod.tp2 index c25a1fb..d67d493 100644 --- a/tod/tod.tp2 +++ b/tod/tod.tp2 @@ -53,9 +53,46 @@ BEGIN @100 COPY ~%MOD_FOLDER%/Bmp~ ~override~ COPY ~%MOD_FOLDER%/Mos~ ~override~ COPY ~%MOD_FOLDER%/Spl~ ~override~ + ACTION_IF GAME_IS ~bgt tob~ THEN BEGIN COPY ~%MOD_FOLDER%/Tis~ ~override~ + END COPY ~%MOD_FOLDER%/Wav~ ~override~ COPY ~%MOD_FOLDER%/Wed~ ~override~ + + ACTION_IF (GAME_IS ~bg2ee eet~) BEGIN + + // Install pvrz-based tilesets without the danger of overwriting pvrz files from other mods or the game itself. + + INCLUDE ~%MOD_FOLDER%/lib/a7_pvrz_tis.tpa~ + + // Installing all TIS files from the specified folder + + ACTION_BASH_FOR ~%MOD_FOLDER%/PVRZ~ ~^.+\.tis$~ BEGIN + COPY ~%BASH_FOR_FILESPEC%~ ~override~ + LPF UPDATE_PVRZ_INDICES RET original_base_index new_base_index END + + // Installing associated PVRZ files for each tileset individually + + ACTION_IF (new_base_index >= 0) BEGIN + LAF TIS_RES_TO_PVRZ STR_VAR tis_res = EVAL ~%BASH_FOR_FILESPEC%~ RET prefix END + + ACTION_BASH_FOR ~%MOD_FOLDER%/PVRZ~ ~^%prefix%.+\.pvrz$~ BEGIN + LAF INSTALL_PVRZ + INT_VAR original_base_index new_base_index + STR_VAR source_file = EVAL ~%BASH_FOR_FILESPEC%~ + RET success DEST_FILESPEC + END + + ACTION_IF (NOT success) BEGIN + FAIL ~Could not install "%BASH_FOR_FILESPEC%"!~ + END + END + END ELSE BEGIN + FAIL ~Could not install "%BASH_FOR_FILESPEC%"!~ + END + END + +END //////////////////// // Compiling Bafs // diff --git a/tod/tra/French/setup.tra b/tod/tra/French/setup.tra index 32e28ad..093da65 100644 --- a/tod/tra/French/setup.tra +++ b/tod/tra/French/setup.tra @@ -55,7 +55,7 @@ Capacités de combat : Capacités spéciales : Permet de lancer "Puiser dans la puissance divine" deux fois par jour Permet de lancer deux sorts par round - -1 à la Dexterité + -1 à la Dextérité 30% de résistance à la magie TAC0 : +5 diff --git a/tod/tra/French/va#tian.tra b/tod/tra/French/va#tian.tra index 4b01f36..d1aac19 100644 --- a/tod/tra/French/va#tian.tra +++ b/tod/tra/French/va#tian.tra @@ -18,7 +18,7 @@ @15 = ~Je vous ai dit tout ce dont vous aurez besoin pour accomplir votre mission. Une fois à l'intérieur de la tour, vous découvrirez le reste.~ @16 = ~Bien. Mon maître sera content.~ @17 = ~Un capitaine en qui j'ai toute confiance vous attend sur son navire dans une baie isolée assez proche d'ici. Je vais vous y amener. Rappelez-vous, à partir de ce point vous ne pourrez compter que sur vous-même. Quand vous aurez terminé, revenez me voir. En route maintenant : la Tour vous attend...~ -@18 = ~Que vous partiez maintenant ou plus tard, mon offre tient toujours. Je préfèrerais cependant que vous accomplissiez cette mission assez rapidement.~ +@18 = ~Que vous partiez maintenant ou plus tard, mon offre tient toujours. Je préférerais cependant que vous accomplissiez cette mission assez rapidement.~ @19 = ~Comme vous voulez. Au revoir.~ @20 = ~Ah, vous revoilà. Avez-vous changé d'avis ?~ @21 = ~Effectivement, j'ai changé d'avis. Reparlez-moi un peu de votre offre.~ @@ -40,7 +40,7 @@ ~Certainement. La voilà, comme promis. Je vous remercie sincèrement. Vous avez fait preuve de talent et vous vous êtes également montrée digne de confiance. Adieu, .~ @35 = ~Merci. Adieu.~ @36 = ~Ne jouez pas au plus fin avec moi, . Je ne suis pas de bonne humeur. Donnez-le moi tout de suite. Nous avions un accord !~ -@37 = ~Non. Comme je viens de vous le dire, je préfèrerais le garder.~ +@37 = ~Non. Comme je viens de vous le dire, je préférerais le garder.~ @38 = ~Vous ne me laissez guère le choix. Je m'en emparerai par la force, si nécessaire. Préparez-vous à mourir !~ @39 = ~Idiots ! Vous êtes revenus sans le livre ? Comment est-ce possible ? Vous auriez mieux fait de rester là-bas, pauvres crétins ! Je ne veux plus avoir à faire à vous !~ diff --git a/tod/tra/French/va#ustrn.tra b/tod/tra/French/va#ustrn.tra index 01346fb..614f9d7 100644 --- a/tod/tra/French/va#ustrn.tra +++ b/tod/tra/French/va#ustrn.tra @@ -19,16 +19,16 @@ ~Il va pourtant vous falloir l'accepter et bien plus encore, et même en redemander, si tel est mon bon plaisir ! Sale voleuse !~ @18 = ~Dans ce cas, vous allez devoir trouver un peu de temps.~ @19 = ~Mais bien sûr, vous feignez l'ignorance. Et pourquoi pas ? Après tout, vous avez démoli ma citadelle, subtilisé mes biens les plus précieux et libéré mes esclaves. Il est tout à fait normal que vous me essayiez de me mentir bassement pour échapper à ma vengeance.~ -@20 = ~S'il vous plaît, rafraichissez-moi donc la mémoire, de quelle citadelle parlez-vous ? J'en ai démolies tellement, vous savez...~ +@20 = ~S'il vous plaît, rafraîchissez-moi donc la mémoire, de quelle citadelle parlez-vous ? J'en ai démolies tellement, vous savez...~ @21 = ~Vous voulez vous battre ? Je suis fin prêt.~ ~Vous voulez vous battre ? Je suis fin prête.~ @22 = ~Avant que je ne vous transperce de mon épée, auriez-vous l'obligeance de me dire votre nom ?~ @23 = ~Je vous assure que je ne veux pas me disputer. Si je vous ai fait du tort de quelque manière que ce soit, alors je vous demande pardon.~ -@24 = ~Ca me rappelle quelque chose...~ +@24 = ~Ça me rappelle quelque chose...~ @25 = ~Votre effronterie commence à me taper sur les nerfs. Vous feriez mieux de surveiller vos paroles.~ @26 = ~La question n'est pas là. C'est plutôt une question de puissance, dont vous manquez vraiment beaucoup. A moins peut-être que vous n'ayez l'intention d'utiliser mon propre équipement contre moi, en espérant contre toute attente qu'il puisse vous aider contre son maître légitime ?~ @27 = ~Bien que je sois très tenté de vous tuer sans même que vous ne sachiez vraiment pourquoi, je crois que je vais effectivement accéder à votre demande. Dans un instant.~ -@28 = ~Epargnez-moi vos pleurnicheries. Il est trop tard pour cela, bien que je sois sensible à vos sentiments.~ +@28 = ~Épargnez-moi vos pleurnicheries. Il est trop tard pour cela, bien que je sois sensible à vos sentiments.~ @29 = ~Cela ne vous sera d'aucune aide, bien sûr. Soyons clair, vous êtes condamné. Dès l'instant où vous avez posé le pied sur le seuil de ma tour, vous avez renoncé à votre vie.~ ~Cela ne vous sera d'aucune aide, bien sûr. Soyons clair, vous êtes condamnée. Dès l'instant où vous avez posé le pied sur le seuil de ma tour, vous avez renoncé à votre vie.~ @30 = ~Je ne comprends toujours pas.~