DEFINE_PATCH_FUNCTION fj_add_are_structure
  INT_VAR
  is_bg2               = ENGINE_IS ~soa tob~
  is_pst               = ENGINE_IS pst
  is_id2               = ENGINE_IS iwd2
  fj_position          = 0x11c
  fj_itm_idx           = 0
  fj_vertex_idx        = 0
  off                  = 0
  num                  = 0
  off1                 = 0
  num1                 = 0
  key                  = 0
  value                = 0
  key1                 = 0
  value1               = 0
  fj_itm_con_off       = 0
  fj_return_offset     = 0
  // let's set up our variables! i++++ 4eva
  fj_box_left          = 0
  fj_box_top           = 0
  fj_box_right         = 0
  fj_box_bottom        = 0
  fj_flags             = 0
  fj_cursor_index      = 0
  fj_info_point_strref = ` 0
  fj_trap_detect       = 0
  fj_trap_remove       = 0
  fj_trap_active       = 0
  fj_trap_status       = 0
  fj_alt_x             = 0
  fj_alt_y             = 0
  fj_lock_diff         = 100
  fj_trap_detect_diff  = 0
  fj_trap_remove_diff  = 100
  fj_trap_loc_x        = 0
  fj_trap_loc_y        = 0
  fj_open_box_left     = 0
  fj_open_box_top      = 0
  fj_open_box_right    = 0
  fj_open_box_bottom   = 0
  fj_closed_box_left   = 0
  fj_closed_box_top    = 0
  fj_closed_box_right  = 0
  fj_closed_box_bottom = 0
  fj_cursor_idx        = 0
  fj_detect_diff       = 0
  fj_lock_diff         = 0
  fj_open_loc_x        = 0
  fj_open_loc_y        = 0
  fj_closed_loc_x      = 0
  fj_closed_loc_y      = 0
  fj_dialogue_strref   = ` 0
  fj_dest_x            = 0
  fj_dest_y            = 0
  fj_animation         = 0
  fj_orientation       = 0
  fj_spawned           = 0
  fj_expiry            = ` 0
  fj_schedule          = ` 0
  fj_num_talked        = 0
  fj_limit_rndwlk      = 0
  fj_loc_x             = 0
  fj_loc_y             = 0
  fj_loc_z             = 0
  fj_spawn_num         = 0
  fj_base_num          = 0
  fj_delay             = 0
  fj_method            = 0
  fj_max_num           = 0
  fj_enable            = 0
  fj_night_prob        = 0
  fj_lockpick_strref   = ` 0
  fj_itm_expiry        = 0
  fj_charge0           = 0
  fj_charge1           = 0
  fj_charge2           = 0
  fj_radius            = 0
  fj_height            = 0
  fj_volume            = 0
  fj_sound_num         = 0
  fj_delay             = 0
  fj_variation         = 0
  fj_bam_seq           = 0
  fj_bam_frame         = 0
  fj_transparent       = 0
  fj_init_frame        = 0
  fj_loop_chance       = 0
  fj_skip_cycles       = 0
  fj_strref_loc        = 1
  fj_color             = 0
  fj_note_id           = 0
  fj_note_strref       = ` 0
  fj_variable_value    = 0
  fj_eff_off           = 0
  fj_eff_size          = 0
  fj_missile_num       = 0
  fj_level_base        = 0
  fj_dunno             = 0
  fj_dunno1            = 0
  fj_caster_id         = 0
  STR_VAR
  fj_name              = ~~
  fj_destination_area  = ~~
  fj_destination_name  = ~~
  fj_key_resref        = ~~
  fj_reg_script        = ~~
  fj_trap_script       = ~~
  fj_key_resref        = ~~
  fj_door_wed_id       = ~~
  fj_door_open_wav     = ~~
  fj_door_close_wav    = ~~
  fj_key_resref        = ~~
  fj_door_script       = ~~
  fj_travel_trigger    = ~~
  fj_dialogue_resref   = ~~
  fj_dlg_resref        = ~~
  fj_bcs_override      = ~~
  fj_bcs_general       = ~~
  fj_bcs_class         = ~~
  fj_bcs_race          = ~~
  fj_bcs_default       = ~~
  fj_bcs_specific      = ~~
  fj_cre_resref        = ~~
  fj_cre_resref0       = ~~
  fj_cre_resref1       = ~~
  fj_cre_resref2       = ~~
  fj_cre_resref3       = ~~
  fj_cre_resref4       = ~~
  fj_cre_resref5       = ~~
  fj_cre_resref6       = ~~
  fj_cre_resref7       = ~~
  fj_cre_resref8       = ~~
  fj_cre_resref9       = ~~
  fj_wav_resref0       = ~~
  fj_wav_resref1       = ~~
  fj_wav_resref2       = ~~
  fj_wav_resref3       = ~~
  fj_wav_resref4       = ~~
  fj_wav_resref5       = ~~
  fj_wav_resref6       = ~~
  fj_wav_resref7       = ~~
  fj_wav_resref8       = ~~
  fj_wav_resref9       = ~~
  fj_bam_resref        = ~~
  fj_bmp_resref        = ~~
  fj_note_text         = ~~
  // internal string vars
  fj_structure_type    = ~~
  RET
  fj_return_offset
