DEFINE_PATCH_FUNCTION fj_are_structure // let's set up our variables! i++++ 4eva INT_VAR // these are internal variables, not to be used as input 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_return_offset = 0 fj_deleted = 0 // instead of adding fj_structure_type, delete if num == fj_delete_mode fj_delete_mode = ` 0 // offsets to various structures unpointed at zero fj_unzero_header_off = 0 // spams your console with psuedoinformative nonsense fj_debug = 0 // actors fj_loc_x = 0 fj_loc_y = 0 fj_dest_x = 0 fj_dest_y = 0 fj_loading = 1 fj_spawned = 0 fj_animation = 0 fj_orientation = 0 fj_expiry = ` 0 fj_wander_dist_actor = 0 fj_mvmt_dist_actor = 0 fj_schedule = ` 0 fj_num_talked = 0 // regions fj_type = 0 fj_box_left = 0 fj_box_top = 0 fj_box_right = 0 fj_box_bottom = 0 fj_cursor_idx = 0 fj_flags = 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 // spawns fj_spawn_num = 0 fj_difficulty = 0 fj_delay = 10 fj_method = 0 fj_duration = 1000 fj_wander_dist_spawn = 1000 fj_mvmt_dist_spawn = 1000 fj_max_num = 0 fj_enable = 1 fj_day_prob = 100 fj_night_prob = 100 // containers fj_lock_diff = 100 fj_trap_remove_diff = 100 fj_trap_loc_x = 0 fj_trap_loc_y = 0 fj_lockpick_strref = ` 0 // items fj_con_itm_idx = ` 0 fj_itm_expiry = 0 fj_charge0 = 0 fj_charge1 = 0 fj_charge2 = 0 // ambients fj_radius = 500 fj_loc_z = 0 fj_volume = 80 fj_sound_num = 0 fj_delay = 0 fj_variation = 0 // variables fj_variable_value = 0 // doors 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_detect_diff = 0 fj_locked_diff = 0 fj_open_loc_x = 0 fj_open_loc_y = 0 fj_closed_loc_x = 0 fj_closed_loc_y = 0 fj_dlg_strref = ` 0 // animations fj_bam_seq = 0 fj_bam_frame = 0 fj_transparent = 0 fj_init_frame = 0 fj_loop_chance = 0 fj_skip_cycles = 0 // songs fj_song_day = 0 fj_song_night = 0 fj_song_victory = 0 fj_song_battle = 0 fj_song_defeat = 0 fj_song_day_vol = 100 fj_song_night_vol = 100 fj_song_reverb = 0 // rest interrupts fj_cre_strref0 = ` 0 fj_cre_strref1 = ` 0 fj_cre_strref2 = ` 0 fj_cre_strref3 = ` 0 fj_cre_strref4 = ` 0 fj_cre_strref5 = ` 0 fj_cre_strref6 = ` 0 fj_cre_strref7 = ` 0 fj_cre_strref8 = ` 0 fj_cre_strref9 = ` 0 // map notes fj_note_strref = ` 0 fj_strref_loc = 1 fj_color = 0 fj_note_id = 0 // embedded projectiles fj_missile_num = ` 0 fj_frequency = 0 fj_target = 0 STR_VAR // variables fj_structure_type = ~~ fj_name = ~~ // actors 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_embedded = ~~ // regions fj_destination_area = ~~ fj_destination_name = ~~ fj_key_resref = ~~ fj_reg_script = ~~ // spawns 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 = ~~ // containers fj_trap_script = ~~ // ambients 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 = ~~ // doors fj_door_wed_id = ~~ fj_door_open_wav = ~~ fj_door_close_wav = ~~ fj_door_script = ~~ fj_travel_trigger = ~~ // animations fj_bam_resref = ~~ fj_bmp_resref = ~~ //bitmask fj_bitmask = ~~ // songs fj_song_day0 = ~~ fj_song_day1 = ~~ fj_song_night0 = ~~ fj_song_night1 = ~~ // map notes fj_note_text = ~~ // only for PST RET fj_return_offset BEGIN // we must set $num(0) == num_0 when using function input // otherwise WeiDU won't recognize that they're synonymous PATCH_FOR_EACH value IN vertex door_open_vert door_closed_vert cell_open_vert cell_closed_vert BEGIN FOR( num = 0 ; VARIABLE_IS_SET EVAL ~fj_%value%_%num%~ ; ++num )BEGIN SET $EVAL ~fj_%value%~(~%num%~) = EVAL ~fj_%value%_%num%~ END END FOR( num = 0 ; VARIABLE_IS_SET EVAL ~fj_embedded_eff_%num%~ ; ++num )BEGIN TEXT_SPRINT $fj_embedded_eff(~%num%~) EVAL ~%fj_embedded_eff_%num%%~ END // php over this array rather than an explicit list to reduce code length and typos 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(0xb0 0xac 0x04 0x04c) animation TEXT_SPRINT $struct(0xa0 0x9c 0x04 0x000) bitmask 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 // Icewind Dale II decided to be uselessly special 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 BEGIN WRITE_LONG off THIS - 0x10 END END END PATCH_IF fj_unzero_header_off BEGIN // a small courtesy to fix areas missing obligatory structures PATCH_IF fj_delete_mode == ` 0 BEGIN PATCH_IF !LONG_AT 0xbc && fj_structure_type != 0xbc BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Offset to songlist points to 0! Adding empty songlist.~ END WRITE_LONG 0xbc BUFFER_LENGTH INSERT_BYTES BUFFER_LENGTH 0x90 END PATCH_IF !LONG_AT 0xc0 && fj_structure_type != 0xc0 BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Offset to rest interrupts points to 0! Adding empty rest interrupt table.~ END WRITE_LONG 0xc0 BUFFER_LENGTH INSERT_BYTES BUFFER_LENGTH 0xe4 END END // offsets to valid structures should not point to 0 PATCH_FOR_EACH off IN 0x54 0x5c 0x60 0x68 0x70 0x78 0x7c 0x84 0x88 0xa0 0xa8 0xb0 0xb8 BEGIN PATCH_IF !LONG_AT off BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Header offset %off% points to 0, setting to 0x11c.~ END WRITE_LONG off 0x11c END END PATCH_IF is_pst BEGIN PATCH_IF !LONG_AT 0xc8 BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Header offset 0xc8 points to 0, setting to 0x11c.~ END 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 PATCH_IF fj_debug BEGIN PATCH_PRINT ~Header offset %off% points to 0, setting to 0x11c.~ END WRITE_LONG off 0x11c END END END END // long block to read all the existing data PATCH_IF fj_debug BEGIN PATCH_PRINT ~Beginning unmarshalling.~ END PHP_EACH struct AS key => value BEGIN PATCH_IF( LONG_AT key_0 )BEGIN // skip it if the header offset points at 0 CLEAR_ARRAY EVAL ~%value%~ GET_OFFSET_ARRAY EVAL ~%value%~ key_0 0x04 key_1 key_2 0x00 0x00 key_3 // e.g. $region PHP_EACH ~%value%~ AS num => off BEGIN CLEAR_ARRAY array PATCH_IF( key_0 == 0x54 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading actor %num%.~ END PATCH_IF!( LONG_AT (off + 0x28) & 0x01 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~ Associating embedded creature.~ END READ_ASCII LONG_AT (off + 0x88) $are_embedded_cre(~%num%~) (LONG_AT (off + 0x8c)) END WRITE_LONG off + 0x88 0 READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0x5c )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading region %num%.~ END PATCH_IF( fj_debug && SHORT_AT ( off + 0x2a ) )BEGIN PATCH_PRINT ~ Associating vertices.~ END 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 == 0x60 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading spawn %num%~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0x68 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading entrance %num%~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0x70 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading container %num%.~ END // load container vertices GET_OFFSET_ARRAY array 0x7c 0x04 (off + 0x54) 0x04 (off + 0x50) 0x04 0x04 PATCH_IF( fj_debug && LONG_AT 0x54 )BEGIN PATCH_PRINT ~ Associating vertices.~ END PHP_EACH array AS num1 => off1 BEGIN READ_LONG off1 $EVAL ~are_container_%num%_vertex~(~%num1%~) END CLEAR_ARRAY array // load container items GET_OFFSET_ARRAY array 0x78 0x04 (off + 0x44) 0x04 (off + 0x40) 0x04 0x14 PATCH_IF( fj_debug && LONG_AT 0x44 )BEGIN PATCH_PRINT ~ Associating items.~ END PHP_EACH array AS num1 => off1 BEGIN READ_ASCII off1 $EVAL ~are_container_%num%_itm~(~%num1%~) (0x14) END CLEAR_ARRAY array // read container structure WRITE_LONG off + 0x40 0x00 // wipe item index WRITE_LONG off + 0x44 0x00 // wipe item count WRITE_LONG off + 0x50 0x00 // wipe vertex index READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE // items are read off with their associated containers PATCH_IF( key_0 == 0x78 )BEGIN END ELSE PATCH_IF( key_0 == 0x84 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading ambient %num%~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0x88 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading variable %num%~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0xa8 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading door %num% and associated vertices.~ END // load door open vertices 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 // load door closed vertices 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 // load cell open vertices 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_open_%num%_vertex~(~%num1%~) END CLEAR_ARRAY array WRITE_LONG off + 0x48 0x00 // load cell closed vertices 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_closed_%num%_vertex~(~%num1%~) END CLEAR_ARRAY array WRITE_LONG off + 0x50 0x00 // read the door structure itself READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0xb8 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading tiled object %num% (something is probably very wrong).~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE // vertices, these are read off with their associated regions/containers/doors PATCH_IF( key_0 == 0x78 )BEGIN END ELSE PATCH_IF( key_0 == 0xb0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading animation %num%.~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( ( key_0 == 0xc4 && is_bg2 ) || ( key_0 == 0xc8 && is_pst) )BEGIN // PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading map note %num%.~ END READ_ASCII off $EVAL ~are_%value%~(~%num%~) (key_3) END ELSE PATCH_IF( key_0 == 0xcc && is_bg2 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading projectile %num%.~ END READ_ASCII off $are_projectile(~%num%~) (key_3) PATCH_IF SHORT_AT (off + 0x0c) BEGIN PATCH_IF( fj_debug )BEGIN PATCH_PRINT ~ Associating v2 embedded effects.~ END READ_ASCII LONG_AT (off + 0x08) $are_embedded_eff(~%num%~) (SHORT_AT (off + 0x0c)) END END END // php_each ~%value%~ CLEAR_ARRAY array CLEAR_ARRAY EVAL ~%value%~ // single structures // bitmask PATCH_IF( key_0 == 0xa0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading bitmask (should only exist in saved game areas).~ END READ_ASCII LONG_AT 0xa0 $are_bitmask(0) (LONG_AT 0x9c) END ELSE // songs PATCH_IF( key_0 == 0xbc )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading songs (obligatory structure).~ END READ_ASCII LONG_AT 0xbc $are_songs(0) (0x90) END ELSE // rest interrupts PATCH_IF( key_0 == 0xc0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reading rest interrupt table (obligatory structure).~ END READ_ASCII LONG_AT 0xc0 $are_interrupts(0) (0xe4) END END // skip if key_0 points to 0 END // end php_each $structure: all extended structures now loaded in buffer PATCH_IF fj_debug BEGIN PATCH_PRINT ~Trimming %SOURCE_FILE% down to the header.~ 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 PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassembling %SOURCE_FILE%.~ END PHP_EACH struct AS key => value BEGIN WRITE_LONG key_0 fj_position PHP_EACH ~are_%value%~ AS key1 => value1 BEGIN PATCH_IF( key_0 != 0xa0 && key_0 != 0xbc && key_0 != 0xc0 )BEGIN PATCH_IF( key1 != fj_delete_mode || fj_structure_type != key_0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reinserting %value% number %key1%.~ END PATCH_IF( key_2 == 0x02 )BEGIN WRITE_SHORT key_1 THIS + 0x01 END ELSE PATCH_IF( key_2 == 0x04 )BEGIN WRITE_LONG key_1 THIS + 0x01 END INSERT_BYTES fj_position key_3 WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += key_3 END END ELSE PATCH_IF( key_0 == 0xa0 && fj_structure_type != key_0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reinserting %value% number %key1%.~ END TEXT_SPRINT value1 $are_bitmask(0) WRITE_LONG 0x9c STRING_LENGTH EVAL ~%value1%~ INSERT_BYTES fj_position LONG_AT 0x9c WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += LONG_AT 0x9c END ELSE PATCH_IF( key_0 == 0xbc && fj_structure_type != key_0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reinserting %value% number %key1%.~ END INSERT_BYTES fj_position key_3 WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += key_3 END ELSE PATCH_IF( key_0 == 0xc0 && fj_structure_type != key_0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reinserting %value% number %key1%.~ END INSERT_BYTES fj_position key_3 WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += key_3 END END // PHP_EACH $EVAL ~are_%value%~ // add new structure PATCH_IF( key_0 == fj_structure_type && fj_delete_mode == ` 0 && key_0 != 0x78 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding new %value% structure.~ END PATCH_IF( key_2 == 0x02 )BEGIN WRITE_SHORT key_1 THIS + 0x01 END ELSE PATCH_IF( key_2 == 0x04 )BEGIN WRITE_LONG key_1 THIS + 0x01 END SET fj_return_offset = fj_position INSERT_BYTES fj_position key_3 SET fj_position += key_3 // actor PATCH_IF( fj_structure_type == 0x54 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_SHORT fj_return_offset + 0x24 fj_dest_x WRITE_SHORT fj_return_offset + 0x26 fj_dest_y WRITE_LONG fj_return_offset + 0x28 fj_loading WRITE_LONG fj_return_offset + 0x2c fj_spawned WRITE_LONG fj_return_offset + 0x30 fj_animation WRITE_LONG fj_return_offset + 0x34 fj_orientation WRITE_LONG fj_return_offset + 0x38 fj_expiry WRITE_SHORT fj_return_offset + 0x3c fj_wander_dist_actor WRITE_SHORT fj_return_offset + 0x3e fj_mvmt_dist_actor WRITE_LONG fj_return_offset + 0x40 fj_schedule WRITE_LONG fj_return_offset + 0x44 fj_num_talked WRITE_ASCIIE fj_return_offset + 0x48 ~%fj_dlg_resref%~ WRITE_ASCIIE fj_return_offset + 0x50 ~%fj_bcs_override%~ WRITE_ASCIIE fj_return_offset + 0x58 ~%fj_bcs_general%~ WRITE_ASCIIE fj_return_offset + 0x60 ~%fj_bcs_class%~ WRITE_ASCIIE fj_return_offset + 0x68 ~%fj_bcs_race%~ WRITE_ASCIIE fj_return_offset + 0x70 ~%fj_bcs_default%~ WRITE_ASCIIE fj_return_offset + 0x78 ~%fj_bcs_specific%~ WRITE_ASCIIE fj_return_offset + 0x80 ~%fj_cre_resref%~ END ELSE // region PATCH_IF( fj_structure_type == 0x5c )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_type WRITE_SHORT fj_return_offset + 0x22 fj_box_left WRITE_SHORT fj_return_offset + 0x24 fj_box_top WRITE_SHORT fj_return_offset + 0x26 fj_box_right WRITE_SHORT fj_return_offset + 0x28 fj_box_bottom WRITE_LONG fj_return_offset + 0x34 fj_cursor_idx WRITE_ASCIIE fj_return_offset + 0x38 ~%fj_destination_area%~ #8 WRITE_ASCIIE fj_return_offset + 0x40 ~%fj_destination_name%~ #32 WRITE_LONG fj_return_offset + 0x60 fj_flags WRITE_LONG fj_return_offset + 0x64 fj_info_point_strref WRITE_SHORT fj_return_offset + 0x68 fj_trap_detect WRITE_SHORT fj_return_offset + 0x6a fj_trap_remove WRITE_SHORT fj_return_offset + 0x6c fj_trap_active WRITE_SHORT fj_return_offset + 0x6e fj_trap_status WRITE_SHORT fj_return_offset + 0x70 fj_loc_x WRITE_SHORT fj_return_offset + 0x72 fj_loc_y WRITE_ASCIIE fj_return_offset + 0x74 ~%fj_key_resref%~ #8 WRITE_ASCIIE fj_return_offset + 0x7c ~%fj_reg_script%~ #8 WRITE_SHORT fj_return_offset + 0x84 fj_alt_x WRITE_SHORT fj_return_offset + 0x86 fj_alt_y PHP_EACH fj_vertex AS key1 => value1 BEGIN WRITE_SHORT fj_return_offset + 0x2a THIS + 0x01 END END ELSE // spawn PATCH_IF( fj_structure_type == 0x60 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_ASCIIE fj_return_offset + 0x24 ~%fj_cre_resref0%~ #8 WRITE_ASCIIE fj_return_offset + 0x2c ~%fj_cre_resref1%~ #8 WRITE_ASCIIE fj_return_offset + 0x34 ~%fj_cre_resref2%~ #8 WRITE_ASCIIE fj_return_offset + 0x3c ~%fj_cre_resref3%~ #8 WRITE_ASCIIE fj_return_offset + 0x44 ~%fj_cre_resref4%~ #8 WRITE_ASCIIE fj_return_offset + 0x4c ~%fj_cre_resref5%~ #8 WRITE_ASCIIE fj_return_offset + 0x54 ~%fj_cre_resref6%~ #8 WRITE_ASCIIE fj_return_offset + 0x5c ~%fj_cre_resref7%~ #8 WRITE_ASCIIE fj_return_offset + 0x64 ~%fj_cre_resref8%~ #8 WRITE_ASCIIE fj_return_offset + 0x6c ~%fj_cre_resref9%~ #8 WRITE_SHORT fj_return_offset + 0x74 fj_spawn_num WRITE_SHORT fj_return_offset + 0x76 fj_difficulty WRITE_SHORT fj_return_offset + 0x78 fj_delay WRITE_SHORT fj_return_offset + 0x7a fj_method WRITE_LONG fj_return_offset + 0x7c fj_duration WRITE_SHORT fj_return_offset + 0x80 fj_wander_distance WRITE_SHORT fj_return_offset + 0x82 fj_mvmt_distance WRITE_SHORT fj_return_offset + 0x84 fj_max_num WRITE_SHORT fj_return_offset + 0x86 fj_enable WRITE_LONG fj_return_offset + 0x88 fj_schedule WRITE_SHORT fj_return_offset + 0x8c fj_day_prob WRITE_SHORT fj_return_offset + 0x8e fj_night_prob END ELSE // entrance PATCH_IF( fj_structure_type == 0x68 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_SHORT fj_return_offset + 0x24 fj_orientation END ELSE // container PATCH_IF( fj_structure_type == 0x70 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_SHORT fj_return_offset + 0x24 fj_type WRITE_SHORT fj_return_offset + 0x26 fj_lock_diff WRITE_LONG fj_return_offset + 0x28 fj_flags WRITE_SHORT fj_return_offset + 0x2c fj_trap_detect WRITE_SHORT fj_return_offset + 0x2e fj_trap_remove_diff WRITE_SHORT fj_return_offset + 0x30 fj_trap_active WRITE_SHORT fj_return_offset + 0x32 fj_trap_status WRITE_SHORT fj_return_offset + 0x34 fj_trap_loc_x WRITE_SHORT fj_return_offset + 0x36 fj_trap_loc_y WRITE_SHORT fj_return_offset + 0x38 fj_box_left WRITE_SHORT fj_return_offset + 0x3a fj_box_top WRITE_SHORT fj_return_offset + 0x3c fj_box_right WRITE_SHORT fj_return_offset + 0x3e fj_box_bottom WRITE_ASCIIE fj_return_offset + 0x48 ~%fj_trap_script%~ #8 WRITE_ASCIIE fj_return_offset + 0x78 ~%fj_key_resref%~ #8 WRITE_LONG fj_return_offset + 0x84 fj_lockpick_strref PHP_EACH fj_vertex AS key1 => value1 BEGIN WRITE_LONG fj_return_offset + 0x54 THIS + 0x01 END END ELSE // ambient PATCH_IF( fj_structure_type == 0x84 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_SHORT fj_return_offset + 0x24 fj_radius WRITE_SHORT fj_return_offset + 0x26 fj_loc_z WRITE_SHORT fj_return_offset + 0x2e fj_volume WRITE_ASCIIE fj_return_offset + 0x30 ~%fj_wav_resref0%~ #8 WRITE_ASCIIE fj_return_offset + 0x38 ~%fj_wav_resref1%~ #8 WRITE_ASCIIE fj_return_offset + 0x40 ~%fj_wav_resref2%~ #8 WRITE_ASCIIE fj_return_offset + 0x48 ~%fj_wav_resref3%~ #8 WRITE_ASCIIE fj_return_offset + 0x50 ~%fj_wav_resref4%~ #8 WRITE_ASCIIE fj_return_offset + 0x58 ~%fj_wav_resref5%~ #8 WRITE_ASCIIE fj_return_offset + 0x60 ~%fj_wav_resref6%~ #8 WRITE_ASCIIE fj_return_offset + 0x68 ~%fj_wav_resref7%~ #8 WRITE_ASCIIE fj_return_offset + 0x70 ~%fj_wav_resref8%~ #8 WRITE_ASCIIE fj_return_offset + 0x78 ~%fj_wav_resref9%~ #8 WRITE_SHORT fj_return_offset + 0x80 fj_sound_num WRITE_LONG fj_return_offset + 0x84 fj_delay WRITE_LONG fj_return_offset + 0x88 fj_variation WRITE_LONG fj_return_offset + 0x8c fj_schedule WRITE_LONG fj_return_offset + 0x90 fj_flags END ELSE // variable PATCH_IF( fj_structure_type == 0x88 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_LONG fj_return_offset + 0x28 fj_variable_value END ELSE // door PATCH_IF( fj_structure_type == 0xa8 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_ASCIIE fj_return_offset + 0x20 ~%fj_door_wed_id%~ WRITE_LONG fj_return_offset + 0x28 fj_flags WRITE_SHORT fj_return_offset + 0x38 fj_open_box_left WRITE_SHORT fj_return_offset + 0x3a fj_open_box_top WRITE_SHORT fj_return_offset + 0x3c fj_open_box_right WRITE_SHORT fj_return_offset + 0x3e fj_open_box_bottom WRITE_SHORT fj_return_offset + 0x40 fj_closed_box_left WRITE_SHORT fj_return_offset + 0x42 fj_closed_box_top WRITE_SHORT fj_return_offset + 0x44 fj_closed_box_right WRITE_SHORT fj_return_offset + 0x46 fj_closed_box_bottom WRITE_ASCIIE fj_return_offset + 0x58 ~%fj_door_open_wav%~ WRITE_ASCIIE fj_return_offset + 0x60 ~%fj_door_close_wav%~ WRITE_LONG fj_return_offset + 0x68 fj_cursor_idx WRITE_SHORT fj_return_offset + 0x6c fj_trap_detect WRITE_SHORT fj_return_offset + 0x6e fj_trap_remove WRITE_SHORT fj_return_offset + 0x70 fj_trap_active WRITE_SHORT fj_return_offset + 0x72 fj_trap_status WRITE_SHORT fj_return_offset + 0x74 fj_trap_loc_x WRITE_SHORT fj_return_offset + 0x76 fj_trap_loc_y WRITE_ASCIIE fj_return_offset + 0x78 ~%fj_key_resref%~ WRITE_ASCIIE fj_return_offset + 0x80 ~%fj_door_script%~ WRITE_LONG fj_return_offset + 0x88 fj_detect_diff WRITE_LONG fj_return_offset + 0x8c fj_locked_diff WRITE_SHORT fj_return_offset + 0x90 fj_open_loc_x WRITE_SHORT fj_return_offset + 0x92 fj_open_loc_y WRITE_SHORT fj_return_offset + 0x94 fj_closed_loc_x WRITE_SHORT fj_return_offset + 0x96 fj_closed_loc_y WRITE_LONG fj_return_offset + 0x98 fj_lockpick_strref WRITE_ASCIIE fj_return_offset + 0x9c ~%fj_travel_trigger%~ #24 WRITE_LONG fj_return_offset + 0xb4 fj_dlg_strref WRITE_ASCIIE fj_return_offset + 0xb8 ~%fj_dlg_resref%~ PHP_EACH fj_door_open_vert AS key1 => value1 BEGIN WRITE_SHORT fj_return_offset + 0x30 THIS + 0x01 END PHP_EACH fj_door_closed_vert AS key1 => value1 BEGIN WRITE_SHORT fj_return_offset + 0x32 THIS + 0x01 END PHP_EACH fj_cell_open_vert AS key1 => value1 BEGIN WRITE_SHORT fj_return_offset + 0x4c THIS + 0x01 END PHP_EACH fj_cell_closed_vert AS key1 => value1 BEGIN WRITE_SHORT fj_return_offset + 0x4e THIS + 0x01 END END ELSE // animation PATCH_IF( fj_structure_type == 0xb0 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_SHORT fj_return_offset + 0x20 fj_loc_x WRITE_SHORT fj_return_offset + 0x22 fj_loc_y WRITE_LONG fj_return_offset + 0x24 fj_schedule WRITE_ASCIIE fj_return_offset + 0x28 ~%fj_bam_resref%~ #8 WRITE_SHORT fj_return_offset + 0x30 fj_bam_seq WRITE_SHORT fj_return_offset + 0x32 fj_bam_frame WRITE_LONG fj_return_offset + 0x34 fj_flags WRITE_SHORT fj_return_offset + 0x38 fj_loc_z WRITE_SHORT fj_return_offset + 0x3a fj_transparent WRITE_SHORT fj_return_offset + 0x3c fj_init_frame WRITE_BYTE fj_return_offset + 0x3e fj_loop_chance WRITE_BYTE fj_return_offset + 0x3f fj_skip_cycles WRITE_ASCIIE fj_return_offset + 0x40 ~%fj_bmp_resref%~ #8 END ELSE // bitmask PATCH_IF( fj_structure_type == 0xa0 )BEGIN PATCH_IF( FILE_EXISTS ~%fj_bitmask%~ )BEGIN SET key1 = BUFFER_LENGTH APPEND_FILE_EVALUATE ~%fj_bitmask%~ WRITE_LONG 0x9c BUFFER_LENGTH - key1 END ELSE BEGIN WRITE_LONG 0x9c 0x00 END SET fj_position += LONG_AT 0x9c END ELSE // songs PATCH_IF( fj_structure_type == 0xbc )BEGIN WRITE_LONG fj_return_offset + 0x00 fj_song_day WRITE_LONG fj_return_offset + 0x04 fj_song_night WRITE_LONG fj_return_offset + 0x08 fj_song_victory WRITE_LONG fj_return_offset + 0x0c fj_song_battle WRITE_LONG fj_return_offset + 0x10 fj_song_defeat WRITE_LONG fj_return_offset + 0x14 0xffffffff WRITE_LONG fj_return_offset + 0x18 0xffffffff WRITE_LONG fj_return_offset + 0x1c 0xffffffff WRITE_LONG fj_return_offset + 0x20 0xffffffff WRITE_LONG fj_return_offset + 0x24 0xffffffff WRITE_ASCIIE fj_return_offset + 0x28 ~%fj_song_day0%~ #8 WRITE_ASCIIE fj_return_offset + 0x30 ~%fj_song_day1%~ #8 WRITE_LONG fj_return_offset + 0x38 fj_song_day_vol WRITE_ASCIIE fj_return_offset + 0x3c ~%fj_song_night0%~ #8 WRITE_ASCIIE fj_return_offset + 0x44 ~%fj_song_night1%~ #8 WRITE_LONG fj_return_offset + 0x4c fj_song_night_vol WRITE_LONG fj_return_offset + 0x50 fj_song_reverb END ELSE // rest interrupts PATCH_IF( fj_structure_type == 0xc0 )BEGIN WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #32 WRITE_LONG fj_return_offset + 0x20 fj_cre_strref0 WRITE_LONG fj_return_offset + 0x24 fj_cre_strref1 WRITE_LONG fj_return_offset + 0x28 fj_cre_strref2 WRITE_LONG fj_return_offset + 0x2c fj_cre_strref3 WRITE_LONG fj_return_offset + 0x30 fj_cre_strref4 WRITE_LONG fj_return_offset + 0x34 fj_cre_strref5 WRITE_LONG fj_return_offset + 0x38 fj_cre_strref6 WRITE_LONG fj_return_offset + 0x3c fj_cre_strref7 WRITE_LONG fj_return_offset + 0x40 fj_cre_strref8 WRITE_LONG fj_return_offset + 0x44 fj_cre_strref9 WRITE_ASCIIE fj_return_offset + 0x48 ~%fj_cre_resref0%~ #8 WRITE_ASCIIE fj_return_offset + 0x50 ~%fj_cre_resref1%~ #8 WRITE_ASCIIE fj_return_offset + 0x58 ~%fj_cre_resref2%~ #8 WRITE_ASCIIE fj_return_offset + 0x60 ~%fj_cre_resref3%~ #8 WRITE_ASCIIE fj_return_offset + 0x68 ~%fj_cre_resref4%~ #8 WRITE_ASCIIE fj_return_offset + 0x70 ~%fj_cre_resref5%~ #8 WRITE_ASCIIE fj_return_offset + 0x78 ~%fj_cre_resref6%~ #8 WRITE_ASCIIE fj_return_offset + 0x80 ~%fj_cre_resref7%~ #8 WRITE_ASCIIE fj_return_offset + 0x88 ~%fj_cre_resref8%~ #8 WRITE_ASCIIE fj_return_offset + 0x90 ~%fj_cre_resref9%~ #8 WRITE_SHORT fj_return_offset + 0x98 fj_spawn_num WRITE_SHORT fj_return_offset + 0x9a fj_difficulty WRITE_LONG fj_return_offset + 0x9c fj_duration WRITE_SHORT fj_return_offset + 0xa0 fj_wander_distance WRITE_SHORT fj_return_offset + 0xa2 fj_mvmt_distance WRITE_SHORT fj_return_offset + 0xa4 fj_max_num WRITE_SHORT fj_return_offset + 0xa6 fj_enable WRITE_SHORT fj_return_offset + 0xa8 fj_day_prob WRITE_SHORT fj_return_offset + 0xaa fj_night_prob END ELSE // map note (BGII) PATCH_IF( fj_structure_type == 0xc4 )BEGIN WRITE_SHORT fj_return_offset + 0x00 fj_loc_x WRITE_SHORT fj_return_offset + 0x02 fj_loc_y WRITE_LONG fj_return_offset + 0x04 fj_note_strref WRITE_SHORT fj_return_offset + 0x08 fj_strref_loc WRITE_SHORT fj_return_offset + 0x0a fj_color WRITE_LONG fj_return_offset + 0x0c fj_note_id END ELSE // map note (PST) PATCH_IF( fj_structure_type == 0xc8 )BEGIN WRITE_LONG fj_return_offset + 0x000 fj_loc_x WRITE_LONG fj_return_offset + 0x004 fj_loc_y WRITE_ASCIIE fj_return_offset + 0x008 ~%fj_note_text%~ WRITE_LONG fj_return_offset + 0x1fc fj_color END ELSE // embedded projectile PATCH_IF( fj_structure_type == 0xcc )BEGIN PATCH_IF( fj_missile_num == ` 0 )BEGIN SET fj_missile_num = IDS_OF_SYMBOL ( projectl ~%fj_name%~ ) PATCH_IF( fj_missile_num > ` 0 )BEGIN SET fj_missile_num -= 0x01 END END WRITE_ASCIIE fj_return_offset + 0x00 ~%fj_name%~ #8 WRITE_SHORT fj_return_offset + 0x0e fj_missile_num WRITE_SHORT fj_return_offset + 0x10 fj_frequency WRITE_SHORT fj_return_offset + 0x12 fj_duration WRITE_SHORT fj_return_offset + 0x14 fj_loc_x WRITE_SHORT fj_return_offset + 0x16 fj_loc_y WRITE_SHORT fj_return_offset + 0x18 fj_loc_z WRITE_SHORT fj_return_offset + 0x1a fj_target END END // add items and index to their containers PATCH_IF( key_0 == 0x78 )BEGIN PHP_EACH are_container AS num => structure BEGIN PATCH_IF( fj_structure_type == 0x70 && num == fj_delete_mode && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN WRITE_LONG LONG_AT 0x70 + 0xc0 * ( num - fj_deleted ) + 0x40 fj_itm_idx PHP_EACH ~are_container_%num%_itm~ AS num1 => value1 BEGIN PATCH_IF( ( fj_structure_type != 0x78 ) || ( fj_delete_mode != num1 + LONG_AT ( LONG_AT 0x70 + 0xc0 * ( num - fj_deleted ) + 0x40 ) ) )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating item %num1% to container %num%.~ END WRITE_LONG LONG_AT 0x70 + 0xc0 * ( num - fj_deleted ) + 0x44 THIS + 0x01 INSERT_BYTES fj_position 0x14 WRITE_ASCIIE fj_position ~%value1%~ WRITE_SHORT 0x76 THIS + 0x01 SET ++ fj_itm_idx SET fj_position += key_3 END END END PATCH_IF( fj_con_itm_idx == num && fj_structure_type == 0x78 )BEGIN READ_LONG LONG_AT 0x70 + 0xc0 * num + 0x44 cnt PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding new item to container %num%.~ END WRITE_LONG LONG_AT 0x70 + 0xc0 * num + 0x44 THIS + 0x01 WRITE_SHORT 0x76 THIS + 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 SET fj_position += key_3 END END // php $are_container SET fj_deleted = 0x00 PHP_EACH are_container AS key => value BEGIN CLEAR_ARRAY EVAL ~are_container_%key%_itm~ END END ELSE // add vertices PATCH_IF( key_0 == 0x7c )BEGIN // vertices associated with regions PHP_EACH are_region AS num => structure BEGIN PATCH_IF( fj_structure_type == 0x5c && num == fj_delete_mode && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating vertices to region %num%.~ END WRITE_LONG LONG_AT 0x5c + 0xc4 * ( num - fj_deleted ) + 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 THIS + 0x01 SET ++fj_vertex_idx SET fj_position += key_3 END END END SET fj_deleted = 0x00 PATCH_IF( fj_structure_type == 0x5c && fj_delete_mode == ` 0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding vertices to new region.~ END WRITE_LONG fj_return_offset + 0x2c fj_vertex_idx PHP_EACH fj_vertex AS num => off BEGIN INSERT_BYTES fj_position 0x04 WRITE_SHORT 0x80 THIS + 0x01 SET ++fj_vertex_idx END PHP_EACH fj_vertex AS num => off BEGIN WRITE_LONG fj_position off SET fj_position += 0x04 END END PHP_EACH are_region AS num => structure BEGIN CLEAR_ARRAY EVAL ~are_region_%num%_vertex~ END // vertices associated with containers PHP_EACH are_container AS num => structure BEGIN PATCH_IF( fj_structure_type == 0x70 && num == fj_delete_mode && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating vertices to container %num%.~ END WRITE_LONG LONG_AT 0x70 + 0xc0 * ( num - fj_deleted ) + 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 THIS + 0x01 SET ++fj_vertex_idx SET fj_position += 0x04 END END END SET fj_deleted = 0x00 PATCH_IF fj_structure_type == 0x70 && fj_delete_mode == ` 0 BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding vertices to new container.~ END WRITE_LONG fj_return_offset + 0x50 fj_vertex_idx PHP_EACH fj_vertex AS num => off BEGIN SET ++fj_vertex_idx INSERT_BYTES fj_position 0x04 WRITE_SHORT 0x80 THIS + 0x01 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 CLEAR_ARRAY EVAL ~are_container_%num%_vertex~ END // vertices associated with doors PHP_EACH are_door AS num => structure BEGIN PATCH_IF( fj_structure_type == 0xa8 && num == fj_delete_mode && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating vertices to door %num%.~ END WRITE_LONG LONG_AT 0xa8 + 0xc8 * ( num - fj_deleted ) + 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 SET ++fj_vertex_idx SET fj_position += 0x04 WRITE_SHORT 0x80 THIS + 0x01 END WRITE_LONG LONG_AT 0xa8 + 0xc8 * ( num - fj_deleted ) + 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 SET ++fj_vertex_idx SET fj_position += 0x04 WRITE_SHORT 0x80 THIS + 0x01 END WRITE_LONG LONG_AT 0xa8 + 0xc8 * ( num - fj_deleted ) + 0x48 fj_vertex_idx PHP_EACH ~are_cell_open_%num%_vertex~ AS num1 => value1 BEGIN INSERT_BYTES fj_position 0x04 WRITE_LONG fj_position value1 SET ++fj_vertex_idx SET fj_position += 0x04 WRITE_SHORT 0x80 THIS + 0x01 END WRITE_LONG LONG_AT 0xa8 + 0xc8 * ( num - fj_deleted ) + 0x50 fj_vertex_idx PHP_EACH ~are_cell_closed_%num%_vertex~ AS num1 => value1 BEGIN INSERT_BYTES fj_position 0x04 WRITE_LONG fj_position value1 SET ++fj_vertex_idx SET fj_position += 0x04 WRITE_SHORT 0x80 THIS + 0x01 END END END SET fj_deleted = 0x00 PATCH_FOR_EACH value1 IN door_open door_closed cell_open cell_closed BEGIN CLEAR_ARRAY EVAL ~are_%value1%_%num%_vertex~ END PATCH_IF( fj_structure_type == 0xa8 && fj_delete_mode == ` 0 )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding vertices to new door.~ END 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 + 0x4c) PATCH_FOR_EACH vertex_type IN door_open door_closed cell_open cell_closed BEGIN PHP_EACH ~fj_%vertex_type%_vert~ AS num => off BEGIN INSERT_BYTES fj_position 0x04 WRITE_SHORT 0x80 THIS + 0x01 END PHP_EACH ~fj_%vertex_type%_vert~ AS num => off BEGIN WRITE_LONG fj_position off SET fj_position += 0x04 END CLEAR_ARRAY EVAL ~fj_%vertex_type%_vert~ END END END // adding vertices // reinsert embedded creatures PATCH_IF( key_0 == 0x54 )BEGIN PHP_EACH are_embedded_cre AS num => value1 BEGIN PATCH_IF( fj_structure_type == 0x54 && num == fj_delete_mode && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating embedded creature to actor %num%.~ END WRITE_LONG LONG_AT 0x54 + ( num - fj_deleted ) * 0x110 + 0x88 fj_position INSERT_BYTES fj_position LONG_AT ( LONG_AT 0x54 + ( num - fj_deleted ) * 0x110 + 0x8c ) WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += LONG_AT (LONG_AT 0x54 + ( num - fj_deleted ) * 0x110 + 0x8c) END END CLEAR_ARRAY are_embedded_cre SET fj_deleted = 0x00 PATCH_IF( fj_structure_type == 0x54 && fj_delete_mode == ` 0 && !( fj_loading & 0x01 ) )BEGIN PATCH_IF( FILE_EXISTS ~%fj_cre_embedded%~ )BEGIN SET off = BUFFER_LENGTH // we do a stupid dance here to avoid INNER_ACTION APPEND_FILE_EVALUATE ~%fj_cre_embedded%~ READ_ASCII off fj_cre_embedded ( BUFFER_LENGTH - off ) DELETE_BYTES off STRING_LENGTH EVAL ~%fj_cre_embedded%~ END ELSE PATCH_IF( FILE_EXISTS_IN_GAME ~%fj_cre_resref%.cre~ ) BEGIN INNER_PATCH_FILE ~%fj_cre_resref%.cre~ BEGIN READ_ASCII 0x00 fj_cre_embedded ( BUFFER_LENGTH ) END END PATCH_IF( ~%fj_cre_embedded%~ STR_CMP ~~ )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Embedding creature to new actor.~ END WRITE_LONG fj_return_offset + 0x88 fj_position WRITE_LONG fj_return_offset + 0x8c STRING_LENGTH EVAL ~%fj_cre_embedded%~ INSERT_BYTES fj_position LONG_AT (fj_return_offset + 0x8c) WRITE_ASCIIE fj_position ~%fj_cre_embedded%~ SET fj_position += LONG_AT ( fj_return_offset + 0x8c ) END ELSE BEGIN WRITE_LONG fj_return_offset + 0x28 THIS | 0x01 // if we didn't find a .cre, mark it unembedded END END END ELSE // reinsert embedded projectile effects PATCH_IF( key_0 == 0xcc )BEGIN PHP_EACH are_embedded_eff AS num => value1 BEGIN PATCH_IF( fj_structure_type == 0xcc && fj_delete_mode == num && fj_deleted == 0x00 )BEGIN SET fj_deleted = 0x01 END ELSE BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Reassociating embedded effects to projectile %num%.~ END WRITE_LONG LONG_AT 0xcc + ( num - fj_deleted ) * 0x1c + 0x08 fj_position INSERT_BYTES fj_position SHORT_AT (LONG_AT 0xcc + ( num - fj_deleted ) * 0x1c + 0x0c) WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += SHORT_AT (LONG_AT 0xcc + ( num - fj_deleted ) * 0x1c + 0x0c) END END SET fj_deleted = 0x00 CLEAR_ARRAY are_embedded_eff PATCH_IF( fj_structure_type == 0xcc && fj_delete_mode == ` 0 )BEGIN WRITE_LONG fj_return_offset + 0x08 fj_position PHP_EACH fj_embedded_eff AS num => value1 BEGIN PATCH_IF( FILE_EXISTS ~%value1%~ )BEGIN SET off = BUFFER_LENGTH APPEND_FILE_EVALUATE ~%value1%~ READ_ASCII off + 0x08 value1 (0x108) DELETE_BYTES off 0x110 END ELSE PATCH_IF( FILE_EXISTS_IN_GAME ~%value1%.eff~ )BEGIN INNER_PATCH_FILE ~%value1%.eff~ BEGIN READ_ASCII 0x08 value1 (0x108) END END ELSE BEGIN TEXT_SPRINT value1 ~~ END PATCH_IF( ~%value1%~ STR_CMP ~~ )BEGIN PATCH_IF fj_debug BEGIN PATCH_PRINT ~Adding effect %num% to new embedded projectile.~ END WRITE_SHORT fj_return_offset + 0x0c THIS + 0x108 INSERT_BYTES fj_position 0x108 WRITE_ASCIIE fj_position ~%value1%~ SET fj_position += 0x108 END END END CLEAR_ARRAY fj_embedded_eff END END // php $struct: everything added // restoring Icewind Dale II's special snowflakiness 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 PATCH_IF LONG_AT off BEGIN WRITE_LONG off THIS + 0x10 END END INSERT_BYTES 0x54 0x10 WRITE_ASCIIE 0x54 ~%id2_header%~ SET fj_return_offset += 0x10 GET_OFFSET_ARRAY fj_id_actor 0x54 0x04 0x58 0x02 0 0 0x110 PHP_EACH fj_id_actor AS key => value BEGIN PATCH_IF( LONG_AT( value + 0x88 ) > 0x00 && LONG_AT( value + 0x28 ) & 0x01 == 0x00 )BEGIN WRITE_LONG value + 0x88 THIS + 0x10 END END END END