Jump to content

Lauriel

Modders
  • Posts

    940
  • Joined

  • Last visited

Posts posted by Lauriel

  1. 1 hour ago, jastey said:

    Did you experience this ingame? Because there is a !AreaCheck("bd6200") in there to prevent that.

    Yeah, in a custom area...but I don't think I'll be doing it that way in the future.  So it's probably ok, and if it's not I'll just add the bd_plot check myself if it's required. S'ok.

  2. Current bug - from Github:

    Spoiler
    Quote
    /* join-up after leaving the group */
    IF WEIGHT #-1
    ~!AreaCheck("bd6200")
    !InParty(Myself)
    Global("bd_joined","locals",0)
    GlobalGT("bd_plot","GLOBAL",54)~ THEN join_again  <=====NEED TO PUT AN UPPER LIMIT ON THIS LIKE 590 or something
      SAY #%63958% /* ~Heya, how are things going?~ */
      ++ #%16414% /* ~Sorry to have kept you waiting. Let's get going.~ */ + kickout_4
      ++ #%16413% /* ~Sorry, kiddo, but I don't need your company just yet.~ */ + kickout_3
    END

     

     

    Because there's no upper limit on bd_plot when Imoen begins a dialogue when not in the group, she will muck up the ending of SoD ... when the PC meets her after leaving the sewer

  3. While browsing BD1000.BCS in NI, I discovered an invalid dialogue file name.

    Code Block:

    Spoiler
    IF
    	Global("C#IM_ImoenRejoinsbd1000","GLOBAL",4)
    	!Dead("IMOEN2")  // Imoen
    	!InPartyAllowDead("IMOEN2")  // Imoen
    THEN
    	RESPONSE #100
    		SetGlobal("C#IM_ImoenRejoinsbd1000","GLOBAL",5)
    		MoveGlobal("bd1000","IMOEN2",[470.3737])  // Imoen
    		ActionOverride("IMOEN2",Face(N))
    		ReallyForceSpellDeadRES("bdrejuve","IMOEN2")  // No such index
    		ChangeEnemyAlly("IMOEN2",NEUTRAL)  // Imoen
    		ChangeSpecifics("IMOEN2",ALLIES)  // Imoen
    		ActionOverride("IMOEN2",SetGlobal("bd_joined","locals",0))
    		ActionOverride("IMOEN2",SetGlobal("bd_retreat","locals",0))
    		ActionOverride("IMOEN2",SaveObjectLocation("LOCALS","bd_default_loc",Myself))
    		ActionOverride("IMOEN2",ChangeAIScript("BDIMOENS",OVERRIDE))
    		ActionOverride("IMOEN2",ChangeAIScript("bdasc3",CLASS))
    		ActionOverride("IMOEN2",ChangeAIScript("BDSHOUT",RACE))
    		ActionOverride("IMOEN2",ChangeAIScript("",GENERAL))
    		ActionOverride("IMOEN2",ChangeAIScript("",DEFAULT))
    		ActionOverride("IMOEN2",SetDialog("BDIMOENP"))         <================bad file name
    		Continue()
    END

     

     

  4. I did install it after EET core this time instead of in with BG1.  But it said it was EET compatible now.  Its trigger includes a check to make sure EndOfBG1 < 2, so it appears to purposely also work in SoD. That would probably be the only fix needed.

  5. Dynaheir gets stuck in a dialogue loop in SoD if Edwin joins the group.  She wants to get to the state which says "Thou invite this snake to join us, <CHARNAME>? Hast thou taken leave of thy senses?" but is sidetracked by the state which says "*You find Dynaheir on her own and in a quiet mood; for once, she is not sorting her scrolls or discussing things in a low voice with one of your companions. Perhaps it would be wise to take advantage of the situation and chat with the mysterious Wychlaran.*"

    I think a weight on the former's trigger is in order.

  6. There are a number of offsets listed in the ARE file that point to undefined sections.  For example, "Offset to CRE structure (for embedded CRE files)" in the ACTORS sections.  

    Are these offsets to sections in the ARE file or is it understood that these sections are to be found in other files?  I really hope the latter isn't the case...  Are they defined but under a different name?

    List of undefined sections reference by offsets in the ARE file:
        ACTORS => 0x0088 => Offset to CRE structure (for embedded CRE files)
        TILED OBJECTS => 0x002c => Offset to open search squares
        TILED OBJECTS => 0x0038 => Offset to closed search squares
        PROJECTILE TRAPS (BG2) => 0x0008 => Effect block offset

    EDIT: Are these only used by save games?

  7. 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

     

     

  8. 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

     

     

  9. From the IESDP for this section:

    Quote

     

    The 'tile map' structures reference indices into this table. The 'tile counts' in the tilemap table are counts of indices in this table. This maps tile indices from the WED tile indices into the appropriate tile indices for the particular tileset file which the overlay in question references. Each element in this array is a little-endian 16-bit word.

    I've never used little-endians.  Do I have to muck about with the order of bits to write the correct value or is there notation (like hex) to say - put this in little-fellaendian notation. Or ... what?

    Or is this some sort of (start, count) pair of ... something.

     

    EDIT: Never mind - I don't think I need to add to this table when adding a door.

  10. Oh, I've seen this...something you installed mucked about with the trigger table so now those triggers are no longer valid when they should be.


    To quote @tipun from another thread...

    On 9/5/2021 at 7:10 PM, tipun said:

    I think there is a mod ... that has poor EE compatibility (or not compatibility at all). And it replaces the trigger.ids file. Therefore, EET_end cannot find the triggers it needs.

×
×
  • Create New...