/*=========================================================================== *
 *                                                                            *
 *        F U N C T I O N S   &   M A C R O S   :   W E D   F I L E S         *
 *                                                                            *
 *=========================================================================== */

/* =============================================================================================================================================================================== *
   OVERALL FUNCTIONS and MACROS :
   ------------------------------
   Note :	Toutes ces fonctions sont expérimentales (all these functions are in experimental stage).
   ------
	- FUNCTIONS GW_REINCLUDE						:	INTÉGRATION d'une sous-routine tp2 dans une routine (PATCH et ACTION).										=> line   50
														GENERATE and RUN an include WeiDU process (tp*) into another one (PATCH and ACTION).
	- FUNCTIONS TO_HEX_NUMBER						:	CONVERSION d'une valeur décimale en valeur hexadécimale en valeur décimale (PATCH et ACTION).				=> line   90
														CONVERTS any decimal number into a hexadecimal number (PATCH and ACTION).
	- MACRO GW_DEF_WED_OFFSETS						:	DÉFINITION des offsets généraux des fichiers WED.															=> line  155
														LOAD the main offsets used to patch WED files.
	- FUNCTION GW_READ_WED_STRUCTURE				:	LECTURE des valeurs des offsets généraux d'un fichier WED.													=> line  230
														READ the values of the main offsets in a WED file.
	- MACRO GW_READ_WED_DOOR_STRUCTURE				:	LECTURE des valeurs des offsets utilisés pour modifier une porte dans un fichier WED.						=> line  294
														READ the values of the main offsets used to patch a door in a WED file.
	- FUNCTION GW_READ_OVERLAY_STRUCTURE			:	LECTURE des valeurs des offsets utilisés pour modifier un overlay dans un fichier WED.						=> line  321
														READ the values of the main offsets used to patch an overlay in a WED file.
	- MACRO GW_READ_WED_POLYGON_STRUCTURE			:	LECTURE des valeurs des offsets utilisés pour lire/modifier un polygone dans un fichier WED.				=> line  352
														READ the values of the main offsets used to patch a polygon in a WED file.
	FUNCTIONS and MACROS REPLACING DOORS INTO A WED FILE :
   -------------------------------------------------------
	- MACRO GW_DRAW_WED_WALLGROUPS						:	DÉFINITION des wall groups (nombre et aires) d'un fichier WED.											=> line  382
															CALCULATE the wall groups (number and bounding box) included in a WED file.
	- FUNCTION GW_CALCULATE_POLYGON_BOUNDING_BOX		:	CALCUL automatiquement la bounding box d'un polygone.													=> line  420
															Automatically CALCULATE a polygon bounding box.
	- FUNCTION GW_ADD_WED_DOOR							:	AJOUTE ou MODIFIE une porte dans un fichier WED.														=> line  457
															ADD or ALTER a door in a WED file.
	- FUNCTION GW_FIX_POLYGONS_IN_WALLGROUPS			:	MISE À JOUR des tables des wall groups et des wall polygon index d'un fichier WED.						=> line  708
															UPDATE the wall groups and wall polygon index tables in a WED file.
	- FUNCTION GW_BUILD_WALLGROUP_POLYGONS_INDEX_LIST	:	CONSTRUCTION de la table des index de polygones des wall groups d'un fichier WED.						=> line  874
															BUILD the wall polygon index tables of a WED file.
	- FUNCTION GW_POLYGON_IN_WALLGROUP					:	DÉTERMINE dans quel wall group se trouve un polygone.													=> line  906
															FIND in which the wall group a polygon is set.
 * =============================================================================================================================================================================== */


/* ============================================================================ *
 *                                                                              *
 *          O V E R A L L    F U N C T I O N S    a n d    M A C R O S          *
 *                                                                              *
 * ============================================================================ */

/* ============================================================================================================= *
 * FUNCTIONS GW_REINCLUDE : INTÉGRATION d'une sous-routine tp2 dans une routine (PATCH et ACTION).               *
 *							GENERATE and RUN an include WeiDU process (tp*) into another one (PATCH and ACTION). *
 * ------------------------------------------------------------------------------------------------------------- *
 * Écrit la liste de commandes "input" dans un fichier temporaire, puis l'exécute automatiquement.               *
 * Write the commands lists 'input" into a temporary file, then run it.                                          *
 * ============================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_REINCLUDE~
	STR_VAR input = ""		// List of commands or functions to launch.
BEGIN

	PATCH_SILENT
	INNER_ACTION BEGIN
		<<<<<<<< temp_file
			%input%
		>>>>>>>>
		COPY - temp_file ~temp_file2~ EVALUATE_BUFFER
	END
	PATCH_REINCLUDE ~temp_file2~
	PATCH_VERBOSE

END	// of DEFINE_PATCH_FUNCTION


DEFINE_ACTION_FUNCTION ~GW_REINCLUDE~
	STR_VAR input = ""
BEGIN

	SILENT
	<<<<<<<< temp_file
		%input%
	>>>>>>>>
	COPY - temp_file ~temp_file2~ EVALUATE_BUFFER
	REINCLUDE ~temp_file2~
	VERBOSE

END	// of DEFINE_ACTION_FUNCTION


/* ====================================================================================================================== *
 * FUNCTION TO_HEX_NUMBER : CONVERSION d'une valeur décimale en valeur hexadécimale en valeur décimale (PATCH et ACTION). *
 *							CONVERTS any decimal number into a hexadecimal number (PATCH and ACTION).                     *
 * ---------------------------------------------------------------------------------------------------------------------- *
 * Piece of code borrowed from Argent77 and used for debugging purpose.                                                   *
 * ====================================================================================================================== */

DEFINE_ACTION_FUNCTION TO_HEX_NUMBER
	INT_VAR
		value     = 0	// the decimal number
		minDigits = 1	// min. number of digits in return value (not counting sign)
		prefix    = 0	// whether to return number with "0x" prefix
	RET
		hexNumber		// returned as string without prefix
BEGIN

	ACTION_IF (minDigits < 1) BEGIN OUTER_SET minDigits = 1 END
	ACTION_IF (minDigits > 8) BEGIN OUTER_SET minDigits = 8 END
	OUTER_TEXT_SPRINT hexNumber ~~
	ACTION_DEFINE_ARRAY digit BEGIN ~0~ ~1~ ~2~ ~3~ ~4~ ~5~ ~6~ ~7~ ~8~ ~9~ ~a~ ~b~ ~c~ ~d~ ~e~ ~f~ END

	ACTION_IF (value < 0) BEGIN
		OUTER_SET signed = 1
		OUTER_SET value = 0 - value
	END ELSE BEGIN
		OUTER_SET signed = 0
	END

	OUTER_WHILE (value != 0) BEGIN
		OUTER_SET curDigit = value BAND 0xf
		OUTER_SET value = value BLSR 4
		OUTER_TEXT_SPRINT hexDigit $EVAL digit(~%curDigit%~)
		OUTER_TEXT_SPRINT hexNumber ~%hexDigit%%hexNumber%~
	END

	OUTER_WHILE (STRING_LENGTH ~%hexNumber%~ < minDigits) BEGIN
		OUTER_TEXT_SPRINT hexNumber ~0%hexNumber%~
	END

	ACTION_IF (prefix) BEGIN
		OUTER_TEXT_SPRINT hexNumber ~0x%hexNumber%~
	END

	ACTION_IF (signed) BEGIN
		OUTER_TEXT_SPRINT hexNumber ~-%hexNumber%~
	END

END

DEFINE_PATCH_FUNCTION TO_HEX_NUMBER
	INT_VAR
		value     = 0
		minDigits = 1
		prefix    = 0
	RET
		hexNumber
BEGIN

	INNER_ACTION BEGIN
		LAF TO_HEX_NUMBER INT_VAR value = value minDigits = minDigits prefix = prefix RET hexNumber END
	END

END


/* ============================================================================ *
 * MACRO GW_DEF_WED_OFFSETS : DÉFINITION des offsets généraux des fichiers WED. *
 *							  LOADS the main offsets used to patch WED files.   *
 * ---------------------------------------------------------------------------- *
 * Lancée une seule fois avant de modifier un ou plusieurs fichiers wed.        *
 * Launched once before patching one or several wed files.                      *
 * ============================================================================ */

DEFINE_ACTION_MACRO ~GW_DEF_WED_OFFSETS~ 
BEGIN
// Section and file sizes
	OUTER_SET GW_wed_min_size			= 0x1f		// Wed minimum size
	OUTER_SET GW_wed_overlay_size		= 0x18		// Size of overlays section
	OUTER_SET GW_wed_door_size			= 0x1a		// Size of doors section
	OUTER_SET GW_wed_wallgroup_size		= 0x04		// Size of wallgroup section
	OUTER_SET GW_wed_polygon_size		= 0x12		// Size of polygons section
	OUTER_SET GW_wed_vertice_size		= 0x04		// Size of vertices section
	OUTER_SET GW_wall_polygon_index_size = 0x02		// Size of wall polygon index section
// Header
	OUTER_SET GW_numoverlays_of			= 0x0008	// Number of overlays (including the base layer)
	OUTER_SET GW_numdoors_of			= 0x000c	// Number of doors
	OUTER_SET GW_overlays_of			= 0x0010	// Offset (from start of file) to overlays
	OUTER_SET GW_2dheader_of			= 0x0014	// Offset (from start of file) to secondary header
	OUTER_SET GW_wed_doors_of			= 0x0018	// Offset (from start of file) to doors
	OUTER_SET GW_door_tilecell_of		= 0x001c	// Offset (from start of file) to door tile cell indices
