Lauriel Posted August 27, 2021 Posted August 27, 2021 Your tools made it super easy to add the closed door tiles to the end of the TIS, too. Spoiler // Add closed door tiles to end of TIS LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%strt_idx%" PVRz_X = 0 PVRz_Y = 448 STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%strt_idx%" PVRz_X = 64 PVRz_Y = 448 STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%strt_idx%" PVRz_X = 0 PVRz_Y = 512 STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%strt_idx%" PVRz_X = 64 PVRz_Y = 512 STR_VAR Method = "Push" RET Count END Quote
Lauriel Posted October 5, 2021 Posted October 5, 2021 (edited) I did a function that adds a door. It's not generic, but it's a start. It should help folks get over some hurdles at least. It's a lot of code...feel free to rip into it. Everything can always be better. Spoiler //////////////////////////////////////////////////// // ADD A DOOR TO AN AREA AND ITS ASSOCIATED FILES // // PVRz are compressed graphic files // // TIS are a series of indices pointing to // // sections (tiles) in the PVRz files // // An area can have two TIS/WED files associated // // with it. One for day, one for night. // // If the area has a day and night version, then // // this will need to be called twice - once // // for each TIS/WED // // // // THIS IS NOT A GENERIC FUNCTION // // IT WAS BUILT FOR A VERY SPECIFIC CASE // // MUCH WORK WOULD NEED TO BE DONE TO MAKE IT // // FIT ALL USE CASES // //////////////////////////////////////////////////// // To get the x/y of the open and closed tiles (g_closed_... and g_open_...) use: // COPY_EXISTING ~<your source tis file>.tis~ ~override~ // LPF ps_tileset_info INT_VAR Verbose = 2 Log = 1 END // Log verbose output of PVRz-based tileset to file // BUT_ONLY // Then open up the log file it generates, search for your tile #s and it'll list and the X/Ys needed to use in his other functions // I could probably automate that process...but I don't feel much inclined to do so DEFINE_ACTION_FUNCTION ADD_DOOR INT_VAR is_day = 0 g_closed_x1 = 0 // X,Y coordinates of the graphic within the source PVRz file (use ps_tileset_info to determine) g_closed_x2 = 0 g_closed_y1 = 0 g_closed_y2 = 0 g_open_x1 = 0 g_open_x2 = 0 g_open_y1 = 0 g_open_y2 = 0 t_open_pos1 = 0 // The tile # in the target TIS to be replaced (closed are added to the end of the file, not replaced) t_open_pos2 = 0 t_open_pos3 = 0 t_open_pos4 = 0 v_closed_x0 = 0 // X/Y pairs (vertices) of the actual door object - only allowing 4 per door state v_closed_y0 = 0 // Must be given in clockwise order starting with the one furthest to the right v_closed_x1 = 0 // If 2 tie for rightmost - use the lower of the two v_closed_y1 = 0 v_closed_x2 = 0 v_closed_y2 = 0 v_closed_x3 = 0 v_closed_y3 = 0 v_open_x0 = 0 v_open_y0 = 0 v_open_x1 = 0 v_open_y1 = 0 v_open_x2 = 0 v_open_y2 = 0 v_open_x3 = 0 v_open_y3 = 0 STR_VAR source_open_pvrz = "" source_closed_pvrz = "" target_tis = "" target_wed = "" target_are = "" door_name = "" door_id = "" RET open_pvrz closed_pvrz BEGIN // There are 2 versions of the door, opened and closed // Copy their respective PVRZ (source graphic) files to the override folder using // names that can be associated with the target TIS file (if necessary) LAF COPY_PVRZ_FILE_TO_OVERRIDE STR_VAR tis_file = EVAL ~%target_tis%~ source_pvrz = EVAL ~%source_open_pvrz%~ RET open_pvrz = pvrz_file open_pvrz_page = pvrz_suffix END ACTION_IF (~%source_closed_pvrz%~ STRING_EQUAL ~%source_open_pvrz%~) = 1 BEGIN // Open and closed day sources are the same file OUTER_SPRINT closed_pvrz ~%open_pvrz%~ OUTER_SPRINT closed_pvrz_page ~%open_pvrz_page%~ END ELSE BEGIN LAF COPY_PVRZ_FILE_TO_OVERRIDE STR_VAR tis_file = EVAL ~%target_tis%~ source_pvrz = EVAL ~%source_closed_pvrz%~ RET closed_pvrz = pvrz_file closed_pvrz_page = pvrz_suffix END END // Update the target TIS file COPY_EXISTING ~%target_tis%.tis~ ~override~ // Will need to know where the closed tiles were added in order to update the WED READ_LONG 0x0008 new_closed_tile // The count of the current tiles will be the index to the new one PATCH_IF (STRING_LENGTH ~%closed_pvrz%~ > 1) BEGIN // Add closed door tiles to end of TIS first LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%closed_pvrz_page%" PVRz_X = "%g_closed_x1%" PVRz_Y = "%g_closed_y1%" STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%closed_pvrz_page%" PVRz_X = "%g_closed_x2%" PVRz_Y = "%g_closed_y1%" STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%closed_pvrz_page%" PVRz_X = "%g_closed_x1%" PVRz_Y = "%g_closed_y2%" STR_VAR Method = "Push" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 PVRz_Page = "%closed_pvrz_page%" PVRz_X = "%g_closed_x2%" PVRz_Y = "%g_closed_y2%" STR_VAR Method = "Push" RET Count END END PATCH_IF (STRING_LENGTH ~%open_pvrz%~ > 1) BEGIN // These replace tiles currently in the file LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 Pos = "%t_open_pos1%" PVRz_Page = "%open_pvrz_page%" PVRz_X = "%g_open_x1%" PVRz_Y = "%g_open_y1%" STR_VAR Method = "Replace" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 Pos = "%t_open_pos2%" PVRz_Page = "%open_pvrz_page%" PVRz_X = "%g_open_x2%" PVRz_Y = "%g_open_y1%" STR_VAR Method = "Replace" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 Pos = "%t_open_pos3%" PVRz_Page = "%open_pvrz_page%" PVRz_X = "%g_open_x1%" PVRz_Y = "%g_open_y2%" STR_VAR Method = "Replace" RET Count END LPF ps_tileset_add_tiles INT_VAR MaxCount = 1 Pos = "%t_open_pos4%" PVRz_Page = "%open_pvrz_page%" PVRz_X = "%g_open_x2%" PVRz_Y = "%g_open_y2%" STR_VAR Method = "Replace" RET Count END END BUT_ONLY_IF_IT_CHANGES // WED file changes COPY_EXISTING ~%target_wed%.WED~ ~override~ LPF ADD_WED_DOOR INT_VAR v_open_x0 = %v_open_x0% // X/Y pairs (vertices) of the actual door object - only allowing 4 per door state v_open_y0 = %v_open_y0% // Must be given in clockwise order starting with the one furthest to the right v_open_x1 = %v_open_x1% // Start with the lowest if two are tied for the rightmost v_open_y1 = %v_open_y1% v_open_x2 = %v_open_x2% v_open_y2 = %v_open_y2% v_open_x3 = %v_open_x3% v_open_y3 = %v_open_y3% v_closed_x0 = %v_closed_x0% v_closed_y0 = %v_closed_y0% v_closed_x1 = %v_closed_x1% v_closed_y1 = %v_closed_y1% v_closed_x2 = %v_closed_x2% v_closed_y2 = %v_closed_y2% v_closed_x3 = %v_closed_x3% v_closed_y3 = %v_closed_y3% t_open_pos1 = %t_open_pos1% // The tile # in the target TIS that was replaced t_open_pos2 = %t_open_pos2% t_open_pos3 = %t_open_pos3% t_open_pos4 = %t_open_pos4% t_closed_pos1 = %new_closed_tile% // The tile # of the first new closed graphic that was added to the target TIS ... rest are sequential STR_VAR door_id = EVAL ~%door_id%~ // Called name in NI, but it's the ID used in the ARE file END BUT_ONLY_IF_IT_CHANGES // I'm just putting it in to connect it to the WED // Any details like scripts, flags, travel regions, keys, etc will have to be done elsewhere ACTION_IF is_day = 1 BEGIN COPY_EXISTING ~%target_are%.ARE~ ~override~ // Set defaults SET door_cursor = 30 // Calculate the min/max x/y for both open/closed LPF GET_BOUNDING_BOX INT_VAR v_x0 = %v_open_x0% v_y0 = %v_open_y0% v_x1 = %v_open_x1% v_y1 = %v_open_y1% v_x2 = %v_open_x2% v_y2 = %v_open_y2% v_x3 = %v_open_x3% v_y3 = %v_open_y3% RET min_open_x = min_x max_open_x = max_x min_open_y = min_y max_open_y = max_y END LPF GET_BOUNDING_BOX INT_VAR v_x0 = %v_closed_x0% v_y0 = %v_closed_y0% v_x1 = %v_closed_x1% v_y1 = %v_closed_y1% v_x2 = %v_closed_x2% v_y2 = %v_closed_y2% v_x3 = %v_closed_x3% v_y3 = %v_closed_y3% RET min_closed_x = min_x max_closed_x = max_x min_closed_y = min_y max_closed_y = max_y END LPF fj_are_structure INT_VAR fj_open_box_left = min_open_x fj_open_box_top = min_open_y fj_open_box_right = max_open_x fj_open_box_bottom = max_open_y fj_closed_box_left = min_closed_x fj_closed_box_top = min_closed_y fj_closed_box_right = max_closed_x fj_closed_box_bottom = max_closed_y fj_cursor_idx = door_cursor fj_door_open_vert_0 = v_open_x0 + (v_open_y0 << 16) fj_door_open_vert_1 = v_open_x1 + (v_open_y1 << 16) fj_door_open_vert_2 = v_open_x2 + (v_open_y2 << 16) fj_door_open_vert_3 = v_open_x3 + (v_open_y3 << 16) fj_door_closed_vert_0 = v_closed_x0 + (v_closed_y0 << 16) fj_door_closed_vert_1 = v_closed_x1 + (v_closed_y1 << 16) fj_door_closed_vert_2 = v_closed_x2 + (v_closed_y2 << 16) fj_door_closed_vert_3 = v_closed_x3 + (v_closed_y3 << 16) STR_VAR fj_structure_type = ~door~ fj_name = EVAL ~%door_name%~ fj_door_wed_id = EVAL ~%door_id%~ END BUT_ONLY_IF_IT_CHANGES END END //////////////////////////////////////////////////// // Gets the name of the PVRz file and copies it // // to the override folder if it's new // // Returns the name of the PVRz file as well // // as it's associated parts (prefix and suffix) // // The PVRz file name is the TIS file name // // with the 2nd letter of the file name dropped // // and then a sequential number added as a suffix // //////////////////////////////////////////////////// DEFINE_ACTION_FUNCTION COPY_PVRZ_FILE_TO_OVERRIDE STR_VAR tis_file = ~~ // target tis file name without the extension source_pvrz = ~~ // source of the graphic without the extension RET pvrz_file pvrz_prefix pvrz_suffix BEGIN // Set default return values OUTER_SPRINT pvrz_file ~~ OUTER_SPRINT pvrz_prefix ~~ OUTER_SPRINT pvrz_suffix ~~ ACTION_IF (STRING_LENGTH ~%tis_file%~ > 1) BEGIN OUTER_INNER_PATCH_SAVE pvrz_prefix ~%tis_file%~ BEGIN DELETE_BYTES 1 1 END ACTION_IF ((~%source_pvrz%~ STRING_CONTAINS_REGEXP ~%pvrz_prefix%~) = 0) AND ((STRING_LENGTH ~%pvrz_prefix%~) = ((STRING_LENGTH ~%source_pvrz%~) - 2)) BEGIN // The source of the graphic is already one of the TIS file's PVRz files OUTER_INNER_PATCH_SAVE pvrz_suffix ~%source_pvrz%~ BEGIN DELETE_BYTES 0 ((STRING_LENGTH ~%source_pvrz%~) - 2) END OUTER_SPRINT pvrz_file ~%source_pvrz%~ END ELSE BEGIN // The source of the graphic will need to be copied to a new PVRz that can be associated with the TIS OUTER_SPRINT pvrz_suffix ~-1~ OUTER_SET file_ok = 0 OUTER_SET strt_idx = 0 ACTION_IF GAME_IS ~eet~ THEN BEGIN OUTER_SET strt_idx = 50 END OUTER_FOR (idx = strt_idx; idx < 99 && file_ok = 0; idx = idx + 1) BEGIN ACTION_IF idx < 10 THEN BEGIN OUTER_SPRINT pvrz_suffix ~0%idx%~ END ELSE BEGIN OUTER_SPRINT pvrz_suffix ~%idx%~ END ACTION_IF NOT FILE_EXISTS_IN_GAME ~%pvrz_prefix%%pvrz_suffix%.pvrz~ THEN BEGIN OUTER_SET file_ok = 1 OUTER_SPRINT pvrz_file ~%pvrz_prefix%%pvrz_suffix%~ COPY_EXISTING ~%source_pvrz%.PVRZ~ ~override\%pvrz_file%.pvrz~ END END END END END ///////////////////////////////////////////////////// // Determine the bounding box for polygon vertices // // Expects there to be four // ///////////////////////////////////////////////////// DEFINE_PATCH_FUNCTION GET_BOUNDING_BOX INT_VAR v_x0 = 0 v_y0 = 0 v_x1 = 0 v_y1 = 0 v_x2 = 0 v_y2 = 0 v_x3 = 0 v_y3 = 0 RET min_x max_x min_y max_y BEGIN SET min_x = v_x0 SET max_x = v_x0 SET min_y = v_y0 SET max_y = v_y0 // Calculate the min/max x/y PATCH_IF v_x1 < min_x BEGIN SET min_x = v_x1 END PATCH_IF v_x2 < min_x BEGIN SET min_x = v_x2 END PATCH_IF v_x3 < min_x BEGIN SET min_x = v_x3 END PATCH_IF v_x1 > max_x BEGIN SET max_x = v_x1 END PATCH_IF v_x2 > max_x BEGIN SET max_x = v_x2 END PATCH_IF v_x3 > max_x BEGIN SET max_x = v_x3 END PATCH_IF v_y1 < min_y BEGIN SET min_y = v_y1 END PATCH_IF v_y2 < min_y BEGIN SET min_y = v_y2 END PATCH_IF v_y3 < min_y BEGIN SET min_y = v_y3 END PATCH_IF v_y1 > max_y BEGIN SET max_y = v_y1 END PATCH_IF v_y2 > max_y BEGIN SET max_y = v_y2 END PATCH_IF v_y3 > max_y BEGIN SET max_y = v_y3 END END ////////////////////////////////////////// // ADD A DOOR TO THE WED FILE // // It'll be easier to insert bytes at // // the proper places starting from // // the bottom of the file, recalc all // // the offsets, then add objects that // // reference those offsets. // // Those sections that don't reference // // offsets can be written right away. // ////////////////////////////////////////// DEFINE_PATCH_FUNCTION ADD_WED_DOOR INT_VAR v_open_x0 = 0 // X/Y pairs (vertices) of the actual door object - only allowing 4 per door state v_open_y0 = 0 // Must be given in clockwise order starting with the one furthest to the right v_open_x1 = 0 // Start with the lowest if two are tied for the rightmost v_open_y1 = 0 v_open_x2 = 0 v_open_y2 = 0 v_open_x3 = 0 v_open_y3 = 0 v_closed_x0 = 0 v_closed_y0 = 0 v_closed_x1 = 0 v_closed_y1 = 0 v_closed_x2 = 0 v_closed_y2 = 0 v_closed_x3 = 0 v_closed_y3 = 0 t_open_pos1 = 0 // The tile # in the target TIS that was replaced (closed were added to the end of the file, not replaced) t_open_pos2 = 0 t_open_pos3 = 0 t_open_pos4 = 0 t_closed_pos1 = 0 // The tile # of the first new closed graphic that was added to the target TIS ... rest are sequential STR_VAR door_id = "" // Called name in NI, but it's the ID used in the ARE file BEGIN /////////////////////////////////////////// // Read in offsets and counts from the headers /////////////////////////////////////////// READ_LONG 0x0008 num_overlays READ_LONG 0x000c num_doors READ_LONG 0x0010 offset_overlays READ_LONG 0x0014 offset_header2 READ_LONG 0x0018 offset_doors READ_LONG 0x001c offset_door_tile_cells READ_LONG (offset_header2) num_polygons READ_LONG (offset_header2 + 0x0004) offset_polygons READ_LONG (offset_header2 + 0x0008) offset_vertices READ_LONG (offset_header2 + 0x000c) offset_wallgroups READ_LONG (offset_header2 + 0x0010) offset_polygon_indices READ_LONG (offset_overlays + 0x0010) offset_overlay_tilemap // if it's not the first overlay - this will need to change /////////////////////////////////////////// // Set up the size of objects /////////////////////////////////////////// SET size_overlay = 0x0018 SET size_door = 0x001a SET size_tilemap = 0x000a SET size_door_tile_cell = 0x0002 SET size_polygon = 0x0012 SET size_index = 0x0002 SET size_vertex = 0x0004 // X,Y ////////////////////////////////// // // // ******** VERTICES ******** // // // ////////////////////////////////// // Only allowing for 8 new vertices, 4 for the open door and 4 for the closed SET new_vertices_open = 4 SET new_vertices_closed = 4 // New vertices can just be added at the end of the file (hopefully) // We'll add the open ones first then the closed ones SET new_open_vertices_offset = SOURCE_SIZE SET new_closed_vertices_offset = new_open_vertices_offset + (new_vertices_open * size_vertex) // Insert bytes at the end of the file for our new vertices INSERT_BYTES new_open_vertices_offset (size_vertex * (new_vertices_open + new_vertices_closed)) // Add the vertices to our new vertices section // These define the door polygons WRITE_SHORT new_open_vertices_offset %v_open_x0% WRITE_SHORT (new_open_vertices_offset + 0x0002) %v_open_y0% WRITE_SHORT (new_open_vertices_offset + 0x0004) %v_open_x1% WRITE_SHORT (new_open_vertices_offset + 0x0006) %v_open_y1% WRITE_SHORT (new_open_vertices_offset + 0x0008) %v_open_x2% WRITE_SHORT (new_open_vertices_offset + 0x000a) %v_open_y2% WRITE_SHORT (new_open_vertices_offset + 0x000c) %v_open_x3% WRITE_SHORT (new_open_vertices_offset + 0x000e) %v_open_y3% WRITE_SHORT new_closed_vertices_offset %v_closed_x0% WRITE_SHORT (new_closed_vertices_offset + 0x0002) %v_closed_y0% WRITE_SHORT (new_closed_vertices_offset + 0x0004) %v_closed_x1% WRITE_SHORT (new_closed_vertices_offset + 0x0006) %v_closed_y1% WRITE_SHORT (new_closed_vertices_offset + 0x0008) %v_closed_x2% WRITE_SHORT (new_closed_vertices_offset + 0x000a) %v_closed_y2% WRITE_SHORT (new_closed_vertices_offset + 0x000c) %v_closed_x3% WRITE_SHORT (new_closed_vertices_offset + 0x000e) %v_closed_y3% //////////////////////////////////////////////////// // // // ******** POLYGON INDEX LOOKUP TABLE ******** // // // //////////////////////////////////////////////////// // I think this is only used for walls - not doors ////////////////////////////////// // // // ******** POLYGONS ******** // // // ////////////////////////////////// // Need to add polygons for both open and closed doors in the polygon section // the offset to and count of these will be added to the door object // only allowing for 1 open and 1 closed polygon at the moment SET new_polygons_open = 1 SET new_polygons_closed = 1 SET new_open_polygon_flags = 129 // Shade wall + door SET new_closed_polygon_flags = 129 // New entries will go at the bottom of the current section SET new_polygons_open_offset = offset_polygons + (num_polygons * size_polygon) SET new_polygons_closed_offset = new_polygons_open_offset + (new_polygons_open * size_polygon) // Determine the next vertex index to use READ_LONG (offset_polygons + ((num_polygons - 1) * size_polygon)) last_vertex_index READ_LONG (offset_polygons + ((num_polygons - 1) * size_polygon) + 0x0004) num_last_vertices_used SET new_vertex_index = last_vertex_index + num_last_vertices_used // Calculate the min/max x/y for both open/closed LPF GET_BOUNDING_BOX INT_VAR v_x0 = %v_open_x0% v_y0 = %v_open_y0% v_x1 = %v_open_x1% v_y1 = %v_open_y1% v_x2 = %v_open_x2% v_y2 = %v_open_y2% v_x3 = %v_open_x3% v_y3 = %v_open_y3% RET min_open_x = min_x max_open_x = max_x min_open_y = min_y max_open_y = max_y END LPF GET_BOUNDING_BOX INT_VAR v_x0 = %v_closed_x0% v_y0 = %v_closed_y0% v_x1 = %v_closed_x1% v_y1 = %v_closed_y1% v_x2 = %v_closed_x2% v_y2 = %v_closed_y2% v_x3 = %v_closed_x3% v_y3 = %v_closed_y3% RET min_closed_x = min_x max_closed_x = max_x min_closed_y = min_y max_closed_y = max_y END // Insert bytes at the end of the current section for our new polygons INSERT_BYTES new_polygons_open_offset (size_polygon * (new_polygons_open + new_polygons_closed)) // Can add polygons now since they only reference indices, not offsets WRITE_LONG new_polygons_open_offset %new_vertex_index% WRITE_LONG (new_polygons_open_offset + 0x0004) %new_vertices_open% WRITE_BYTE (new_polygons_open_offset + 0x0008) %new_open_polygon_flags% WRITE_BYTE (new_polygons_open_offset + 0x0009) 0xff WRITE_SHORT (new_polygons_open_offset + 0x000a) %min_open_x% WRITE_SHORT (new_polygons_open_offset + 0x000c) %max_open_x% WRITE_SHORT (new_polygons_open_offset + 0x000e) %min_open_y% WRITE_SHORT (new_polygons_open_offset + 0x0010) %max_open_y% WRITE_LONG new_polygons_closed_offset (%new_vertex_index% + %new_vertices_open%) WRITE_LONG (new_polygons_closed_offset + 0x0004) %new_vertices_closed% WRITE_BYTE (new_polygons_closed_offset + 0x0008) %new_closed_polygon_flags% WRITE_BYTE (new_polygons_closed_offset + 0x0009) 0xff WRITE_SHORT (new_polygons_closed_offset + 0x000a) %min_closed_x% WRITE_SHORT (new_polygons_closed_offset + 0x000c) %max_closed_x% WRITE_SHORT (new_polygons_closed_offset + 0x000e) %min_closed_y% WRITE_SHORT (new_polygons_closed_offset + 0x0010) %max_closed_y% ///////////////////////////////////// // // // ******** WALL GROUPS ******** // // // ///////////////////////////////////// // I don't think I need to do anything here ///////////////////////////////////////////////// // // // ******** TILE INDEX LOOKUP TABLE ******** // // // ///////////////////////////////////////////////// // I don't think I need to do anything with these ///////////////////////////////////////// // // // ******** DOOR TILE CELLS ******** // // // ///////////////////////////////////////// // Need to add 4 entries into this table for the 4 graphic tiles used by the open door // It'll point to tiles defined in the Tile Map Structure and will also associate them with their closed graphics SET new_door_tile_cells = 4 // Find the last tilemap index to calculate the next and determine the offset to the next SET last_door_tile_index = 0 SET last_door_tile_count = 0 PATCH_IF num_doors > 0 BEGIN SET last_door_offset = offset_doors + ((num_doors - 1) * size_door) READ_SHORT (last_door_offset + 0x000a) last_door_tile_index READ_SHORT (last_door_offset + 0x000c) last_door_tile_count END SET new_door_tile_index = (last_door_tile_index + last_door_tile_count) // Calculate where the new door tile cells are inserted SET new_door_tile_cell_offset = offset_door_tile_cells + (new_door_tile_index * size_door_tile_cell) // Insert bytes at the end of the current section for our new door tile cells INSERT_BYTES new_door_tile_cell_offset (size_door_tile_cell * new_door_tile_cells) // Door tile cells only reference indices, not offsets, so we can add them right away WRITE_SHORT new_door_tile_cell_offset %t_open_pos1% WRITE_SHORT (new_door_tile_cell_offset + size_door_tile_cell) %t_open_pos2% WRITE_SHORT (new_door_tile_cell_offset + (2 * size_door_tile_cell)) %t_open_pos3% WRITE_SHORT (new_door_tile_cell_offset + (3 * size_door_tile_cell)) %t_open_pos4% ///////////////////////////////////////////// // // // ******** TILE MAP STRUCTURES ******** // // // ///////////////////////////////////////////// // Need to find and update the tiles associated with the open door // and update their secondary values to point to the new closed door graphics WRITE_SHORT (offset_overlay_tilemap + (t_open_pos1 * size_tilemap) + 0x0004) %t_closed_pos1% WRITE_SHORT (offset_overlay_tilemap + (t_open_pos2 * size_tilemap) + 0x0004) (%t_closed_pos1% + 1) WRITE_SHORT (offset_overlay_tilemap + (t_open_pos3 * size_tilemap) + 0x0004) (%t_closed_pos1% + 2) WRITE_SHORT (offset_overlay_tilemap + (t_open_pos4 * size_tilemap) + 0x0004) (%t_closed_pos1% + 3) /////////////////////////////// // // // ******** DOORS ******** // // // /////////////////////////////// // Calculate the start of our new door object SET new_door_offset = offset_doors + (num_doors * size_door) // Only allowing for 4 door tiles (per state) at the moment // Only the open ones need to be linked to the door structure SET new_tilemap_tiles = 4 // Insert bytes at the start of our new door section INSERT_BYTES new_door_offset size_door // Write the door section after all offsets are updated ///////////////////////////////////////////// // // // ******** RECALCULATE OFFSETS ******** // // // ///////////////////////////////////////////// SET add_size = size_door SET offset_door_tile_cells = offset_door_tile_cells + add_size SET add_size = add_size + (size_door_tile_cell * new_door_tile_cells) SET offset_wallgroups = offset_wallgroups + add_size SET offset_polygons = offset_polygons + add_size SET new_polygons_open_offset = new_polygons_open_offset + add_size SET new_polygons_closed_offset = new_polygons_open_offset + (size_polygon * new_polygons_open) SET add_size = add_size + (size_polygon * (new_polygons_open + new_polygons_closed)) SET offset_polygon_indices = offset_polygon_indices + add_size SET offset_vertices = offset_vertices + add_size SET new_open_vertices_offset = new_open_vertices_offset + add_size SET new_closed_vertices_offset = new_closed_vertices_offset + add_size /////////////////////////////////////////////////////////////// // // // ******** WRITE TO SECTIONS REFERENCING OFFSETS ******** // // // /////////////////////////////////////////////////////////////// // VERTICES - already written // POLYGON INDEX LOOKUP TABLE - no changes // POLYGONS - already written // WALL GROUPS - no changes // TILE INDEX LOOKUP TABLE - no changes // DOOR TILE CELLS - already written // TILE MAP STRUCTURES - already written // DOORS WRITE_ASCIIE new_door_offset ~%door_id%~ (8) WRITE_SHORT (new_door_offset + 0x0008) 1 // Is door? WRITE_SHORT (new_door_offset + 0x000a) %new_door_tile_index% WRITE_SHORT (new_door_offset + 0x000c) %new_tilemap_tiles% WRITE_SHORT (new_door_offset + 0x000e) %new_polygons_open% WRITE_SHORT (new_door_offset + 0x0010) %new_polygons_closed% WRITE_LONG (new_door_offset + 0x0012) %new_polygons_open_offset% WRITE_LONG (new_door_offset + 0x0016) %new_polygons_closed_offset% // SECONDARY HEADER WRITE_LONG (offset_header2) (num_polygons + new_polygons_open + new_polygons_closed) WRITE_LONG (offset_header2 + 0x0004) %offset_polygons% WRITE_LONG (offset_header2 + 0x0008) %offset_vertices% WRITE_LONG (offset_header2 + 0x000c) %offset_wallgroups% WRITE_LONG (offset_header2 + 0x0010) %offset_polygon_indices% // OVERLAYS - offset to this section doesn't change // Update offsets to tilemaps and tile index lookups referenced by the overlays FOR (idx = 0; idx < num_overlays; idx = idx + 1) BEGIN READ_LONG (offset_overlays + (idx * size_overlay) + 0x0010) offset_overlay_tilemap READ_LONG (offset_overlays + (idx * size_overlay) + 0x0014) offset_overlay_tile_lookup SET add_size = size_door SET new_offset_overlay_tilemap = offset_overlay_tilemap + add_size SET add_size = add_size + (new_door_tile_cells * size_door_tile_cell) SET new_offset_overlay_tile_lookup = offset_overlay_tile_lookup + add_size WRITE_LONG (offset_overlays + (idx * size_overlay) + 0x0010) %new_offset_overlay_tilemap% WRITE_LONG (offset_overlays + (idx * size_overlay) + 0x0014) %new_offset_overlay_tile_lookup% END // HEADER // Update the header section with new number of doors and offset to door tile cell indices WRITE_LONG (0x000c) (num_doors + 1) WRITE_LONG (0x001c) %offset_door_tile_cells% END It's called like this: Spoiler // Add a door to the PC's residence in the SoD areas // Will take the graphic for the open door from the BG1 area PVRz files // There are 4 versions of every exterior door - open and closed during the day and night OUTER_SPRINT open_source_day "A020008" OUTER_SPRINT open_source_night "A0200N08" OUTER_SPRINT closed_source_day "B001000" OUTER_SPRINT closed_source_night "B0010N00" ACTION_IF GAME_IS ~eet~ THEN BEGIN OUTER_SPRINT open_source_day "B020008" OUTER_SPRINT open_source_night "B0200N08" OUTER_SPRINT closed_source_day "B001050" OUTER_SPRINT closed_source_night "B0010N50" END // Daytime door LAF ADD_DOOR INT_VAR is_day = 1 g_closed_x1 = 0 // X,Y coordinates from within the source PVRz file g_closed_x2 = 64 g_closed_y1 = 448 g_closed_y2 = 512 g_open_x1 = 128 g_open_x2 = 192 g_open_y1 = 704 g_open_y2 = 768 t_open_pos1 = 140 // The tile # in the target TIS to be replaced t_open_pos2 = 141 t_open_pos3 = 160 t_open_pos4 = 161 v_closed_x0 = 39 // X/Y pairs (vertices) of the actual door object - only allowing 4 per door state v_closed_y0 = 524 // Must be given in clockwise order starting with the one furthest to the right v_closed_x1 = 87 // If 2 tie for rightmost - use the lower of the two v_closed_y1 = 535 v_closed_x2 = 87 v_closed_y2 = 469 v_closed_x3 = 39 v_closed_y3 = 457 v_open_x0 = 16 v_open_y0 = 553 v_open_x1 = 39 v_open_y1 = 552 v_open_x2 = 39 v_open_y2 = 455 v_open_x3 = 16 v_open_y3 = 484 STR_VAR source_open_pvrz = EVAL "%open_source_day%" source_closed_pvrz = EVAL "%closed_source_day%" target_tis = ~BD0010~ target_wed = ~BD0010~ target_are = ~BD0010~ door_name = "Port0006" door_id = "door0006" RET pvrzOpenDay = open_pvrz pvrzClosedDay = closed_pvrz END // Nighttime door LAF ADD_DOOR INT_VAR is_day = 0 g_closed_x1 = 0 // X,Y coordinates from within the source PVRz file (use DLTCEP to determine) g_closed_x2 = 64 g_closed_y1 = 448 g_closed_y2 = 512 g_open_x1 = 128 g_open_x2 = 192 g_open_y1 = 704 g_open_y2 = 768 t_open_pos1 = 140 // The tile # in the target TIS to be replaced t_open_pos2 = 141 t_open_pos3 = 160 t_open_pos4 = 161 v_closed_x0 = 39 // X/Y pairs (vertices) of the actual door object - only allowing 4 per door state v_closed_y0 = 524 // Must be given in clockwise order starting with the one furthest to the right v_closed_x1 = 87 // If 2 tie for rightmost - use the lower of the two v_closed_y1 = 535 v_closed_x2 = 87 v_closed_y2 = 469 v_closed_x3 = 39 v_closed_y3 = 457 v_open_x0 = 16 v_open_y0 = 553 v_open_x1 = 39 v_open_y1 = 552 v_open_x2 = 39 v_open_y2 = 455 v_open_x3 = 16 v_open_y3 = 484 STR_VAR source_open_pvrz = EVAL "%open_source_night%" source_closed_pvrz = EVAL "%closed_source_night%" target_tis = ~BD0010N~ target_wed = ~BD0010N~ target_are = ~BD0010~ door_name = "Port0006" door_id = "door0006" RET pvrzOpenNight = open_pvrz pvrzClosedNight = closed_pvrz END Edited October 5, 2021 by Lauriel Removed redundant code and fixed a comment Quote
jastey Posted October 5, 2021 Posted October 5, 2021 @Lauriel Wow! I'd suggest also posting this into here. Quote
Lauriel Posted October 5, 2021 Posted October 5, 2021 Just now, jastey said: @Lauriel Wow! I'd suggest also posting this into here. Okie dokes. Quote
Recommended Posts
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.