-
Notifications
You must be signed in to change notification settings - Fork 3
/
setup-aranw.tp2
3492 lines (3256 loc) · 162 KB
/
setup-aranw.tp2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
BACKUP ~aranw/backup~
AUTHOR ~cmorgan~
/*
* IF YOU ARE DOWNOADING FROM GITHUB, you need to do the following:
* 1. check to make sure everything is there,
* 2. edit the VERSION line found right below this message with your username and the date, so you have a way of knowing what "version" you have
* 3. copy another mod's setup-mymod.exe and rename it setup-aranw.exe
* 4. enjoy the mod. If you run into problmes, find me at G3 or start an issue ticket on GitHub!
*/
VERSION ~Beta_2~
BEGIN ~Install Aran Whitehand Beta 2 for SoA and ToB~
/* extra regexp vars */
INCLUDE ~aranw/lib/extra_regexp_vars.tpa~
/* .ids patching */
INCLUDE ~aranw/lib/ids_patching.tph~
OUTER_FOR( aran_timer_choice = 0 ; ~%aran_timer_choice%~ STRING_COMPARE_REGEXP ~^[12]$~ ; )BEGIN
PRINT ~Set Talk and Flirt Timers
[1] Install Default Timers
[2] Customize Timers
Please type 1 or 2 and press enter.~
ACTION_READLN aran_timer_choice
END // of O_F
ACTION_IF ("aran_timer_choice" = 1) THEN BEGIN
/* .ids patching with player choice: set talk timers */
APPEND ~gtimes.ids~ ~3600 ARAN_FTT~
APPEND ~gtimes.ids~ ~3600 ARAN_LTT~
APPEND ~gtimes.ids~ ~3600 ARAN_FLIRT~
PRINT ~Speed: minimum 1 hour real time between dialogues (Default, recommended)~
OUTER_SET choseninitialrom = 2400
PRINT ~Initial Lovetalk offset by 40 minutes~
OUTER_SET choseninitialflirt = 1200
PRINT ~Initial NPC-Initiated Flirt offset by 20 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
hourly FriendTalk,
NPC-initiated Flirt 20 minutes later,
RomanceTalk 20 minutes after that,
then 20 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("aran_timer_choice" = 2) THEN BEGIN
PRINT ~Select Aran's Talk timers:~
PRINT ~Please choose one of the following:
[1] approximately 1 hour real time minimum between friendship dialogues (recommended, default)
[2] approximately 15 minutes real time minimum between friendship dialogues
[3] approximately 30 minutes real time minimum between friendship dialogues
[4] approximately 45 minutes real time minimum between friendship dialogues
[5] approximately 1 hour 30 minutes real time minimum friendship between dialogues
[6] approximately 2 hours real time minimum between friendshipdialogues~
OUTER_SPRINT ~friendshiptimer~ ~placeholder_value~
OUTER_WHILE (!(IS_AN_INT ~friendshiptimer~) OR (~friendshiptimer~ > 0x6) OR (~friendshiptimer~ < 0x1)) BEGIN
PRINT ~Please type 1, 2, 3, 4, 5 or 6 and press enter.~
ACTION_READLN ~friendshiptimer~
END
ACTION_IF ("friendshiptimer" = 1) THEN BEGIN
APPEND ~gtimes.ids~ ~3600 ARAN_FTT~
APPEND ~gtimes.ids~ ~3600 ARAN_LTT~
APPEND ~gtimes.ids~ ~3600 ARAN_FLIRT~
PRINT ~Speed: minimum 1 hour real time between dialogues (Default, recommended)~
OUTER_SET choseninitialrom = 2400
PRINT ~Initial Lovetalk offset by 40 minutes~
OUTER_SET choseninitialflirt = 1200
PRINT ~Initial NPC-Initiated Flirt offset by 20 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
hourly FriendTalk,
NPC Flirt 20 minutes later,
and RomanceTalk 20 minutes after that,
then 20 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("friendshiptimer" = 2) THEN BEGIN
APPEND ~gtimes.ids~ ~900 ARAN_FTT~
APPEND ~gtimes.ids~ ~900 ARAN_LTT~
APPEND ~gtimes.ids~ ~900 ARAN_FLIRT~
PRINT ~Speed: minimum 15 minutes real time between dialogues~
OUTER_SET choseninitialrom = 600
PRINT ~Initial Lovetalk offset by 10 minutes~
OUTER_SET choseninitialflirt = 300
PRINT ~Initial NPC-Initiated Flirt offset by 5 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
15 minute FriendTalk,
NPC-initiated Flirt 5 minutes later,
and RomanceTalk 5 minutes after that,
then 5 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("friendshiptimer" = 3) THEN BEGIN
APPEND ~gtimes.ids~ ~1800 ARAN_FTT~
APPEND ~gtimes.ids~ ~1800 ARAN_LTT~
APPEND ~gtimes.ids~ ~1800 ARAN_FLIRT~
PRINT ~Speed: minimum 30 minutes real time between dialogues~
OUTER_SET choseninitialrom = 1200
PRINT ~Initial Lovetalk offset by 20 minutes~
OUTER_SET choseninitialflirt = 600
PRINT ~Initial NPC-Initiated Flirt offset by 10 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
30 minute FriendTalk,
NPC-initiated Flirt 10 minutes later,
and RomanceTalk 10 minutes after that,
then 10 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("friendshiptimer" = 4) THEN BEGIN
APPEND ~gtimes.ids~ ~2700 ARAN_FTT~
APPEND ~gtimes.ids~ ~2700 ARAN_LTT~
APPEND ~gtimes.ids~ ~2700 ARAN_FLIRT~
PRINT ~Speed: minimum 45 minutes real time between dialogues~
OUTER_SET choseninitialrom = 1800
PRINT ~Initial Lovetalk offset by 30 minutes~
OUTER_SET choseninitialflirt = 900
PRINT ~Initial NPC-Initiated Flirt offset by 15 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
45 minute FriendTalk,
NPC-initiated Flirt 15 minutes later,
and RomanceTalk 15 minutes after that,
then 15 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("friendshiptimer" = 5) THEN BEGIN
APPEND ~gtimes.ids~ ~5400 ARAN_FTT~
APPEND ~gtimes.ids~ ~5400 ARAN_LTT~
APPEND ~gtimes.ids~ ~5400 ARAN_FLIRT~
PRINT ~Speed: minimum 1 hour 30 minutes real time between dialogues~
OUTER_SET choseninitialrom = 3600
PRINT ~Initial Lovetalk offset by 60 minutes~
OUTER_SET choseninitialflirt = 1800
PRINT ~Initial NPC-Initiated Flirt offset by 30 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
90 minute FriendTalk,
NPC-initiated Flirt 30 minutes later,
and RomanceTalk 30 minutes after that,
then 30 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
ACTION_IF ("friendshiptimer" = 6) THEN BEGIN
APPEND ~gtimes.ids~ ~7200 ARAN_FTT~
APPEND ~gtimes.ids~ ~7200 ARAN_LTT~
APPEND ~gtimes.ids~ ~7200 ARAN_FLIRT~
PRINT ~Speed: minimum 2 hours real time between dialogues~
OUTER_SET choseninitialrom = 4800
PRINT ~Initial Lovetalk offset by 80 minutes~
OUTER_SET choseninitialflirt = 2400
PRINT ~Initial NPC-Initiated Flirt offset by 40 minutes~
PRINT ~So if you are in a romance with him and never stop the romance,
after the lovetalks start (after friendship talk 3),
the timer sequence will start
120 minute FriendTalk,
NPC-initiated Flirt 40 minutes later,
and RomanceTalk 40 minutes after that,
then 40 minutes later the next FriendTalk fires.
Please note that the timers are not exact, and
variations within the game may mean
bursts of activity followed by long waits...
especially when you run out of timered content!~
END
END
/* .2da patching */
APPEND ~pdialog.2da~
~C-ARAN C-ARANP C-ARANJ C-ARAND C-ARN25P C-ARN25J C-ARN25D C-ARN25~
UNLESS ~C-ARAN~
APPEND ~interdia.2da~ ~C-ARAN C-ARANB C-ARN25B~
UNLESS ~C-ARAN~
/* make sure Imoen has her banter file assigned */
ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN /* fixes ToB version */
COPY_EXISTING ~interdia.2da~ ~override~
SET_2DA_ENTRY 17 1 2 ~BIMOEN2~
BUT_ONLY_IF_IT_CHANGES
END ELSE BEGIN
APPEND ~interdia.2da~ ~IMOEN BIMOEN2~ /* fixes SoA version */
UNLESS ~BIMOEN2~
END
/* define all macros */
DEFINE_ACTION_MACRO ~chooseasoundtrack~ BEGIN
OUTER_SPRINT ~soundchoice~ ~placeholder_value~
OUTER_WHILE (!(IS_AN_INT ~soundchoice~) OR (~soundchoice~ > 0x3) OR (~soundchoice~ < 0x1)) BEGIN
PRINT ~Music choices:
[1] JSayles unaccompanied guitar, Early Music
[2] Renaissance brass
[3] Vox Vulgaris (midaevil wih a twist)
Please type 1, 2, or 3, and press enter.~
ACTION_READLN ~soundchoice~
END
ACTION_IF ("soundchoice" = 1) THEN BEGIN
/* sound themes : default */
/* Source - http://www.jsayles.com/familypages/earlymusic.htm - "All MP3 recordings listed below, may be downloaded and distributed free of charge. The recordings may be used for any purpose whatsoever. In fact, that's the only reason I'm doing this to promote Early Music, and especially to promote the musical selections recorded below." - J. Sayles, performer */
COPY ~aranw/media/wavc/set2_1_orosetta.wav~ ~override/c-arnfth.wav~ /* 1 friend, upbeat */
COPY ~aranw/media/wavc/set2_2_praetorius.wav~ ~override/c-arnfti.wav~ /* 2 friend, introspective */
COPY ~aranw/media/wavc/set2_3_sweetnymphcometothylover.wav~ ~override/c-arnltu.wav~ /* 3 love, upbeat */
COPY ~aranw/media/wavc/set2_4_aprilinmistressface.wav~ ~override/c-arnltl.wav~ /* 4 love, introspective */
COPY ~aranw/media/wavc/set2_5_riuriuchiu.wav~ ~override/c-arandf.wav~ /* 5 drunk or in an inn, fast */
COPY ~aranw/media/wavc/set2_6_comeagain.wav~ ~override/c-arands.wav~ /* 6 inn, introspective */
PRINT ~Default unaccompanied guitarsoundtrack chosen~
END
ACTION_IF ("soundchoice" = 2) THEN BEGIN
/* sound themes */
/* Set 3 - Vox Vulgaris - middle ages with a twist. Source - The group. Selections clipped from three of their online materials, Cantiga 166, Rokatanc, and Saltarello. Copyrighted, so again, if an official someone objects for use in a free mod, I'll just use it on my own install. I have to thank the husband and wife team that developed mount & Blade, because I didn't know there was such great midaevil re-covers from groups like Vox Vulgaris and Hungary Debrecen, until modders put them into their M&B mods! */
COPY ~aranw/media/wavc/set3_1_vox_vulgaris_rokatanc.wav~ ~override/c-arnfth.wav~ /* 1 friend, upbeat */
COPY ~aranw/media/wavc/set3_2_vox_vulgaris_rokatanc.wav~ ~override/c-arnfti.wav~ /* 2 friend, introspective */
COPY ~aranw/media/wavc/set3_3_vox_vulgaris_cantiga_166.wav~ ~override/c-arnltu.wav~ /* 3 love, upbeat */
COPY ~aranw/media/wavc/set3_3_vox_vulgaris_cantiga_166.wav~ ~override/c-arnltl.wav~ /* 4 love, introspective */
COPY ~aranw/media/wavc/set2_5_riuriuchiu.wav~ ~override/c-arandf.wav~ /* 5 drunk or in an inn, fast */
COPY ~aranw/media/wavc/set3_6_vox_vulgaris_saltarello.wav~ ~override/c-arands.wav~ /* 6 inn, introspective */
PRINT ~Vox Vulgaris soundtrack chosen~
END
ACTION_IF ("soundchoice" = 3) THEN BEGIN
/* sound themes */
/* Set 1 - brass ensemble, Suzato, The Danseyre. Renaissance, done in a brass arrangement. Czech Brass. Source - Czech Brass album "Virtuosi Baroque Music", on the Sonnleitner Verlag label. Copyrighted, so if someone objects to the rip for a free mod, I'll take it out. But if you find one of their recordings, they are solid brass, more calm in their interpretations that the Philip Jones Brass Ensemble or Canadian Brass. */
/* Inn/Drunk clips: #5 Praetorius's Volte, unknown recording. #6, see Set 2 #5 */
COPY ~aranw/media/wavc/set1_1_suzato_danserye_mourisque.wav~ ~override/c-arnfth.wav~ /* 1 friend, upbeat */
COPY ~aranw/media/wavc/set1_2_suzato_danserye_battaille.wav~ ~override/c-arnfti.wav~ /* 2 friend, introspective */
COPY ~aranw/media/wavc/set1_3_suzato_danserye_bransle.wav~ ~override/c-arnltu.wav~ /* 3 love, upbeat */
COPY ~aranw/media/wavc/set1_4_suzato_danserye_monamy.wav~ ~override/c-arnltl.wav~ /* 4 love, introspective */
COPY ~aranw/media/wavc/set1_5_praetorius_volte.wav~ ~override/c-arandf.wav~ /* 5 drunk or in an inn, fast */
COPY ~aranw/media/wavc/set2_6_comeagain.wav~ ~override/c-arands.wav~ /* 6 inn, introspective */
PRINT ~Brass soundtrack chosen~
END
END // of macro
/* Nythrun's definition */
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 = 1
// 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