// Overlays : Each overlay is mapped to a tileset. The sections of the area each overlay will cover is controlled by the tilemap section.
	OUTER_SET GW_overlay_width_of		= 0x0000	// Width (in tiles)
	OUTER_SET GW_overlay_height_of		= 0x0002	// Height (in tiles)
	OUTER_SET GW_overlay_tile_name_of	= 0x0004	// Name of tileset
	OUTER_SET GW_overlay_uniq_tile_c_of	= 0x000c	// Unique tile count
	OUTER_SET GW_overlay_movt_type_of	= 0x000e	// Movement type
	OUTER_SET GW_overlay_tilemap_of		= 0x0010	// Offset to tilemap for this overlay
	OUTER_SET GW_overay_lookup_table_of	= 0x0014	// Offset to tile index lookup for this overlay
// Secondary header : The "secondary header" contains more offsets, which would generally be found within the primary header. The secondary header and the extra information it contains was probably added due to incompatibilities between earlier internal versions of the WED format (V1.0, V1.1, and V1.2) and the current version.
	OUTER_SET GW_wall_poly_nb_of		= 0x0000	// Number of polygons used to represent walls
	OUTER_SET GW_polygons_of			= 0x0004	// Offset to polygons
	OUTER_SET GW_wed_vertices_of		= 0x0008	// Offset to vertices
	OUTER_SET GW_wallgroups_of			= 0x000c	// Offset to wall groups
	OUTER_SET GW_polygons_lookup_table_of = 0x0010	// Offset to polygon indices lookup table
// Doors : This section generally describes doors, though the concept can be extended to describe any object which acts like a door; i.e. has an open state and a closed state, and optionally blocks certain cells from being reached. The door tile cells for a given door are those cells which are impeded, and whose graphics change when this door is closed.
	OUTER_SET GW_door_name_of			= 0x0000	// Name of door (matched on in AREA file?)
	OUTER_SET GW_door_open_of			= 0x0008	// Open (0) / Closed (1)
	OUTER_SET GW_door_first_tile_of		= 0x000a	// First door tile cell index
	OUTER_SET GW_door_tiles_nb_of		= 0x000c	// Count of door tile cells for this door
	OUTER_SET GW_door_open_poly_nb_of	= 0x000e	// Count of polygons open state
	OUTER_SET GW_door_closed_poly_nb_of	= 0x0010	// Count of polygons closed state
	OUTER_SET GW_door_open_poly_of		= 0x0012	// Offset (from start of file) to polygons open state
	OUTER_SET GW_door_closed_poly_of	= 0x0016	// Offset (from start of file) to polygons closed state
// Tilemap structures : For each tile cell in a overlay, there is one tilemap structure. These structures tell us which tile(s) from the tileset resource are to be used for the given tile cell. Each tile cell must have one tileset resource; those which are referenced by the door tile cells of a door must have 2 - one for the open state, and one for the closed state. If a tile cell is animated it will use a range of tile indices from the tile indices lookup table.
	OUTER_SET GW_tilemap_lookup_table_of = 0x0000	// Start index in tile index lookup table of primary (default) tile
	OUTER_SET GW_tilemap_tile_nb_of		= 0x0002	// Count of tiles in tile index lookup table for primary (default) tile
	OUTER_SET GW_tilemap_alternate_of	= 0x0004	// Index from TIS file of secondary (alternate) tile (i.e. tile for closed state, if tile has an open/closed state) and also for overlays indication (tiles with marked overlay area, by "green" color)
	OUTER_SET GW_tilemap_byte_of		= 0x0006	// 1 (byte) = bit 0: Unused - bit 1: Draw overlay 1 - bit 2: Draw overlay 2 ... bit 7: Draw overlay 7
// Door tile cells : This is an array of indices into the tilemap array. Each door is associated with several elements of this array. When the open/closed state of the door is changed, the associated tiles represented by the elements in this array have their state toggled, i.e. the tile becomes (un)passable.
// Tile index lookup table : 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.
// Wall groups : Outlines of objects (specifically walls and doors) need to be stored in order to determine when to dither creature animations (to represent moving "behind" a wall). Outlines are stored as a series of ordered vertices, creating a polygon. Doors can be represented by more than one polygon in either their open or closed state - this allows for double doors. These wall groups are sets of indices in the polygon indices lookup table, which in turn points into the polygon table. One thing worth remembering is that one wall group has the following dimensions : 10 tiles * 7.5 tiles, thus all areas should have the according to the background overlay amount of wall groups sections stored here i.e. area with dimensions 80*60 tiles should have 64 wall groups.
	OUTER_SET GW_wallgroup_polygon_of	= 0x0000	// Start polygon index
	OUTER_SET GW_wallgroup_polygon_nb_of = 0x0002	// Polygon index count
// Polygons : A polygon consists of a list of vertices, a minimum bounding box and some unknown state information. The order of vertices can be important when describing polygons for doors wall, the vertices have to be listed clockwise, starting with the rightmost vertex first. If there are two or more vertex on the same rightmost vertical line, the lowest point should be listed first. For normal walls, the vertices can be listed in clockwise or anti-clockwise order, starting with the most lowest vertex.
	OUTER_SET GW_polygon_start_ind_of	= 0x0000	// Starting vertex index
	OUTER_SET GW_polygon_vertices_nb_of	= 0x0004	// Count of vertices
	OUTER_SET GW_polygon_flags_of		= 0x0008	// Indicates whether this polygon is a polygon or a hole (i.e. whether it is a section of impassability, or one of passability). The default behavior is that wall shades animations from both sides. ==> bit 0 : Shade wall - bit 1 : Hovering - bit 2 : Cover animations - bit 3 : Cover animations - bit 4 bit 5 bit 6 : Unknown - bit 7 : Door?
	OUTER_SET GW_polygon_height_of		= 0x0009	// Height
	OUTER_SET GW_polygon_box_left_of	= 0x000a	// Minimum X coordinate of bounding box
	OUTER_SET GW_polygon_box_right_of	= 0x000c	// Maximum X coordinate of bounding box
	OUTER_SET GW_polygon_box_top_of		= 0x000e	// Minimum Y coordinate of bounding box
	OUTER_SET GW_polygon_box_bottom_of	= 0x0010	// Maximum Y coordinate of bounding box
// Polygon index lookup table : Like all the lookup tables in WED files, this maps a (start, count) pair (in this case, from the wall group table) into a set of polygon indices (from the polygon table). This is essentially a table of little-endian 16-bit integers which are indices into the polygon table.
// Vertices : This is a table of (x, y) pairs of vertices. Each x and y is a little-endian 16-bit integer representing an onscreen coordinate.
	OUTER_SET GW_vertice_X_of		= 0x0000	// X coordinate
	OUTER_SET GW_vertice_Y_of		= 0x0002	// Y coordinate

END	// of DEFINE_ACTION_MACRO


/* =========================================================================================== *
 * FUNCTION GW_READ_WED_STRUCTURE : LECTURE des valeurs des offsets généraux d'un fichier WED. *
 *									READ the values of the main offsets in a WED file.         *
 * ------------------------------------------------------------------------------------------- *
 * Lancée systématiquement avant de modifier un élément d'un fichier wed.                      *
 * Launched before patching any section in a wed file.                                         *
 * =========================================================================================== */

DEFINE_PATCH_FUNCTION ~GW_READ_WED_STRUCTURE~ 
	RET	
// Header
	GW_wed_overlays_num				// Number of overlays (including the base layer)
	GW_wed_doors_num				// Number of doors
	GW_wed_overlays_off				// Offset (from start of file) to overlays
	GW_wed_2dheader_off				// Offset (from start of file) to secondary header
	GW_wed_doors_off				// Offset (from start of file) to doors
	GW_wed_door_tilecell_off		// Offset (from start of file) to door tile cell indices
// Secondary header
	GW_wed_wall_polygons_num		// Number of polygons used to represent walls
	GW_wed_polygons_off				// Offset to polygons
	GW_wed_vertices_off				// Offset to vertices
	GW_wed_wallgroups_off			// Offset to wall groups
	GW_wed_poly_lookup_table_off	// Offset to polygon indices lookup table
/* Wall groups
	GW_wed_wallgroup_polygon_start	// Start polygon index
	GW_wed_wallgroup_polygons_num	// Polygon index count
// Tilemap structures
	GW_wed_tilemap_lookup_start		// Start index in tile index lookup table of primary (default) tile
	GW_wed_tilemap_tiles_num		// Count of tiles in tile index lookup table for primary (default) tile
	GW_wed_tilemap_alternate_index	// Index from TIS file of secondary (alternate) tile (i.e. tile for closed state, if tile has an open/closed state) and also for overlays indication (tiles with marked overlay area, by "green" color)
	GW_wed_tilemap_byte				// 1 (byte) = bit 0: Unused - bit 1: Draw overlay 1 - bit 2: Draw overlay 2 ... bit 7: Draw overlay 7
// Polygon index lookup table
	GW_wed_vertice_X				// X coordinate
	GW_wed_vertice_Y				// Y coordinate
*/
BEGIN
// Header
	READ_LONG  GW_numoverlays_of									GW_wed_overlays_num					// Number of overlays (including the base layer)
	READ_LONG  GW_numdoors_of										GW_wed_doors_num					// Number of doors
	READ_LONG  GW_overlays_of										GW_wed_overlays_off					// Offset (from start of file) to overlays
	READ_LONG  GW_2dheader_of										GW_wed_2dheader_off					// Offset (from start of file) to secondary header
	READ_LONG  GW_wed_doors_of										GW_wed_doors_off					// Offset (from start of file) to doors
	READ_LONG  GW_door_tilecell_of									GW_wed_door_tilecell_off			// Offset (from start of file) to door tile cell indices