BEGIN
  PATCH_FOR_EACH value IN
    vertex door_open door_closed cell_closed cell_open
  BEGIN
    FOR (num = 0; VARIABLE_IS_SET EVAL ~fj_%value%_%num%~; num += 1) BEGIN
      SET $EVAL ~fj_%value%~(~%num%~) = EVAL ~fj_%value%_%num%~
    END
  END // otherwise WeiDU won't recognize that $num(0) == num_0
  CLEAR_ARRAY struct
  TEXT_SPRINT $struct(0x54 0x58 0x02 0x110) actor
  TEXT_SPRINT $struct(0x5c 0x5a 0x02 0x0c4) region
  TEXT_SPRINT $struct(0x60 0x64 0x04 0x0c8) spawn
  TEXT_SPRINT $struct(0x68 0x6c 0x04 0x068) entrance
  TEXT_SPRINT $struct(0x70 0x74 0x02 0x0c0) container
  TEXT_SPRINT $struct(0x78 0x76 0x02 0x014) itm
  TEXT_SPRINT $struct(0x84 0x82 0x02 0x0d4) ambient
  TEXT_SPRINT $struct(0x88 0x8c 0x02 0x054) variable
  TEXT_SPRINT $struct(0xa8 0xa4 0x04 0x0c8) door
  TEXT_SPRINT $struct(0xb8 0xb4 0x04 0x06c) tiled
  TEXT_SPRINT $struct(0x7c 0x80 0x02 0x004) vertex
  TEXT_SPRINT $struct(0xa0 0x9c 0x04 0x001) bitmask
  TEXT_SPRINT $struct(0xb0 0xac 0x04 0x04c) animation
  TEXT_SPRINT $struct(0xbc 0x00 0x00 0x090) songs
  TEXT_SPRINT $struct(0xc0 0x00 0x00 0x0e4) interrupts
  PATCH_IF is_pst BEGIN
    TEXT_SPRINT $struct(0xc8 0xcc 0x04 0x214) note
  END ELSE BEGIN
    TEXT_SPRINT $struct(0xc4 0xc8 0x04 0x034) note
  END
  TEXT_SPRINT $struct(0xcc 0xd0 0x02 0x01c) projectile
  PHP_EACH struct AS key => value BEGIN
    PATCH_IF ~%value%~ STRING_EQUAL_CASE ~%fj_structure_type%~ BEGIN
      SET fj_structure_type = key_0
    END
  END
  PATCH_IF is_id2 BEGIN
    READ_ASCII   0x54 id2_header (0x10)
    DELETE_BYTES 0x54 0x10
    PATCH_FOR_EACH off IN
      0x54 0x5c 0x60 0x68 0x70 0x78 0x7c 0x84
      0x88 0xa0 0xa8 0xb0 0xb8 0xbc 0xc0
    BEGIN
      PATCH_IF LONG_AT off > 0x00 BEGIN
        WRITE_LONG off LONG_AT off - 0x10
      END
    END
  END
  PATCH_FOR_EACH off IN
    0x54 0x5c 0x60 0x68 0x70 0x78 0x7c 0x84
    0x88 0xa0 0xa8 0xb0 0xb8 0xbc 0xc0
  BEGIN
    PATCH_IF !LONG_AT off  BEGIN
      WRITE_LONG off 0x11c
    END
  END
  PATCH_IF is_pst BEGIN
    PATCH_IF !LONG_AT 0xc8 BEGIN
      WRITE_LONG 0xc8 0x11c
    END
  END ELSE PATCH_IF is_bg2 BEGIN
    PATCH_FOR_EACH off IN 0xc4 0xcc BEGIN
      PATCH_IF !LONG_AT off BEGIN
        WRITE_LONG off 0x11c
      END
    END
  END
  PHP_EACH struct AS key => value BEGIN
    PATCH_IF LONG_AT key_0 BEGIN                      // skip it if the header offset points at 0
      PATCH_IF key_1 BEGIN                            // skip to later if it's a fixed size
        PATCH_IF key_0 != 0x78 && key_0 != 0x7c BEGIN // vertices and items get special handling
          PATCH_IF !(!is_bg2 && key_0 = 0xcc) &&      // only bg2 has projectile traps
            !(!is_bg2 && !is_pst && (key_0 = 0xc8 || key_0 = 0xc8))
          BEGIN                                       // and only bg2/pst have map notes
            CLEAR_ARRAY EVAL ~%value%~
            GET_OFFSET_ARRAY EVAL ~%value%~ key_0 0x04 key_1 key_2 0x00 0x00 key_3
            PHP_EACH ~%value%~ AS num => off BEGIN
              CLEAR_ARRAY array
              PATCH_IF key_0 != 0x5c && key_0 != 0x70 && key_0 != 0xa8 BEGIN
                READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3)
              END ELSE PATCH_IF key_0 = 0x5c BEGIN
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x2a 0x02 off + 0x2c 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_region_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x2c 0x00
                READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3)
              END ELSE PATCH_IF key_0 = 0x70 BEGIN
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x54 0x04 off + 0x50 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_container_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                GET_OFFSET_ARRAY array 0x78 0x04 off + 0x44 0x04 off + 0x40 0x04 0x14
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_ASCII off1 $EVAL ~are_container_%num%_itm~(~%num1%~) (0x14)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x50 0x00
                READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3)
                PATCH_IF fj_itm_con_off = off BEGIN
                  SET fj_itm_con_off = num
                END
              END ELSE PATCH_IF key_0 = 0xa8 BEGIN
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x30 0x02 off + 0x2c 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_door_open_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x2c 0x00
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x32 0x02 off + 0x34 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_door_closed_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x34 0x00
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x4c 0x02 off + 0x48 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_cell_closed_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x48 0x00
                GET_OFFSET_ARRAY array 0x7c 0x04 off + 0x4e 0x02 off + 0x50 0x04 0x04
                PHP_EACH array AS num1 => off1 BEGIN
                  READ_LONG off1 $EVAL ~are_cell_open_%num%_vertex~(~%num1%~)
                END
                CLEAR_ARRAY array
                WRITE_LONG off + 0x50 0x00
                READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3)
              END
              CLEAR_ARRAY array
            END
          END
          CLEAR_ARRAY EVAL ~%value%~
        END
      END ELSE BEGIN
        READ_ASCII LONG_AT key_0 $EVAL ~are_%value%~(0) (key_3)
      END
    END
  END
  DELETE_BYTES 0x11c BUFFER_LENGTH - 0x11c
  PHP_EACH struct AS key => value BEGIN
    PATCH_IF key_2 = 0x02 BEGIN
      WRITE_SHORT key_1 0x00
    END ELSE PATCH_IF key_2 = 0x04 BEGIN
      WRITE_LONG  key_1 0x00
    END
  END
  PHP_EACH struct AS key => value BEGIN
    WRITE_LONG key_0 fj_position
    PATCH_IF key_0 != 0x78 && key_0 != 0x7c BEGIN
      PHP_EACH ~are_%value%~ AS key1 => value1 BEGIN
        PATCH_IF key_2 = 0x02 BEGIN
          WRITE_SHORT key_1 SHORT_AT key_1 + 0x01
        END ELSE PATCH_IF key_2 = 0x04 BEGIN
          WRITE_LONG  key_1 LONG_AT  key_1 + 0x01
        END
        INSERT_BYTES fj_position key_3
        WRITE_ASCIIE fj_position ~%value1%~
        SET fj_position += key_3
      END
      PATCH_IF key_0 = fj_structure_type BEGIN
        PATCH_IF key_2 = 0x02 BEGIN
          WRITE_SHORT key_1 SHORT_AT key_1 + 0x01
        END ELSE PATCH_IF key_2 = 0x04 BEGIN
          WRITE_LONG  key_1 LONG_AT  key_1 + 0x01
        END
        SET fj_return_offset = fj_position
        INSERT_BYTES fj_position key_3
        PATCH_IF fj_structure_type = 0x54 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_SHORT  fj_position + 0x24 fj_dest_loc_x
          WRITE_SHORT  fj_position + 0x26 fj_dest_loc_y
          WRITE_LONG   fj_position + 0x28 fj_flags
          WRITE_LONG   fj_position + 0x2c fj_spawned
          WRITE_LONG   fj_position + 0x30 fj_animation
          WRITE_LONG   fj_position + 0x34 fj_orientation
          WRITE_LONG   fj_position + 0x38 fj_expiry
          WRITE_SHORT  fj_position + 0x3c fj_limit_rndwlk
          WRITE_LONG   fj_position + 0x40 fj_schedule
          WRITE_LONG   fj_position + 0x44 fj_num_talked
          WRITE_ASCIIE fj_position + 0x48 ~%fj_dlg_resref%~
          WRITE_ASCIIE fj_position + 0x50 ~%fj_bcs_override%~
          WRITE_ASCIIE fj_position + 0x58 ~%fj_bcs_general%~
          WRITE_ASCIIE fj_position + 0x60 ~%fj_bcs_class%~
          WRITE_ASCIIE fj_position + 0x68 ~%fj_bcs_race%~
          WRITE_ASCIIE fj_position + 0x70 ~%fj_bcs_default%~
          WRITE_ASCIIE fj_position + 0x78 ~%fj_bcs_specific%~
          WRITE_ASCIIE fj_position + 0x80 ~%fj_cre_resref%~
        END ELSE PATCH_IF fj_structure_type = 0x5c BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_SHORT  fj_position + 0x20 fj_type
          WRITE_SHORT  fj_position + 0x22 fj_box_left
          WRITE_SHORT  fj_position + 0x24 fj_box_top
          WRITE_SHORT  fj_position + 0x26 fj_box_right
          WRITE_SHORT  fj_position + 0x28 fj_box_bottom
          WRITE_LONG   fj_position + 0x34 fj_cursor_index
          WRITE_ASCIIE fj_position + 0x38 ~%fj_destination_area%~ #8
          WRITE_ASCIIE fj_position + 0x40 ~%fj_destination_name%~ #32
          WRITE_LONG   fj_position + 0x60 fj_flags
          WRITE_LONG   fj_position + 0x64 fj_info_point_strref
          WRITE_SHORT  fj_position + 0x68 fj_trap_detect
          WRITE_SHORT  fj_position + 0x6a fj_trap_remove
          WRITE_SHORT  fj_position + 0x6c fj_trap_active
          WRITE_SHORT  fj_position + 0x6e fj_trap_status
          WRITE_SHORT  fj_position + 0x70 fj_loc_x
          WRITE_SHORT  fj_position + 0x72 fj_loc_y
          WRITE_ASCIIE fj_position + 0x74 ~%fj_key_resref%~ #8
          WRITE_ASCIIE fj_position + 0x7c ~%fj_reg_script%~ #8
          WRITE_SHORT  fj_position + 0x84 fj_alt_x
          WRITE_SHORT  fj_position + 0x86 fj_alt_y
          PHP_EACH fj_vertex AS key1 => value1 BEGIN
            WRITE_SHORT fj_position + 0x2a SHORT_AT (fj_position + 0x2a) + 0x01
          END
        END ELSE PATCH_IF fj_structure_type = 0x60 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_ASCIIE fj_position + 0x24 ~%fj_cre_resref0%~ #8
          WRITE_ASCIIE fj_position + 0x2c ~%fj_cre_resref1%~ #8
          WRITE_ASCIIE fj_position + 0x34 ~%fj_cre_resref2%~ #8
          WRITE_ASCIIE fj_position + 0x3c ~%fj_cre_resref3%~ #8
          WRITE_ASCIIE fj_position + 0x44 ~%fj_cre_resref4%~ #8
          WRITE_ASCIIE fj_position + 0x4c ~%fj_cre_resref5%~ #8
          WRITE_ASCIIE fj_position + 0x54 ~%fj_cre_resref6%~ #8
          WRITE_ASCIIE fj_position + 0x5c ~%fj_cre_resref7%~ #8
          WRITE_ASCIIE fj_position + 0x64 ~%fj_cre_resref8%~ #8
          WRITE_ASCIIE fj_position + 0x6c ~%fj_cre_resref9%~ #8
          WRITE_SHORT  fj_position + 0x74 fj_spawn_num
          WRITE_SHORT  fj_position + 0x76 fj_base_num
          WRITE_SHORT  fj_position + 0x78 fj_delay
          WRITE_SHORT  fj_position + 0x7a fj_method
          WRITE_SHORT  fj_position + 0x84 fj_max_num
          WRITE_SHORT  fj_position + 0x86 fj_enable
          WRITE_LONG   fj_position + 0x88 fj_schedule
          WRITE_SHORT  fj_position + 0x8e fj_night_prob
        END ELSE PATCH_IF fj_structure_type = 0x68 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #20
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_SHORT  fj_position + 0x24 fj_orientation
        END ELSE PATCH_IF fj_structure_type = 0x70 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_SHORT  fj_position + 0x24 fj_type
          WRITE_SHORT  fj_position + 0x26 fj_lock_diff
          WRITE_LONG   fj_position + 0x28 fj_flags
          WRITE_SHORT  fj_position + 0x2c fj_trap_detect_diff
          WRITE_SHORT  fj_position + 0x2e fj_trap_remove_diff
          WRITE_SHORT  fj_position + 0x30 fj_trap_active
          WRITE_SHORT  fj_position + 0x32 fj_trap_status
          WRITE_SHORT  fj_position + 0x34 fj_trap_loc_x
          WRITE_SHORT  fj_position + 0x36 fj_trap_loc_y
          WRITE_SHORT  fj_position + 0x38 fj_box_left
          WRITE_SHORT  fj_position + 0x3a fj_box_top
          WRITE_SHORT  fj_position + 0x3c fj_box_right
          WRITE_SHORT  fj_position + 0x3e fj_box_bottom
          WRITE_ASCIIE fj_position + 0x48 ~%fj_trap_script%~ #8
          WRITE_ASCIIE fj_position + 0x78 ~%fj_key_resref%~ #8
          WRITE_LONG   fj_position + 0x84 fj_lockpick_strref
          PHP_EACH fj_vertex AS key1 => value1 BEGIN
            WRITE_LONG fj_position + 0x54 LONG_AT (fj_position + 0x54) + 0x01
          END
        END ELSE PATCH_IF fj_structure_type = 0x78 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #8
          WRITE_SHORT  fj_position + 0x08 fj_itm_expiry
          WRITE_SHORT  fj_position + 0x0a fj_charge0
          WRITE_SHORT  fj_position + 0x0c fj_charge1
          WRITE_SHORT  fj_position + 0x0e fj_charge2
          WRITE_LONG   fj_position + 0x10 fj_flags
        END ELSE PATCH_IF fj_structure_type = 0x84 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_SHORT  fj_position + 0x24 fj_radius
          WRITE_SHORT  fj_position + 0x26 fj_loc_z
          WRITE_SHORT  fj_position + 0x2e fj_volume
          WRITE_ASCIIE fj_position + 0x30 ~%fj_wav_resref0%~ #8
          WRITE_ASCIIE fj_position + 0x38 ~%fj_wav_resref1%~ #8
          WRITE_ASCIIE fj_position + 0x40 ~%fj_wav_resref2%~ #8
          WRITE_ASCIIE fj_position + 0x48 ~%fj_wav_resref3%~ #8
          WRITE_ASCIIE fj_position + 0x50 ~%fj_wav_resref4%~ #8
          WRITE_ASCIIE fj_position + 0x58 ~%fj_wav_resref5%~ #8
          WRITE_ASCIIE fj_position + 0x60 ~%fj_wav_resref6%~ #8
          WRITE_ASCIIE fj_position + 0x68 ~%fj_wav_resref7%~ #8
          WRITE_ASCIIE fj_position + 0x70 ~%fj_wav_resref8%~ #8
          WRITE_ASCIIE fj_position + 0x78 ~%fj_wav_resref9%~ #8
          WRITE_SHORT  fj_position + 0x80 fj_sound_num
          WRITE_LONG   fj_position + 0x84 fj_delay
          WRITE_LONG   fj_position + 0x88 fj_variation
          WRITE_LONG   fj_position + 0x8c fj_schedule
          WRITE_LONG   fj_position + 0x90 fj_flags
        END ELSE PATCH_IF fj_structure_type = 0x88 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #20
          WRITE_LONG   fj_position + 0x28 fj_variable_value
        END ELSE PATCH_IF fj_structure_type = 0xa4 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_ASCIIE fj_position + 0x20 ~%fj_door_wed_id%~
          WRITE_LONG   fj_position + 0x28 fj_flags
          WRITE_SHORT  fj_position + 0x38 fj_open_box_left
          WRITE_SHORT  fj_position + 0x3a fj_open_box_top
          WRITE_SHORT  fj_position + 0x3c fj_open_box_right
          WRITE_SHORT  fj_position + 0x3e fj_open_box_bottom
          WRITE_SHORT  fj_position + 0x40 fj_closed_box_left
          WRITE_SHORT  fj_position + 0x42 fj_closed_box_top
          WRITE_SHORT  fj_position + 0x44 fj_closed_box_right
          WRITE_SHORT  fj_position + 0x46 fj_closed_box_bottom
          WRITE_ASCIIE fj_position + 0x58 ~%fj_door_open_wav%~
          WRITE_ASCIIE fj_position + 0x60 ~%fj_door_close_wav%~
          WRITE_LONG   fj_position + 0x68 fj_cursor_idx
          WRITE_SHORT  fj_position + 0x6c fj_trap_detect_diff
          WRITE_SHORT  fj_position + 0x6e fj_trap_remove_diff
          WRITE_SHORT  fj_position + 0x70 fj_trap_active
          WRITE_SHORT  fj_position + 0x72 fj_trap_status
          WRITE_SHORT  fj_position + 0x74 fj_trap_loc_x
          WRITE_SHORT  fj_position + 0x76 fj_trap_loc_y
          WRITE_ASCIIE fj_position + 0x78 ~%fj_key_resref%~
          WRITE_ASCIIE fj_position + 0x80 ~%fj_door_script%~
          WRITE_LONG   fj_position + 0x88 fj_detect_diff
          WRITE_LONG   fj_position + 0x8c fj_lock_diff
          WRITE_SHORT  fj_position + 0x90 fj_open_loc_x
          WRITE_SHORT  fj_position + 0x92 fj_open_loc_y
          WRITE_SHORT  fj_position + 0x94 fj_closed_loc_x
          WRITE_SHORT  fj_position + 0x96 fj_closed_loc_y
          WRITE_LONG   fj_position + 0x98 fj_lockpick_strref
          WRITE_ASCIIE fj_position + 0x9c ~%fj_travel_trigger%~ #16
          WRITE_LONG   fj_position + 0xbc fj_dialogue_strref
          WRITE_ASCIIE fj_position + 0xc0 ~%fj_dialogue_resref%~
          PHP_EACH fj_door_open_vert   AS key1 => value1 BEGIN
            WRITE_SHORT fj_position + 0x30 SHORT_AT (fj_position + 0x30) + 0x01
          END
          PHP_EACH fj_door_closed_vert AS key1 => value1 BEGIN
            WRITE_SHORT fj_position + 0x32 SHORT_AT (fj_position + 0x32) + 0x01
          END
          PHP_EACH fj_cell_closed_vert AS key1 => value1 BEGIN
            WRITE_SHORT fj_position + 0x4c SHORT_AT (fj_position + 0x4c) + 0x01
          END
          PHP_EACH fj_cell_open_vert   AS key1 => value1 BEGIN
            WRITE_SHORT fj_position + 0x4e SHORT_AT (fj_position + 0x4e) + 0x01
          END
        END ELSE PATCH_IF fj_structure_type = 0xb0 BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #32
          WRITE_SHORT  fj_position + 0x20 fj_loc_x
          WRITE_SHORT  fj_position + 0x22 fj_loc_y
          WRITE_LONG   fj_position + 0x24 fj_schedule
          WRITE_ASCIIE fj_position + 0x28 ~%fj_bam_resref%~ #8
          WRITE_SHORT  fj_position + 0x30 fj_bam_seq
          WRITE_SHORT  fj_position + 0x32 fj_bam_frame
          WRITE_LONG   fj_position + 0x34 fj_flags
          WRITE_SHORT  fj_position + 0x38 fj_loc_z
          WRITE_SHORT  fj_position + 0x3a fj_transparent
          WRITE_SHORT  fj_position + 0x3c fj_init_frame
          WRITE_BYTE   fj_position + 0x3e fj_loop_chance
          WRITE_BYTE   fj_position + 0x3f fj_skip_cycles
          WRITE_ASCIIE fj_position + 0x40 ~%fj_bmp_resref%~ #8
        END ELSE PATCH_IF fj_structure_type = 0xc4 BEGIN
          WRITE_SHORT  fj_position + 0x00 fj_loc_x
          WRITE_SHORT  fj_position + 0x02 fj_loc_y
          WRITE_LONG   fj_position + 0x04 fj_note_strref
          WRITE_SHORT  fj_position + 0x08 fj_strref_loc
          WRITE_SHORT  fj_position + 0x0a fj_color
          WRITE_LONG   fj_position + 0x0c fj_note_id
        END ELSE PATCH_IF fj_structure_type = 0xc8 BEGIN
          WRITE_LONG   fj_position + 0x000 fj_loc_x
          WRITE_LONG   fj_position + 0x004 fj_loc_y
          WRITE_ASCIIE fj_position + 0x008 ~%fj_note_text%~
          WRITE_LONG   fj_position + 0x1fc fj_color
        END ELSE PATCH_IF fj_structure_type = 0xcc BEGIN
          WRITE_ASCIIE fj_position + 0x00 ~%name%~ #8
          WRITE_LONG   fj_position + 0x08 fj_eff_off
          WRITE_SHORT  fj_position + 0x0c fj_eff_size
          WRITE_SHORT  fj_position + 0x0e fj_missile_num
          WRITE_LONG   fj_position + 0x10 fj_level_base
          WRITE_SHORT  fj_position + 0x14 fj_loc_x
          WRITE_SHORT  fj_position + 0x16 fj_loc_y
          WRITE_SHORT  fj_position + 0x18 fj_dunno
          WRITE_BYTE   fj_position + 0x1a fj_dunno1
          WRITE_BYTE   fj_position + 0x1b fj_caster_id
        END
        SET fj_position += key_3
      END
    END ELSE PATCH_IF key_0 = 0x78 BEGIN
      PHP_EACH are_container AS num => structure BEGIN
        WRITE_LONG LONG_AT 0x70 + 0xc0 * num + 0x40 fj_itm_idx
        PHP_EACH ~are_container_%num%_itm~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x14
          WRITE_ASCIIE fj_position ~%value1%~
          WRITE_SHORT  0x76     SHORT_AT 0x76 + 0x01
          SET fj_itm_idx += 0x01
          SET fj_position  += key_3
        END
        PATCH_IF fj_structure_type = 0x78 BEGIN
          PATCH_IF num = fj_itm_con_off BEGIN
            WRITE_LONG LONG_AT 0x70 + 0xc0 * num + 0x44
              LONG_AT (LONG_AT 0x70 + 0xc0 * num + 0x44) + 0x01
            WRITE_SHORT  0x76     SHORT_AT 0x76 + 0x01
            INSERT_BYTES fj_position key_3
            WRITE_ASCIIE fj_position + 0x00 ~%fj_name%~ #8
            WRITE_SHORT  fj_position + 0x08 fj_itm_expiry
            WRITE_SHORT  fj_position + 0x0a fj_charge0
            WRITE_SHORT  fj_position + 0x0c fj_charge1
            WRITE_SHORT  fj_position + 0x0e fj_charge2
            WRITE_LONG   fj_position + 0x10 fj_flags
            SET fj_itm_idx += 0x01
            SET fj_position  += key_3
          END
        END
      END
    END ELSE PATCH_IF key_0 = 0x7c BEGIN
      PHP_EACH are_region    AS num => structure BEGIN
        WRITE_LONG LONG_AT 0x5c + 0xc4 * num + 0x2c fj_vertex_idx
        PHP_EACH ~are_region_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += key_3
        END
      END
      PATCH_IF fj_structure_type = 0x5c BEGIN
        WRITE_LONG fj_return_offset + 0x2c fj_vertex_idx
        PHP_EACH fj_vertex AS num => off BEGIN
          SET fj_vertex_idx += 0x01
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          INSERT_BYTES fj_position 0x04
        END
        PHP_EACH fj_vertex AS num => off BEGIN
          WRITE_LONG fj_position off
          SET fj_position += 0x04
        END
      END
      PHP_EACH are_container AS num => structure BEGIN
        WRITE_LONG LONG_AT 0x70 + 0xc0 * num + 0x50 fj_vertex_idx
        PHP_EACH ~are_container_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += 0x04
        END
      END
      PATCH_IF fj_structure_type = 0x70 BEGIN
        WRITE_LONG fj_return_offset + 0x50 fj_vertex_idx
        PHP_EACH fj_vertex AS num => off BEGIN
          SET fj_vertex_idx += 0x01
          INSERT_BYTES fj_position 0x04
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
        END
        PHP_EACH fj_vertex AS num => off BEGIN
          WRITE_LONG fj_position off
          SET fj_position += 0x04
        END
      END
      PHP_EACH are_door      AS num => structure BEGIN
        WRITE_LONG LONG_AT 0xa8 + 0xc8 * num + 0x2c fj_vertex_idx
        PHP_EACH ~are_door_open_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += 0x04
        END
        WRITE_LONG LONG_AT 0xa8 + 0xc8 * num + 0x34 fj_vertex_idx
        PHP_EACH ~are_door_closed_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += 0x04
        END
        WRITE_LONG LONG_AT 0xa8 + 0xc8 * num + 0x48 fj_vertex_idx
        PHP_EACH ~are_cell_closed_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += 0x04
        END
        WRITE_LONG LONG_AT 0xa8 + 0xc8 * num + 0x50 fj_vertex_idx
        PHP_EACH ~are_cell_open_%num%_vertex~ AS num1 => value1 BEGIN
          INSERT_BYTES fj_position 0x04
          WRITE_LONG   fj_position value1
          WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          SET fj_vertex_idx += 0x01
          SET fj_position += 0x04
        END
      END
      PATCH_IF fj_structure_type = 0xa8 BEGIN
        WRITE_LONG fj_return_offset + 0x2c fj_vertex_idx
        WRITE_LONG fj_return_offset + 0x34
          LONG_AT (fj_return_offset + 0x2c) + SHORT_AT (fj_return_offset + 0x30)
        WRITE_LONG fj_return_offset + 0x48
          LONG_AT (fj_return_offset + 0x34) + SHORT_AT (fj_return_offset + 0x32)
        WRITE_LONG fj_return_offset + 0x50
          LONG_AT (fj_return_offset + 0x48) + SHORT_AT (fj_return_offset + 0x4e)
        PATCH_FOR_EACH vertex_type IN
          door_open door_closed cell_closed cell_open
        BEGIN
          PHP_EACH ~fj_%vertex_type%_vert~ AS num => off BEGIN
            INSERT_BYTES fj_position 0x04
            WRITE_SHORT  0x80     SHORT_AT 0x80 + 0x01
          END
          PHP_EACH ~fj_%vertex_type%_vert~ AS num => off BEGIN
            WRITE_LONG fj_position off
            SET fj_position += 0x04
          END
        END
      END
    END
  END
  PATCH_IF is_id2 BEGIN
    PATCH_FOR_EACH off IN
      0x54 0x5c 0x60 0x68 0x70 0x78 0x7c 0x84
      0x88 0xa0 0xa8 0xb0 0xb8 0xbc 0xc0
    BEGIN
      WRITE_LONG off LONG_AT off + 0x10
    END
    INSERT_BYTES 0x54 0x10
    WRITE_ASCIIE 0x54 ~%id2_header%~
  END
  PHP_EACH are_region    AS key => value BEGIN
    CLEAR_ARRAY EVAL ~are_region_%key%_vertex~
  END
  PHP_EACH are_container AS key => value BEGIN
    PATCH_FOR_EACH off IN vertex itm BEGIN
      CLEAR_ARRAY EVAL ~are_container_%key%_%off%~
    END
  END
  PHP_EACH are_door      AS key => value BEGIN
    PATCH_FOR_EACH off IN
      door_open door_closed cell_closed cell_open
    BEGIN
      CLEAR_ARRAY EVAL ~are_%off%_%key%_vertex~
    END
  END
  PHP_EACH struct        AS key => value BEGIN
    CLEAR_ARRAY EVAL ~are_%value%~
  END
  CLEAR_ARRAY struct
END