// Secondary header
	READ_LONG  (GW_wed_2dheader_off + GW_wall_poly_nb_of)			GW_wed_wall_polygons_num			// Number of polygons used to represent walls
	READ_LONG  (GW_wed_2dheader_off + GW_polygons_of)				GW_wed_polygons_off					// Offset to polygons
	READ_LONG  (GW_wed_2dheader_off + GW_wed_vertices_of)			GW_wed_vertices_off					// Offset to vertices
	READ_LONG  (GW_wed_2dheader_off + GW_wallgroups_of)				GW_wed_wallgroups_off				// Offset to wall groups
	READ_LONG  (GW_wed_2dheader_off + GW_polygons_lookup_table_of)	GW_wed_poly_lookup_table_off		// Offset to polygon indices lookup table
/* Wall groups
	READ_SHORT GW_wallgroup_polygon_of								GW_wed_wallgroup_polygon_start		// Start polygon index
	READ_SHORT GW_wallgroup_polygon_nb_of							GW_wed_wallgroup_polygons_num		// Polygon index count
// Tilemap structures
	READ_SHORT GW_tilemap_lookup_table_of							GW_wed_tilemap_lookup_start		// Start index in tile index lookup table of primary (default) tile
	READ_SHORT GW_tilemap_tile_nb_of								GW_wed_tilemap_tile_num			// Count of tiles in tile index lookup table for primary (default) tile
	READ_SHORT GW_tilemap_alternate_of								GW_wed_tilemap_alternate_index		// Index from TIS file of secondary (alternate) tile (i.e. tile for closed state, if tile has an open/closed state) and also for overlays indication (tiles with marked overlay area, by "green" color)
	READ_BYTE  GW_tilemap_byte_of									GW_wed_tilemap_byte			// 1 (byte) = bit 0: Unused - bit 1: Draw overlay 1 - bit 2: Draw overlay 2 ... bit 7: Draw overlay 7
// Polygon index lookup table
	READ_SHORT GW_vertice_X_of			GW_wed_vertice_X				// X coordinate
	READ_SHORT GW_vertice_Y_of			GW_wed_vertice_Y				// Y coordinate
*/
END	// of DEFINE_PATCH_FUNCTION


/* ======================================================================================================================== *
 * MACRO GW_READ_WED_DOOR_STRUCTURE : LECTURE des valeurs des offsets utilisés pour modifier une porte dans un fichier WED. *
 *									  READ the values of the main offsets used to patch a door in a WED file.               *
 * ------------------------------------------------------------------------------------------------------------------------ *
 * Lancée systématiquement avant de modifier une porte d'une carte.                                                         *
 * Launched before patching a door in a wed file.                                                                           *
 * ------------------------------------------------------------------------------------------------------------------------ *
 * VARIABLE pré-définie (predefined) :                                                                                      *
 *	SET GW_wed_door_offset = "%GW_wed_doors_off%" + ("%GW_wed_door_size%" * d) with d = index of the door                   *
 * ======================================================================================================================== */

DEFINE_PATCH_MACRO ~GW_READ_WED_DOOR_STRUCTURE~ 
BEGIN

// Doors : This section generally describes doors, though the concept can be extended to describe any object which acts like a door; i.e. has an open state and a closed state, and optionally blocks certain cells from being reached. The door tile cells for a given door are those cells which are impeded, and whose graphics change when this door is closed.
	READ_ASCII	(GW_wed_door_offset + GW_door_name_of)				GW_wed_door_name (8) NULL		// Name of door (matched on in AREA file?)
	READ_SHORT	(GW_wed_door_offset + GW_door_open_of)				GW_wed_door_open				// Open (0) / Closed (1)
	READ_SHORT	(GW_wed_door_offset + GW_door_first_tile_of)		GW_wed_door_first_tile_off		// First door tile cell index
	READ_SHORT	(GW_wed_door_offset + GW_door_tiles_nb_of)			GW_wed_door_tiles_num			// Count of door tile cells for this door
	READ_SHORT	(GW_wed_door_offset + GW_door_open_poly_nb_of)		GW_wed_door_open_polygons_num	// Count of polygons open state
	READ_SHORT	(GW_wed_door_offset + GW_door_closed_poly_nb_of)	GW_wed_door_closed_polygons_num	// Count of polygons closed state
	READ_LONG	(GW_wed_door_offset + GW_door_open_poly_of)			GW_wed_door_open_polygons_off	// Offset (from start of file) to polygons open state
	READ_LONG	(GW_wed_door_offset + GW_door_closed_poly_of)		GW_wed_door_closed_polygons_off	// Offset (from start of file) to polygons closed state

END	// of DEFINE_PATCH_MACRO


/* =========================================================================================================================== *
 * FUNCTION GW_READ_OVERLAY_STRUCTURE : LECTURE des valeurs des offsets utilisés pour modifier un overlay dans un fichier WED. *
 *									    READ the values of the main offsets used to patch an overlay in a WED file.            *
 * --------------------------------------------------------------------------------------------------------------------------- *
 * Lancée systématiquement avant de modifier un overlay d'un fichier wed.                                                      *
 * Launched before patching an overlay in a wed file.                                                                          *
 * =========================================================================================================================== */

DEFINE_PATCH_FUNCTION ~GW_READ_OVERLAY_STRUCTURE~ 
	INT_VAR GW_overlay_num = 0				// overlay number starting from 0
	RET		GW_wed_overlay_width			// Width (in tiles)
			GW_wed_overlay_height			// Height (in tiles)
			GW_wed_overlay_name				// Name of tileset
//			GW_wed_overlat_uniq_tile		// Unique tile count
//			GW_wed_overlay_movt_type		// Movement type
			GW_wed_overlay_tilemap_off		// Offset to tilemap for this overlay
			GW_wed_overlay_lookup_table_off	// Offset to tile index lookup for this overlay
BEGIN

// Overlays : Each overlay is mapped to a tileset. The sections of the area each overlay will cover is controlled by the tilemap section.
	READ_SHORT	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_width_of)		GW_wed_overlay_width			// Width (in tiles)
	READ_SHORT	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_height_of)		GW_wed_overlay_height			// Height (in tiles
	READ_ASCII	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_tile_name_of)	GW_wed_overlay_name (8) NULL	// Name of tileset
//	READ_SHORT	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_uniq_tile_c_of)	GW_wed_overlat_uniq_tile		// Unique tile count
//	READ_SHORT	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_movt_type_of)	GW_wed_overlay_movt_type		// Movement type
	READ_LONG	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overlay_tilemap_of)		GW_wed_overlay_tilemap_off		// Offset to tilemap for this overlay
	READ_LONG	(GW_wed_overlays_off + (GW_wed_overlay_size * GW_overlay_num) + GW_overay_lookup_table_of)	GW_wed_overlay_lookup_table_off	// Offset to tile index lookup for this overlay

END	// of DEFINE_PATCH_FUNCTION


/* ============================================================================================================================= *
 * MACRO GW_READ_WED_POLYGON_STRUCTURE : LECTURE des valeurs des offsets utilisés pour modifier un polygone dans un fichier WED. *
 *										 READ the values of the main offsets used to patch a polygon in a WED file.              *
 * ----------------------------------------------------------------------------------------------------------------------------- *
 * Lancée systématiquement avant de modifier un overlay d'un fichier wed.                                                        *
 * Launched before patching an overlay in a wed file.                                                                            *
 * ============================================================================================================================= */
// CURRENTLY unused
DEFINE_PATCH_MACRO ~GW_READ_WED_POLYGON_STRUCTURE~ 
BEGIN

// Polygons : A polygon consists of a list of vertices, a minimum bounding box and some unknown state information. The order of vertices can be important when describing polygons for doors wall, the vertices have to be listed clockwise, starting with the rightmost vertex first. If there are two or more vertex on the same rightmost vertical line, the lowest point should be listed first. For normal walls, the vertices can be listed in clockwise or anti-clockwise order, starting with the most lowest vertex.
	READ_LONG	(GW_wed_polygon_offset + GW_polygon_start_ind_of)	GW_wed_polygon_vertex_ind_start	// Starting vertex index
	READ_LONG	(GW_wed_polygon_offset + GW_polygon_vertices_nb_of)	GW_wed_polygon_vertices_num		// Count of vertices
	READ_BYTE	(GW_wed_polygon_offset + GW_polygon_flags_of)		GW_wed_polygon_flags			// Indicates whether this polygon is a polygon or a hole (i.e. whether it is a section of impassability, or one of passability). The default behavior is that wall shades animations from both sides. ==> bit 0 : Shade wall - bit 1 : Hovering - bit 2 : Cover animations - bit 3 : Cover animations - bit 4 bit 5 bit 6 : Unknown - bit 7 : Door?
	READ_BYTE	(GW_wed_polygon_offset + GW_polygon_height_of)		GW_wed_polygon_height			// Height
	READ_SHORT	(GW_wed_polygon_offset + GW_polygon_box_left_of)	GW_wed_polygon_box_left			// Minimum X coordinate of bounding box
	READ_SHORT	(GW_wed_polygon_offset + GW_polygon_box_right_of)	GW_wed_polygon_box_right		// Maximum X coordinate of bounding box
	READ_SHORT	(GW_wed_polygon_offset + GW_polygon_box_top_of)		GW_wed_polygon_box_top			// Minimum Y coordinate of bounding box
	READ_SHORT	(GW_wed_polygon_offset + GW_polygon_box_bottom_of)	GW_wed_polygon_box_bottom		// Maximum Y coordinate of bounding box

END	// of DEFINE_PATCH_MACRO


/* ==================================================================================================== *
 *                                                                                                      *
 *            F U N C T I O N S    &    M A C R O S    P A T C H I N G    W E D    F I L E S            *
 *                                                                                                      *
 * ==================================================================================================== */

/* ============================================================================================================================================================================= *
 * MACRO GW_DRAW_WED_WALLGROUPS : DÉFINITION des wall groups (nombre et aires) d'un fichier WED.                                                                                 *
 *								  CALCULATE the wall groups (number and bounding box) included in a WED file.                                                                    *
 * ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- *
 * IESDP :                                                                                                                                                                       *
 * Wall groups : Outlines of objects (specifically walls and doors) need to be stored in order to determine when to dither creature animations (to represent moving "behind" a   *
 * wall). Outlines are stored as a series of ordered vertices, creating a polygon. Doors can be represented by more than one polygon in either their open or closed state - this *
 * allows for double doors. These wall groups are sets of indices in the polygon indices lookup table, which in turn points into the polygon table.                              *
 * One thing worth remembering is that one wall group has the following dimensions : 10 tiles * 7.5 tiles, thus all areas should have the according to the background overlay    *
 * amount of wall groups sections stored here i.e. area with dimensions 80*60 tiles should have 64 wall groups.                                                                  *
 * ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- *
 * Lancée systématiquement avant de corriger un fichier wed corrompu ou d'insérer un nouveau polygone dans un fichier wed, elle crée la table de variables suivantes :           *
 * Launched before fixing a wed file or adding a new polygon into a wed file, it creates the following array :                                                                   *
 * $wallgroup("wed file" "wall group number" "left") - $wallgroup("wed file" "wall group number" "right") - $wallgroup("wed file" "wall group number" "top")                     *
 * $wallgroup("wed file" "wall group number" "bottom")                                                                                                                           *
 * ============================================================================================================================================================================= */

DEFINE_PATCH_MACRO ~GW_DRAW_WED_WALLGROUPS~ 
BEGIN

	SET GW_wed_width = GW_wed_overlay_width * 64
	SET GW_wed_height = GW_wed_overlay_height * 64
	SET GW_wg_hori = (((GW_wed_width / 640) * 640) < GW_wed_width) ? ((GW_wed_width / 640) + 1) : (GW_wed_width / 640)
	SET GW_wg_vert = (((GW_wed_height / 480) * 480) < GW_wed_height) ? ((GW_wed_height / 480) + 1) : (GW_wed_height / 480)
	SET wallgroups = 0
	FOR (v = 0 ; v < GW_wg_vert ; ++v) BEGIN		// Looping through vertical limits
		FOR (h = 0 ; h < GW_wg_hori ; ++h) BEGIN	// Looping through horizontal limits
			SET $wallgroup("%SOURCE_RES%" "%wallgroups%" "left")	= (h = 0) ? 0	: (640 * h) + (1 * h)
			SET $wallgroup("%SOURCE_RES%" "%wallgroups%" "right")	= (h = 0) ? 640 : ((640 * (h + 1) + (1 * h)) < GW_wed_width) ? (640 * (h + 1) + (1 * h)) : GW_wed_width
			SET $wallgroup("%SOURCE_RES%" "%wallgroups%" "top")		= (v = 0) ? 0	: (480 * v) + (1 * v)
			SET $wallgroup("%SOURCE_RES%" "%wallgroups%" "bottom")	= (v = 0) ? 480 : ((480 * (v + 1) + (1 * v)) < GW_wed_height) ? (480 * (v + 1) + (1 * v)) : GW_wed_height
			wallgroups += 1
		END	// of Looping through horizontal limits
	END		// of Looping through vertical limits

END			// of DEFINE_PATCH_MACRO


/* ======================================================================================================================================= *
 * FUNCTION GW_CALCULATE_POLYGON_BOUNDING_BOX : CALCUL automatiquement la bounding box d'un polygone.                                      *
 *												Automatically CALCULATE a polygon bounding box.                                            *
 * --------------------------------------------------------------------------------------------------------------------------------------- *
 * Variables :                                                                                                                             *
 *	- GW_v_coordX & GW_v_coordY : cordonnées de chaque vertex (vertex coordinates.)							                               *
 *	- GW_old_box_left (right, top, bottom) : valeurs de la bounding box à comparer (bounding box values to compare with the new vertex).   *
 *					(1 << 1) [locked] - (1 << 6) [located = linked] (1 << 9) [can be looked through]                                       *
 *	- GW_box_left (right, top, bottom) : retourne les valeurs de la bounding box actualisées - Returns the bounding box values updated     *
 * ======================================================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_CALCULATE_POLYGON_BOUNDING_BOX~ 
	INT_VAR GW_v_coordX			= 0		// Vertex X coordinate
			GW_v_coordY			= 0		// Vertex Y coordinate
			GW_old_box_left		= 5120	// Minimum X coordinate of bounding box basis (5120 = 80 x 64)
			GW_old_box_right	= 0		// Maximum X coordinate of bounding box basis
			GW_old_box_top		= 3840	// Minimum Y coordinate of bounding box basis (3840 = 60 x 64)
			GW_old_box_bottom	= 0		// Maximum Y coordinate of bounding box basis
	RET		GW_box_left					// Minimum X coordinate of bounding box
			GW_box_right				// Maximum X coordinate of bounding box
			GW_box_top					// Minimum Y coordinate of bounding box
			GW_box_bottom				// Maximum Y coordinate of bounding box
BEGIN

	SET GW_box_left		= GW_old_box_left
	SET GW_box_right	= GW_old_box_right
	SET GW_box_top		= GW_old_box_top
	SET GW_box_bottom	= GW_old_box_bottom

	PATCH_IF (GW_v_coordX < 5120) && (GW_v_coordX < GW_old_box_left)	BEGIN	SET GW_box_left = GW_v_coordX END
	PATCH_IF (GW_v_coordX < 5120) && (GW_v_coordX > GW_old_box_right)	BEGIN	SET GW_box_right = GW_v_coordX END
	PATCH_IF (GW_v_coordY < 3840) && (GW_v_coordY < GW_old_box_top)		BEGIN	SET GW_box_top = GW_v_coordY END
	PATCH_IF (GW_v_coordY < 3840) && (GW_v_coordY > GW_old_box_bottom)	BEGIN	SET GW_box_bottom = GW_v_coordY END

END	// of DEFINE_PATCH_FUNCTION


/* ========================================================================================================================================= *
 * FUNCTION GW_ADD_WED_DOOR : AJOUTE ou MODIFIE une porte dans un fichier WED.                                                               *
 *						      ADD or ALTER a door in a WED file.                                                                             *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * !!!!! ATTENTION - WARNING !!!!! : FONCTION EXPÉRIMENTALE - EXPERIMENTAL FUNCTION                                                          *
 *									 Pour l'instant, seul fonctionne l'ajout de polygones d'ouverture ou de fermeture à une porte existante. *
 *									 For now, it can only add open and closed door polygones to an existing door.                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * Explications : à faire                                                                                                                    *
 * Readme : to do                                                                                                                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * Variable : GW_output_wallgroups                                                                                                           *
 * Utilisée par la fonction GW_FIX_POLYGONS_IN_WALLGROUPS pour mettre à jour la table des wallgroups.                                        *
 * Used by the function GW_FIX_POLYGONS_IN_WALLGROUPS to update the wallgroups table.                                                        *
 * ========================================================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_ADD_WED_DOOR~ 
	STR_VAR GW_Wed	= ""			// Which map to patch (WED file without ext.).
			GW_Door	= ""			// Door's name to add or modify.
			GW_Add	= "N"			// @ToDo Y
	RET		GW_output_wallgroups
BEGIN

	SPRINT GW_output_wallgroups ""
	PATCH_IF ("%GW_Add%" STRING_EQUAL "N") BEGIN
		SET GW_match_door = 0
// 1. First, we seek the door to modify.
// -------------------------------------
		LPF ~GW_READ_WED_STRUCTURE~ RET	GW_wed_overlays_num GW_wed_doors_num GW_wed_overlays_off GW_wed_2dheader_off GW_wed_doors_off GW_wed_door_tilecell_off	// Header
										GW_wed_wall_polygons_num GW_wed_polygons_off GW_wed_vertices_off GW_wed_wallgroups_off GW_wed_poly_lookup_table_off END	// Secondary header

		wed_size = SOURCE_SIZE

		FOR (d = 0 ; d < GW_wed_doors_num ; ++d) BEGIN				// Looping through doors
			SET GW_wed_door_offset = "%GW_wed_doors_off%" + ("%GW_wed_door_size%" * d)
			READ_ASCII GW_wed_door_offset "nom" (8) NULL
			PATCH_IF ("%GW_Door%" STRING_COMPARE_CASE "%nom%" = 0) BEGIN 
				SET GW_num_wed_door_match = d						// index used to add/modify polygons of the door (if needed)
				SET GW_match_door = 1								// door found
				SET d = GW_wed_doors_num							// door found : stop the process
				LPM ~GW_READ_WED_DOOR_STRUCTURE~
			END	// of PATCH_IF ("%GW_Door%" STRING_COMPARE_CASE "%nom%" = 0)
		END		// of Looping through doors

// 2. If the door exists.
// ----------------------
		PATCH_IF (GW_match_door) BEGIN

			SET GW_polygons_total_count = GW_wed_wall_polygons_num		// We count the total number of polygons
			FOR (d = 0 ; d < GW_wed_doors_num ; ++d) BEGIN				// Looping through doors
				SET GW_wed_door_offset = "%GW_wed_doors_off%" + ("%GW_wed_door_size%" * d)
				LPM ~GW_READ_WED_DOOR_STRUCTURE~
				SET GW_polygons_total_count = GW_polygons_total_count + GW_wed_door_open_polygons_num + GW_wed_door_closed_polygons_num	// Count of polygons open state + Count of polygons closed state
			END
			SET GW_polygons_total_count_index = GW_polygons_total_count - 1	// used to add the Wall polygon index in its respective wall group

// 2. a) First, we read the GW_New_wed_vertices array and auto-generate door vertex (open & closed).
// -------------------------------------------------------------------------------------------------
			SET GW_Nb_new_vertices_open					= 0		// Nb of new vertices for the open door polygons
			SET GW_Nb_new_vertices_closed				= 0		// Nb of new vertices for the closed door polygons
			SET GW_Nb_new_vertices_this_open_polygon	= 1		// Nb of new vertices per each new open door polygon
			SET GW_Nb_new_vertices_this_closed_polygon	= 1		// Nb of new vertices per each new closed door polygon
			SET GW_Nb_new_open_polygons					= 0		// Nb of new polygons (open doors)
			SET GW_Nb_new_closed_polygons				= 0		// Nb of new polygons (closed doors)
			SET GW_Nb_vertices							= ((SOURCE_SIZE - GW_wed_vertices_off) / 4)

			PATCH_PHP_EACH GW_New_wed_vertices AS donnees => door BEGIN

				PATCH_IF ("%donnees_0%" STRING_COMPARE_CASE "%GW_Wed%" = 0) && ("%door%" STRING_COMPARE_CASE "%GW_Door%" = 0) 
					  && ("%donnees_0%" STRING_COMPARE_CASE "%SOURCE_RES%" = 0) BEGIN 

					PATCH_IF ("%donnees_1%" STRING_COMPARE_CASE "OP" = 0) BEGIN															// Open doors vertices
						PATCH_IF ("%donnees_4%" != GW_Nb_new_open_polygons) BEGIN														// Open doors polygons
							SET GW_Nb_new_open_polygons = EVAL "%donnees_4%"
							SET GW_Nb_new_vertices_this_open_polygon = 1
						END
						GW_Nb_new_vertices_open +=1
						SET $GW_new_vertice_open_X("%door%" "%GW_Nb_new_vertices_open%") = EVAL "%donnees_2%"
						SET $GW_new_vertice_open_Y("%door%" "%GW_Nb_new_vertices_open%") = EVAL "%donnees_3%"
						SET $GW_new_polygon_open_vertices("%door%" "%GW_Nb_new_open_polygons%") = GW_Nb_new_vertices_this_open_polygon	// Vertices count in the new open polygon
						GW_Nb_new_vertices_this_open_polygon +=1
					END	// of // Open doors vertices
					PATCH_IF ("%donnees_1%" STRING_COMPARE_CASE "CL" = 0) BEGIN															// Closed doors vertices 
						PATCH_IF ("%donnees_4%" != GW_Nb_new_closed_polygons) BEGIN														// Closed doors polygons
							SET GW_Nb_new_closed_polygons = EVAL "%donnees_4%"
							SET GW_Nb_new_vertices_this_closed_polygon = 1
						END 
						GW_Nb_new_vertices_closed +=1
						SET $GW_new_vertice_closed_X("%door%" "%GW_Nb_new_vertices_closed%") = EVAL "%donnees_2%"
						SET $GW_new_vertice_closed_Y("%door%" "%GW_Nb_new_vertices_closed%") = EVAL "%donnees_3%"
						SET $GW_new_polygon_closed_vertices("%door%" "%GW_Nb_new_closed_polygons%") = GW_Nb_new_vertices_this_closed_polygon	// Vertices count in the new closed polygon
						GW_Nb_new_vertices_this_closed_polygon +=1
					END	// of // Closed doors vertices

				END		// of PATCH_IF ("%donnees_0%" STRING_COMPARE_CASE "%GW_Wed%" = 0) && ("%door%" STRING_COMPARE_CASE "%GW_Door%" = 0) && ("%donnees_0%" STRING_COMPARE_CASE "%SOURCE_RES%" = 0)

			END			// of PATCH_PHP_EACH GW_New_wed_vertices

// 2. b) We insert new door vertices.
// ----------------------------------
			PATCH_IF (GW_Nb_new_vertices_open > 0) OR (GW_Nb_new_vertices_closed > 0) BEGIN
				INSERT_BYTES wed_size (GW_wed_vertice_size * (GW_Nb_new_vertices_open + GW_Nb_new_vertices_closed))					// Insert new vertices

				PATCH_IF (GW_Nb_new_vertices_open > 0) THEN BEGIN										// Write Open door new vertices

					FOR (poly = 1 ; poly <= GW_Nb_new_open_polygons ; ++poly) BEGIN						// Looping through new open door polygons
						GW_polygons_total_count_index += 1												// Update the Wall polygon index to add in the wall group table
						GW_open_box_left	= 5120
						GW_open_box_right	= 0
						GW_open_box_top		= 3840
						GW_open_box_bottom	= 0

						FOR (vertice = 1 ; vertice <= $GW_new_polygon_open_vertices("%door%" "%poly%") ; ++vertice) BEGIN		// Looping through vertices
							WRITE_SHORT (wed_size + (GW_wed_vertice_size * poly * (vertice - 1))) EVAL $GW_new_vertice_open_X("%door%" "%vertice%")
							WRITE_SHORT (wed_size + ((GW_wed_vertice_size * poly * (vertice - 1)) + GW_vertice_Y_of)) EVAL $GW_new_vertice_open_Y("%door%" "%vertice%")
							SET GW_v_coordX = EVAL $GW_new_vertice_open_X("%door%" "%vertice%")
							SET GW_v_coordY = EVAL $GW_new_vertice_open_Y("%door%" "%vertice%")
							SET GW_old_box_left		= (vertice = 1) ? 5120 : GW_open_box_left
							SET GW_old_box_right	= (vertice = 1) ? 0 : GW_open_box_right
							SET GW_old_box_top		= (vertice = 1) ? 3840 : GW_open_box_top
							SET GW_old_box_bottom	= (vertice = 1) ? 0 : GW_open_box_bottom
							LPF ~GW_CALCULATE_POLYGON_BOUNDING_BOX~ INT_VAR GW_v_coordX GW_v_coordY GW_old_box_left GW_old_box_right GW_old_box_top GW_old_box_bottom 
								RET GW_open_box_left = GW_box_left GW_open_box_right = GW_box_right GW_open_box_top = GW_box_top GW_open_box_bottom = GW_box_bottom END
						END	// of FOR (vertice = 1 ; vertice <= GW_Nb_new_vertices_open ; ++vertice)

						SET $GW_new_open_poly_bounding_box_left("%door%" "%poly%") = GW_open_box_left
						SET $GW_new_open_poly_bounding_box_right("%door%" "%poly%") = GW_open_box_right
						SET $GW_new_open_poly_bounding_box_top("%door%" "%poly%") = GW_open_box_top
						SET $GW_new_open_poly_bounding_box_bottom("%door%" "%poly%") = GW_open_box_bottom

						LPF ~GW_POLYGON_IN_WALLGROUP~ INT_VAR GW_left = EVAL $GW_new_open_poly_bounding_box_left("%door%" "%poly%") GW_right = EVAL $GW_new_open_poly_bounding_box_right("%door%" "%poly%") GW_top = EVAL $GW_new_open_poly_bounding_box_top("%door%" "%poly%") GW_bottom = EVAL $GW_new_open_poly_bounding_box_bottom("%door%" "%poly%") STR_VAR GW_all_wallgroups = "Y" RET GW_match_wallgroup END

						SPRINT GW_output_wallgroups EVAL "%GW_output_wallgroups%%LNL%%TAB%%GW_match_wallgroup%%TAB%=>%TAB%%GW_polygons_total_count_index%"

					END		// of Looping through new open door polygons - FOR (poly = 1 ; poly <= GW_Nb_new_open_polygons ; ++poly)

				END			// of PATCH_IF (GW_Nb_new_vertices_open > 0)

				PATCH_IF (GW_Nb_new_vertices_closed > 0) THEN BEGIN																	// Write Closed door new vertices

					FOR (poly = 1 ; poly <= GW_Nb_new_closed_polygons ; ++poly) BEGIN												// Looping through new closed door polygons
						GW_closed_box_left	 = 5120
						GW_closed_box_right	 = 0
						GW_closed_box_top	 = 3840
						GW_closed_box_bottom = 0

						FOR (vertice = 1 ; vertice <= GW_Nb_new_vertices_closed ; ++vertice) BEGIN									// Looping through vertices
							WRITE_SHORT (wed_size + (GW_wed_vertice_size * poly * (vertice - 1))) EVAL $GW_new_vertice_closed_X("%door%" "%vertice%")
							WRITE_SHORT (wed_size + ((GW_wed_vertice_size * poly * vertice) - GW_vertice_Y_of)) EVAL $GW_new_vertice_closed_Y("%door%" "%vertice%")
							SET GW_v_coordX = EVAL $GW_new_vertice_closed_X("%door%" "%vertice%")
							SET GW_v_coordY = EVAL $GW_new_vertice_closed_Y("%door%" "%vertice%")
							SET GW_old_box_left		= (vertice = 1) ? 5120 : GW_closed_box_left
							SET GW_old_box_right	= (vertice = 1) ? 0 : GW_closed_box_right
							SET GW_old_box_top		= (vertice = 1) ? 3840 : GW_closed_box_top
							SET GW_old_box_bottom	= (vertice = 1) ? 0 : GW_closed_box_bottom
							LPF ~GW_CALCULATE_POLYGON_BOUNDING_BOX~ INT_VAR GW_v_coordX GW_v_coordY GW_old_box_left GW_old_box_right GW_old_box_top GW_old_box_bottom 
								RET GW_closed_box_left = GW_box_left GW_closed_box_right = GW_box_right GW_closed_box_top = GW_box_top GW_closed_box_bottom = GW_box_bottom END
						END	// of FOR (vertice = 1 ; vertice <= GW_Nb_new_vertices_closed ; ++vertice)

						SET $GW_new_closed_poly_bounding_box_left("%door%" "%poly%") = GW_closed_box_left
						SET $GW_new_closed_poly_bounding_box_right("%door%" "%poly%") = GW_closed_box_right
						SET $GW_new_closed_poly_bounding_box_top("%door%" "%poly%") = GW_closed_box_top
						SET $GW_new_closed_poly_bounding_box_bottom("%door%" "%poly%") = GW_closed_box_bottom

						LPF ~GW_POLYGON_IN_WALLGROUP~ INT_VAR GW_left = EVAL $GW_new_closed_poly_bounding_box_left("%door%" "%poly%") GW_right = EVAL $GW_new_closed_poly_bounding_box_right("%door%" "%poly%") GW_top = EVAL $GW_new_closed_poly_bounding_box_top("%door%" "%poly%") GW_bottom = EVAL $GW_new_closed_poly_bounding_box_bottom("%door%" "%poly%") STR_VAR GW_all_wallgroups = "Y" RET GW_match_wallgroup END

						SPRINT GW_output_wallgroups EVAL "%GW_output_wallgroups%%LNL%%TAB%%GW_match_wallgroup%%TAB%=>%TAB%%GW_polygons_total_count_index%"

					END		// of Looping through new closed door polygons - FOR (poly = 1 ; poly <= GW_Nb_new_closed_polygons ; ++poly)

				END			// of PATCH_IF (GW_Nb_new_vertices_closed > 0)

// 2. c) We insert new door polygons.
// ----------------------------------
				PATCH_IF (GW_Nb_new_open_polygons > 0) OR (GW_Nb_new_closed_polygons > 0) BEGIN
					INSERT_BYTES GW_wed_poly_lookup_table_off (GW_wed_polygon_size * (GW_Nb_new_open_polygons + GW_Nb_new_closed_polygons))	// Insert new polygons
					WRITE_LONG	 GW_wed_poly_lookup_table_off GW_Nb_vertices																// Starting vertex index
				END			// of (GW_Nb_new_open_polygons > 0) OR (GW_Nb_new_closed_polygons > 0)

				PATCH_IF (GW_Nb_new_open_polygons > 0) THEN BEGIN																			// Write open polygons settings

					FOR (op = 1 ; op <= GW_Nb_new_open_polygons ; ++op) BEGIN
						SET GW_count_new_vertices_open = (op = 1) ? GW_Nb_vertices : (GW_Nb_vertices + $GW_new_polygon_open_vertices("%door%" "%op%"))
// Write Starting vertex index
						WRITE_LONG	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)))							 GW_count_new_vertices_open
// Write Vertices count in the new open polygon
						WRITE_LONG	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_vertices_nb_of) $GW_new_polygon_open_vertices("%door%" "%op%")
// Write polygon flags = bit 0 : Shade wall - bit 3 : Cover animations - bit 7 : Door?
						WRITE_BYTE	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_flags_of)		(THIS | BIT0 | BIT3 | BIT7)
// Write polygon Height
						WRITE_BYTE	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_height_of)	0xff
// Write polygon bounding box
						WRITE_SHORT (GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_box_left_of)	 $GW_new_open_poly_bounding_box_left("%door%" "%op%")
						WRITE_SHORT (GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_box_right_of)	 $GW_new_open_poly_bounding_box_right("%door%" "%op%")
						WRITE_SHORT (GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_box_top_of)	 $GW_new_open_poly_bounding_box_top("%door%" "%op%")
						WRITE_SHORT (GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (op - 1)) + GW_polygon_box_bottom_of) $GW_new_open_poly_bounding_box_bottom("%door%" "%op%")

					END	// of FOR (op = 1 ; op <= GW_Nb_new_open_polygons ; ++op)

				END		// of PATCH_IF (GW_Nb_new_open_polygons > 0)

				PATCH_IF (GW_Nb_new_closed_polygons > 0) THEN BEGIN																		// Write closed polygons settings

					FOR (cp = 1 ; cp <= GW_Nb_new_closed_polygons ; ++cp) BEGIN
						SET GW_count_new_vertices_closed = (cp = 1) ? GW_Nb_vertices : (GW_Nb_vertices + $GW_new_polygon_closed_vertices("%door%" "%cp%"))
// Write Starting vertex index
						WRITE_LONG	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)))							 GW_count_new_vertices_closed
// Write Vertices count in the new closed polygon
						WRITE_LONG	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_vertices_nb_of) $GW_new_polygon_closed_vertices("%door%" "%op%")
// Write polygon flags = bit 0 : Shade wall - bit 3 : Cover animations - bit 7 : Door?
						WRITE_BYTE	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_flags_of)		 (THIS | BIT0 | BIT3 | BIT7)
// Write polygon Height
						WRITE_BYTE	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_height_of)	 0xff
// Write polygon bounding box
						WRITE_SHORT	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_box_left_of)	$GW_new_closed_poly_bounding_box_left("%door%" "%cp%")
						WRITE_SHORT	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_box_right_of) $GW_new_closed_poly_bounding_box_right("%door%" "%cp%")
						WRITE_SHORT	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_box_top_of)	 $GW_new_closed_poly_bounding_box_top("%door%" "%cp%")
						WRITE_SHORT	(GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (cp - 1)) + GW_polygon_box_bottom_of) $GW_new_closed_poly_bounding_box_bottom("%door%" "%cp%")

					END	// of FOR (cp = 1 ; cp <= GW_Nb_new_closed_polygons ; ++cp)

				END		// of PATCH_IF (GW_Nb_new_closed_polygons > 0)

// 2. d) We update the door settings.
// ----------------------------------
				WRITE_SHORT	(GW_wed_door_offset + GW_door_open_poly_nb_of)	 (GW_wed_door_open_polygons_num + GW_Nb_new_open_polygons)		// Count of polygons open state
				WRITE_SHORT	(GW_wed_door_offset + GW_door_closed_poly_nb_of) (GW_wed_door_closed_polygons_num + GW_Nb_new_closed_polygons)	// Count of polygons closed state
				WRITE_LONG	(GW_wed_door_offset + GW_door_open_poly_of)		 GW_wed_door_open_polygons_off						// Offset (from start of file) to polygons open state
				WRITE_LONG	(GW_wed_door_offset + GW_door_closed_poly_of)	 (GW_wed_door_closed_polygons_off + (GW_wed_polygon_size * GW_Nb_new_open_polygons)) // Offset (from start of file) to polygons closed state

// 2. e) We update the other offsets.
// ----------------------------------
// Secondary header : Offset to vertices
				WRITE_LONG (GW_wed_2dheader_off + GW_wed_vertices_of) (GW_wed_vertices_off + (GW_wed_polygon_size * (GW_Nb_new_open_polygons + GW_Nb_new_closed_polygons)))
// Secondary header : Offset to polygon indices lookup table
				WRITE_LONG (GW_wed_2dheader_off + GW_polygons_lookup_table_of) (GW_wed_poly_lookup_table_off + (GW_wed_polygon_size * (GW_Nb_new_open_polygons + GW_Nb_new_closed_polygons)))

			END ELSE BEGIN
				PATCH_PRINT "WARNING: Door %GW_Door% new settings not found for %GW_Wed%.WED"
			END

// No door found.
// --------------
		END ELSE BEGIN	// TODO IF GW_Add = Y	==> Add a brand new door
			PATCH_PRINT "WARNING: Door %GW_Door% not found in %GW_Wed%.WED"
		END		// of PATCH_IF (GW_match_door)

	END			// of PATCH_IF ("%GW_Add%" STRING_EQUAL "N")
END				// of DEFINE_ACTION_FUNCTION


/* ========================================================================================================================================= *
 * FUNCTION GW_FIX_POLYGONS_IN_WALLGROUPS : MISE À JOUR des tables des wall groups et des wall polygon index d'un fichier WED.               *
 *						    			    UPDATE the wall groups and wall polygon index tables in a WED file.                              *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * !!!!! ATTENTION - WARNING !!!!! : FONCTION EXPÉRIMENTALE - EXPERIMENTAL FUNCTION                                                          *
 *									 Pour l'instant, seul fonctionne l'ajout de polygones d'ouverture ou de fermeture à une porte existante. *
 *									 For now, it can only add open and closed door polygones to an existing door.                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * Explications : à faire                                                                                                                    *
 * Readme : to do                                                                                                                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * ========================================================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_FIX_POLYGONS_IN_WALLGROUPS~ 
	INT_VAR GW_Add_new_polygon = 0	// Default (0 = We fix the WED file) - 1 = We add new polygons and update the wallgroups table.
	STR_VAR GW_array = ""			// Array used to fix a WED file (GW_fix_ARxxxx_wed_wallgroups) defined in GW_vertices_table
			array = ""				// Array used to add new polygons a WED file and fix the wallgroups table (GW_output_wallgroups defined in function GW_ADD_WED_DOOR).
BEGIN

// Initialize all needed variables
	LPF ~GW_READ_WED_STRUCTURE~ RET	GW_wed_overlays_num GW_wed_doors_num GW_wed_overlays_off GW_wed_2dheader_off GW_wed_doors_off GW_wed_door_tilecell_off	// Header
									GW_wed_wall_polygons_num GW_wed_polygons_off GW_wed_vertices_off GW_wed_wallgroups_off GW_wed_poly_lookup_table_off END	// Secondary header
	READ_SHORT (GW_wed_polygons_off - GW_wed_wallgroup_size) GW_last_wallgroup_start_polygon_index
	READ_SHORT (GW_wed_polygons_off - GW_wed_wallgroup_size + GW_wallgroup_polygon_nb_of) GW_last_wallgroup_polygon_index_count
	SET GW_wed_wallgroups_polygons_num = GW_last_wallgroup_start_polygon_index + GW_last_wallgroup_polygon_index_count - 1

// FIRST CASE : WE NEED TO FIX THE ORIGINAL WED FILE.
// --------------------------------------------------
	PATCH_IF ("%GW_array%" STR_CMP "") BEGIN
// 1. a) Construct wallgroup array from %GW_array%
		PATCH_PHP_EACH "%GW_array%" AS donnees => wallgroup BEGIN
			SET $new_wallgroup("%SOURCE_RES%" "%donnees_0%" "start") = %donnees_1%
			SET $new_wallgroup("%SOURCE_RES%" "%donnees_0%" "count") = %donnees_2%
			PATCH_IF ("%donnees_0%" = wallgroups - 1) BEGIN
				SET GW_new_last_polygon_index = %donnees_1% + %donnees_2% - 1
			END

// 1. b) Fix the wall groups settings
			SET wg_offset = GW_wed_wallgroups_off + (0x4 * %donnees_0%)
			WRITE_SHORT	(wg_offset      )	%donnees_1%
			WRITE_SHORT	(wg_offset + 0x2)	%donnees_2%
			READ_SHORT	(wg_offset      )	GW_new_wed_wallgroup_polygon_start
			READ_SHORT	(wg_offset + 0x2)	GW_new_wed_wallgroup_polygons_num
		END	// of PATCH_PHP_EACH "%GW_array%" AS donnees => wallgroup BEGIN

// 1. c) Calculate the new wall polygon index to insert and insert them
		SET GW_delta_polygon_index = GW_new_last_polygon_index - GW_wed_wallgroups_polygons_num
		INSERT_BYTES GW_wed_vertices_off (GW_wall_polygon_index_size * GW_delta_polygon_index)		// Insert new wall polygon index
		WRITE_LONG (GW_wed_2dheader_off + GW_wed_vertices_of)	(GW_wed_vertices_off + (GW_wall_polygon_index_size * GW_delta_polygon_index))

// 1. d) Select the fixed wall polygon index values
		PATCH_MATCH ~%SOURCE_RES%~ WITH
			AR0400	BEGIN
				SPRINT list_wed_poly_index "74 75 76 49 0 1 2 46 47 49 0 3 4 5 55 56 57 74 75 76 77 78 196 49 50 51 52 53 54 55 56 57 97 98 99 198 48 49 99 100 131 4 5 6 7 13 14 15 130 131 199 8 9 10 11 14 16 200 77 78 79 80 82 173 58 61 97 98 99 173 174 175 176 177 60 61 62 63 98 99 100 130 131 132 204 13 14 128 129 130 131 132 10 11 12 16 17 19 127 128 201 17 18 19 20 21 22 202 80 81 93 94 95 96 133 173 59 133 135 136 137 173 174 176 177 181 59 60 63 64 169 170 182 183 186 65 66 119 120 121 122 128 129 141 203 103 104 105 107 108 123 124 125 126 127 128 23 24 25 26 27 28 71 72 87 91 92 93 94 95 133 133 134 135 136 139 180 134 138 139 140 146 147 169 170 171 172 178 179 180 182 183 184 185 186 187 110 117 118 119 120 141 142 143 144 145 146 148 149 150 151 152 153 154 155 156 157 167 168 184 205 45 73 101 102 103 104 105 106 108 109 110 111 112 113 114 115 116 119 123 25 29 30 31 32 33 34 35 45 70 71 72 73 197 83 84 85 86 87 91 83 84 90 180 158 159 160 161 162 163 164 165 166 167 172 178 179 180 187 194 206 155 156 166 167 168 190 191 192 193 44 45 67 68 73 189 190 191 30 31 32 33 34 36 37 38 39 40 41 42 43 45 68 69 73 197 83 84 85 83 84 88 160 194 195 192 193 194 188 189 190 40" END
			AR0400N	BEGIN
				SPRINT list_wed_poly_index "73 74 75 49 0 1 2 46 47 49 0 3 4 5 55 56 57 73 74 75 76 77 195 49 50 51 52 53 54 55 56 57 96 97 98 198 48 49 98 99 130 4 5 6 7 13 14 15 129 130 199 8 9 10 11 14 16 200 76 77 78 79 81 172 58 61 96 97 98 172 173 174 175 176 60 61 62 63 97 98 99 129 130 131 204 13 14 127 128 129 130 131 10 11 12 16 17 19 126 127 201 17 18 19 20 21 22 202 79 80 92 93 94 95 132 172 59 132 134 135 136 172 173 175 176 180 59 60 63 64 168 169 181 182 185 65 66 118 119 120 121 127 128 140 203 102 103 104 106 107 122 123 124 125 126 127 23 24 25 26 27 28 70 71 86 90 91 92 93 94 132 132 133 134 135 138 179 133 137 138 139 145 146 168 169 170 171 177 178 179 181 182 183 184 185 186 109 116 117 118 119 140 141 142 143 144 145 147 148 149 150 151 152 153 154 155 156 166 167 183 205 45 72 100 101 102 103 104 105 107 108 109 110 111 112 113 114 115 118 122 25 29 30 31 32 33 34 35 45 69 70 71 72 196 82 83 84 85 86 90 82 83 89 179 157 158 159 160 161 162 163 164 165 166 171 177 178 179 186 193 206 154 155 165 166 167 189 190 191 192 44 45 67 72 188 189 190 197 30 31 32 33 34 36 37 38 39 40 41 42 43 45 68 72 196 197 82 83 84 82 83 87 159 193 194 191 192 193 187 188 189 40" END
			DEFAULT
		END

// 1. e) Automatically write the fixed wall polygon index values
		SPRINT input_wed EVAL ~SET wall_polygon_index = 0
PATCH_FOR_EACH poly IN %list_wed_poly_index% BEGIN
	SET poly_index = GW_wed_poly_lookup_table_off + (0x2 * wall_polygon_index)
	WRITE_SHORT poly_index poly
//LPF TO_HEX_NUMBER INT_VAR value = poly_index minDigits = 1 prefix = 1 RET poly_index_offset = hexNumber END
//PATCH_LOG "%DEST_FILE%	==>	Wall polygon index %wall_polygon_index% = %poly% ==> %poly_index_offset%"
	SET wall_polygon_index +=1
END~

		LPF ~GW_REINCLUDE~ STR_VAR input = EVAL "%input_wed%" END

	END	// of PATCH_IF ("%GW_array%" STR_CMP "") BEGIN

// SECOND CASE : UPDATE THE WALL GROUPS AND THE POLYGON INDEX TABLES.
// ------------------------------------------------------------------
	PATCH_IF (GW_Add_new_polygon) BEGIN
// 2. a) Build original wallgroup array
		wg_num = 0
		FOR (wg = GW_wed_wallgroups_off ; wg < GW_wed_polygons_off ; wg += 0x4) BEGIN
			READ_SHORT wg			GW_wed_wallgroup_polygon_start
			READ_SHORT (wg + 0x2)	GW_wed_wallgroup_polygons_num
			SET $wallgroup_new("%wg_num%" "start") = GW_wed_wallgroup_polygon_start
			SET $wallgroup_new("%wg_num%" "index") = GW_wed_wallgroup_polygons_num
			wg_num +=1
		END

// 2. b) generating include tph file to build the new wall groups settings array.
		SPRINT input_wallgroups EVAL "INNER_ACTION BEGIN 
ACTION_DEFINE_ASSOCIATIVE_ARRAY temp_array BEGIN 
%array%
END
END"
		SPRINT new_wallgroups_file EVAL "%SOURCE_RES%_new_wallgroups"
		INNER_ACTION BEGIN
			<<<<<<<< .../%new_wallgroups_file%.tph
>>>>>>>>
			COPY ~.../%new_wallgroups_file%.tph~ ~%MOD_FOLDER%/lib/%new_wallgroups_file%.tph~
				INSERT_BYTES 0 (STRING_LENGTH ~%input_wallgroups%~)
				WRITE_ASCIIE 0 ~%input_wallgroups%~
		END
// applying include tph file
		PATCH_REINCLUDE ~%MOD_FOLDER%/lib/%new_wallgroups_file%.tph~

//2. c) Build the modified wall groups settings array and the new wall polygon index table.
		FOR (wallgp = 0 ; wallgp < wallgroups ; ++wallgp) BEGIN		// Looping through wall groups
			SET $EVAL delta("%wallgp%") = 0
		END

		SPRINT GW_List_wallgroup_polygons_index_file ""				// Initialise wall groups polygons index array
		FOR (wallgp = 0 ; wallgp < wallgroups ; ++wallgp) BEGIN		// Looping through wall groups
			SET GW_this_wallgroup_polygon_start = $wallgroup_new("%wallgp%" "start")
			SET GW_this_wallgroup_polygons_num = $wallgroup_new("%wallgp%" "index")
			LPF ~GW_BUILD_WALLGROUP_POLYGONS_INDEX_LIST~ INT_VAR GW_this_wallgroup_polygon_start GW_this_wallgroup_polygons_num RET GW_List_wallgroup_polygons_index_temp END
			SPRINT GW_List_wallgroup_polygons_index_file EVAL "%GW_List_wallgroup_polygons_index_file%%GW_List_wallgroup_polygons_index_temp%"
			PATCH_PHP_EACH temp_array AS data => p BEGIN
				PATCH_IF ("%data_0%" = "%wallgp%") BEGIN 
					SET $GW_new_polygon_index("%data_0%") = EVAL "%p%"
					SET $wallgroup_new("%wallgp%" "index") +=1 
					SET np = $GW_new_polygon_index("%data_0%")
					SPRINT GW_List_wallgroup_polygons_index_file EVAL "%GW_List_wallgroup_polygons_index_file%%p% "
					FOR (w = wallgp + 1 ; w < wallgroups ; ++w) BEGIN		// Looping through wall groups
						SET $EVAL delta("%w%") += 1
					END
				END
			END
		END	// of Looping through wall groups

		FOR (wallgp = 0 ; wallgp < wallgroups ; ++wallgp) BEGIN		// Looping through wall groups
			SET $EVAL wallgroup_new("%wallgp%" "start") = $EVAL wallgroup_new("%wallgp%" "start") + $EVAL delta("%wallgp%")
			SET cc = $EVAL wallgroup_new("%wallgp%" "start")
			SET dd = $EVAL wallgroup_new("%wallgp%" "index")
			PATCH_IF (wallgp = wallgroups - 1) BEGIN
				SET GW_new_last_polygon_index = $EVAL wallgroup_new("%wallgp%" "start") + $EVAL wallgroup_new("%wallgp%" "index") - 1
			END

// 2. d) Fix the wall groups settings
			SET wg_offset = GW_wed_wallgroups_off + (0x4 * wallgp)
			WRITE_SHORT	(wg_offset      )	$EVAL wallgroup_new("%wallgp%" "start")
			WRITE_SHORT	(wg_offset + 0x2)	$EVAL wallgroup_new("%wallgp%" "index")
			READ_SHORT	(wg_offset      )	GW_new_wed_wallgroup_polygon_start
			READ_SHORT	(wg_offset + 0x2)	GW_new_wed_wallgroup_polygons_num
		END	// of Looping through wall groups

// 2. e) Calculate the new wall polygon index to insert and insert them
		SET GW_delta_polygon_index = GW_new_last_polygon_index - GW_wed_wallgroups_polygons_num

		INSERT_BYTES GW_wed_vertices_off						(GW_wall_polygon_index_size * GW_delta_polygon_index)		// Insert new wall polygon index
		WRITE_LONG  (GW_wed_2dheader_off + GW_wed_vertices_of)	(GW_wed_vertices_off + (GW_wall_polygon_index_size * GW_delta_polygon_index))

// 2. f) Automatically write the fixed wall polygon index values
		SPRINT input_wed EVAL ~SET wall_polygon_index = 0
PATCH_FOR_EACH poly IN %GW_List_wallgroup_polygons_index_file% BEGIN
	SET poly_index = GW_wed_poly_lookup_table_off + (0x2 * wall_polygon_index)
	WRITE_SHORT poly_index poly
//LPF TO_HEX_NUMBER INT_VAR value = poly_index minDigits = 1 prefix = 1 RET poly_index_offset = hexNumber END
//PATCH_LOG "%SOURCE_FILE%	==>	Wall polygon index %wall_polygon_index% = %poly% ==> %poly_index_offset%"
	SET wall_polygon_index +=1
END~

		LPF ~GW_REINCLUDE~ STR_VAR input = EVAL "%input_wed%" END

	END	// of PATCH_IF (GW_Add_new_polygon) BEGIN

END		// of DEFINE_PATCH_FUNCTION


/* ========================================================================================================================================= *
 * FUNCTION GW_BUILD_WALLGROUP_POLYGONS_INDEX_LIST : CONSTRUCTION de la table des index de polygones des wallgroups d'un fichier WED.        *
 *						    						 BUILD the wall polygon index tables of a WED file.                                      *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * !!!!! ATTENTION - WARNING !!!!! : FONCTION EXPÉRIMENTALE - EXPERIMENTAL FUNCTION                                                          *
 *									 Pour l'instant, seul fonctionne l'ajout de polygones d'ouverture ou de fermeture à une porte existante. *
 *									 For now, it can only add open and closed door polygones to an existing door.                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * Explications : à faire                                                                                                                    *
 * Readme : to do                                                                                                                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * ========================================================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_BUILD_WALLGROUP_POLYGONS_INDEX_LIST~ 
	INT_VAR GW_this_wallgroup_polygon_start = 0
			GW_this_wallgroup_polygons_num  = 0
	RET 	GW_List_wallgroup_polygons_index_temp
BEGIN

	LPF ~GW_READ_WED_STRUCTURE~ RET	GW_wed_overlays_num GW_wed_doors_num GW_wed_overlays_off GW_wed_2dheader_off GW_wed_doors_off GW_wed_door_tilecell_off	// Header
									GW_wed_wall_polygons_num GW_wed_polygons_off GW_wed_vertices_off GW_wed_wallgroups_off GW_wed_poly_lookup_table_off END	// Secondary header
	READ_SHORT (GW_wed_polygons_off - 0x4) last_poly_index
	SPRINT GW_List_wallgroup_polygons_index_temp ""

// Build Wall polygon index list
	FOR (i = GW_this_wallgroup_polygon_start ; i < (GW_this_wallgroup_polygon_start + GW_this_wallgroup_polygons_num) ; ++i) BEGIN
		READ_SHORT (GW_wed_poly_lookup_table_off + (GW_wall_polygon_index_size * i)) poly_index
		SPRINT GW_List_wallgroup_polygons_index_temp EVAL "%GW_List_wallgroup_polygons_index_temp%%poly_index% "
	END
END


/* ========================================================================================================================================= *
 * FUNCTION GW_POLYGON_IN_WALLGROUP : DÉTERMINE dans quel wall group se trouve un polygone.                                                  *
 *						    		  FIND in which the wallgroup a polygon is set.                                                          *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * !!!!! ATTENTION - WARNING !!!!! : FONCTION EXPÉRIMENTALE - EXPERIMENTAL FUNCTION                                                          *
 *									 Pour l'instant, seul fonctionne l'ajout de polygones d'ouverture ou de fermeture à une porte existante. *
 *									 For now, it can only add open and closed door polygones to an existing door.                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * Explications : à faire                                                                                                                    *
 * Readme : to do                                                                                                                            *
 * ----------------------------------------------------------------------------------------------------------------------------------------- *
 * ========================================================================================================================================= */

DEFINE_PATCH_FUNCTION ~GW_POLYGON_IN_WALLGROUP~ 
INT_VAR GW_box = 0
		GW_vertice = 0
		GW_left = 0
		GW_right = 0
		GW_top = 0
		GW_bottom = 0
STR_VAR GW_all_wallgroups = "N"
RET		GW_match_wallgroup
BEGIN

	GW_match_wallgroup = 0
	PATCH_IF ("%GW_all_wallgroups%" STR_CMP "Y") BEGIN	// Check a specific wallgroup
		PATCH_IF GW_box BEGIN
			PATCH_IF
(
(GW_left >= $wallgroup("%SOURCE_RES%" "%wallgp%" "left")) AND (GW_left < $wallgroup("%SOURCE_RES%" "%wallgp%" "right")) AND (((GW_top >= $wallgroup("%SOURCE_RES%" "%wallgp%" "top")) AND (GW_top <= $wallgroup("%SOURCE_RES%" "%wallgp%" "bottom"))))
)
			BEGIN
				SET GW_match_wallgroup = 1
			END
		END	// of PATCH_IF GW_box

		PATCH_IF GW_vertice BEGIN
			PATCH_IF
(
((GW_left >= $wallgroup("%SOURCE_RES%" "%wallgp%" "left")) AND (GW_left < $wallgroup("%SOURCE_RES%" "%wallgp%" "right")) AND (((GW_top >= $wallgroup("%SOURCE_RES%" "%wallgp%" "top")) AND (GW_top <= $wallgroup("%SOURCE_RES%" "%wallgp%" "bottom")))))

)
			BEGIN
				SET GW_match_wallgroup = 1
			END
		END	// of GW_vertice

	END ELSE BEGIN													// Check all the wall groups
		FOR (wallgp = 0 ; wallgp < wallgroups ; ++wallgp) BEGIN		// Looping through wall groups
			PATCH_IF
(
(GW_left >= $wallgroup("%SOURCE_RES%" "%wallgp%" "left")) AND (GW_left < $wallgroup("%SOURCE_RES%" "%wallgp%" "right")) AND (((GW_top >= $wallgroup("%SOURCE_RES%" "%wallgp%" "top")) AND (GW_top <= $wallgroup("%SOURCE_RES%" "%wallgp%" "bottom"))))
)
			BEGIN
				SET GW_match_wallgroup = wallgp
				SET wallgp = wallgroups
			END
		END	// of Looping through wall groups

	END		// of Check all the wall groups

END			// of DEFINE_PATCH_FUNCTION
