-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTyruswoo_TileControl.js
2104 lines (2007 loc) · 84 KB
/
Tyruswoo_TileControl.js
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
//=============================================================================
// Tile Control
// For RPG Maker MZ
// By Tyruswoo and McKathlin
//=============================================================================
/*
* MIT License
*
* Copyright (c) 2023 Kathy Bunn and Scott Tyrus Washburn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
var Imported = Imported || {};
Imported.Tyruswoo_TileControl = true;
var Tyruswoo = Tyruswoo || {};
Tyruswoo.TileControl = Tyruswoo.TileControl || {};
/*:
* @target MZ
* @plugindesc MZ v3.0.2 Change tiles dynamically during gameplay!
* @author Tyruswoo and McKathlin
* @url https://www.tyruswoo.com
*
* @help Tyruswoo Tile Control for RPG Maker MZ
* ============================================================================
* Plugin commands, their arguments, and short explanations:
*
* Set Tile Modify the tileID at selected location.
* - Tile ID Use a tile code (see below) or exact ID.
* - X,Y,Z Coordinates Select the location of the tile to modify.
* > X On map, X coordinate at which to set tile.
* > Y On map, Y coordinate at which to set tile.
* > Z Z layer to affect. z 0-3 for layers 1-4.
* - Relativity & Options Relative position of coords, and options.
* > Relativity Mode Absolute, or relative to player or event.
* * Event ID If relative to event: The event's ID.
* * Party Member If relative to player: Leader or follower.
* * Orientational Shift Change loc based on character's direction.
* > Allow Autotiling True for autotiling. False for exact.
* > Clear Upper Layers True to erase upper z layers. False: Keep.
*
* Fill Tiles Modify multiple tiles. Allows filters.
* - Tile ID Fill tile code (see below) or exact ID.
* - X,Y,Z Coordinates Select the fill origin location.
* > X On map, X coordinate of origin.
* > Y On map, Y coordinate of origin.
* > Z Z layer to affect. z 0-3 for layers 1-4.
* - Relativity & Options Relative position of coords, and options.
* > Relativity Mode Absolute, or relative to player or event.
* * Event ID If relative to event: The event's ID.
* * Party Member If relative to player: Leader or follower.
* * Orientational Shift Relative shift loc by character's direction.
* - Forward Shift + to shift forward. - to shift backward.
* - Rightward Shift + to shift rightward. - to shift leftward.
* > Allow Autotiling True for autotiling. False for exact.
* > Clear Upper Layers True to erase upper z layers. False: Keep.
* - Filters Only fill tiles that pass all filters.
* > Region(s) Filter Region(s) allowed for fill.
* > Tile ID(s) Filter Only allow fill at certain Tile ID(s).
* * Tile ID(s) Recognized Tile ID(s) at which fill can occur.
* * Z Coord(s) Recognized Z coords (layers) at which fill can occur.
* > Area Filter Area to allow fill.
* * X1 X coordinate of first corner of fill area.
* * Y1 Y coordinate of first corner of fill area.
* * X2 X coordinate of other corner of fill area.
* * Y2 Y coordinate of other corner of fill area.
* > Distance Filter Distance from origin to allow fill.
* > Hollow Filter True for hollow. False for regular fill.
* > Origin Filter Never fill origin tile, or always fill.
* > Creep Append unique tile changes, beyond fill.
* * Creep Distance Distance creep spreads.
* * Creep Tile ID Tile code (see below) of creep.
* * Creep Z Coordinate Z layer to affect with creep.
* * Creep Options Options for creep.
* - Allow Autotiling True for autotiling. False: exact.
* - Clear Upper Layers True to erase upper z layers.
* * Creep Filters Only creep on tiles passing filters.
* - Creep Region(s) Filter Region(s) onto which creep can go.
* - Creep TileID(s) Filter Only allow creep on these tile IDs.
* > Tile ID(s) Recognized Tile ID(s) onto which creep can go.
* > Z Coord(s) Recognized Z layers to search for tile ID(s).
* - Creep Area Filter Area onto which creep can go.
* > X1 X coordinate of 1st corner (creep).
* > Y1 Y coordinate of 1st corner (creep).
* > X2 X coordinate of 2nd corner (creep).
* > Y2 Y coordinate of 2nd corner (creep).
* - Creep Hollow Filter True: Hollow. False: Regular creep.
*
* Change Animation Frames During game, change tile animation speed.
* - Tile Animation Frames Frames for tile animations. Lower is faster.
* ============================================================================
* Plugin parameters, their arguments, and short explanations:
*
* Tile Animation Frames Frames for tile animations of animated tiles.
* Lower is faster. Higher is slower. Default: 30.
*
* Common Event on OK Press Common event to begin when player presses the
* OK button (Enter).
*
* Tile Info on OK Press True: Output tile info to console window when
* playtester holds Ctrl then presses Enter (OK).
* (Tip: When playtesting, press F12 to open the
* console window.) Default: True.
* ============================================================================
* Script calls (Advanced):
*
* $gameMap.tileCodeAt(x,y,z)
* Returns the "Tx,y" ("Letter X comma Y" or "Tab X comma Y") tile code
* at location (x,y,z) where x is the x coordinate,y is the y coordinate,
* and z is the z layer (0, 1, 2, or 3). Tile code returns as a string.
* - For example, from the default Overworld tileset, ocean returns the
* string "A0,0".
* - This script call is useful in a conditional branch.
* For example, if the player is in the Overworld and the Overworld is
* using the default tilset, you can use a conditional branch with the
* following script to check whether the player is currently in a
* temperate/deciduous forest tile (at z=1, which is editor layer 2):
* > Conditional Branch (Script):
* $gameMap.tileCodeAt($gamePlayer.x, $gamePlayer.y, 1) == "A4,2"
*
* $gameMap.tileCode(x,y,z)
* Same as $gameMap.tileCodeAt(x,y,z).
*
* $gameMap.tileMatch(tileIdList, x, y, z)
* $gameMap.tileIdInList(tileIdList, x, y, z)
* $gameMap.autotileInList(autotileList, x, y, z)
* $gameMap.tileIdInListAhead(tileIdList, distance, z)
* $gameMap.tileAhead(tileIdList, distance, z)
* $gameMap.autotileInListAhead(autotileList, distance, z)
* $gameMap.autotileAhead(autotileList, distance, z)
* These script calls return true if the tile at the location matches one
* in the list; false otherwise. They're useful for conditional branches.
* - tileIdList and autotileList are arrays that can
* contain numbers or tile codes (as strings).
* - tileAhead and autotileAhead looks in the direction the player is facing,
* and finds whichever tile is located there at the z level indicated.
* - $gameMap.tileIdInListAhead() is the same as $gameMap.tileAhead().
* - Likwise, $gameMap.autotileInListAhead() is the same as
* $gameMap.autotileAhead().
* Example use case: When the player is pushing an event, you can look
* at the tile(s) 2 steps ahead of the player's current location, to
* determine what happens when the player tries to push the event.
*
* ============================================================================
* Basics of how to use this plugin:
* 1. To change a tile while a player is playing your game, you can create an
* event that runs the plugin command Set Tile.
* 2. In the Set Tile command, type the Tile ID code for your desired tile.
* Use one of the three types of Tile ID codes (described below).
* 3. Choose the coordinates (X, Y, and Z) at which to change the tile.
* Keep in mind that the coordinates are by default relative to the event
* that is running this plugin command.
* 4. You can modify the settings in Relativity & Options, if you like.
* If you want absolute coordinates, or coorcinates relative to the player,
* you can change this here. If you want to keep upper z layers, you can do
* that, too. (Keep autotiling true unless you need to set an autotile
* to an exact value.)
* 5. When you activate the event, the tile at the coordinates you have chosen
* will change to the Tile ID you chose!
* ============================================================================
* Tile ID Codes:
* There are three types of tile ID codes. You can use any of these tile
* codes for the "Tile ID" of plugin commands.
*
* Tx,y Where T is the tab, x is the x position in the tab's tileset,
* and y is the y position in the tab's tileset. Also known as
* "Letter X comma Y" or "Tab X comma Y".
* - This tile code is determined by the Tab (A, B, C, D, or E)
* and the (x,y) position of the desired tile within the
* tilset.
* - For example, in tab A, the top left tile is A0,0 (which in
* the Overworld tileset is ocean).
* - For example, in the default Overworld tileset, use tile code
* A3,1 for a whirlpool.
* - For example, in the default Overworld tileset, use tile code
* B2,1 for a pyramid.
* - You can use tile code B0,0 to erase any tile.
*
* The Tx,y tile ID code assumes that you have a full tileset in
* Tab A. This includes A1, A2, A3, A4, and A5. If a plugin
* command calls for a Tile ID belonging to an absent tile sheet,
* the console will log a warning, and the tile will not be placed.
* If you do not have a full tileset in Tab A, refer to the table
* below for the first Y value of each A tilesheet:
*
* Tilesheet | First Y value (top of its sheet)
* ----------+----------------------------------
* A1 | 0
* A2 | 2
* A3 | 6
* A4 | 10
* A5 | 16
*
* Tabs B, C, D, and E (if present) have a single tilesheet each,
* so finding their x,y coordinates is straightforward.
*
* Tn Where T is the tab, and n is the number of the tile when
* counting tiles from left to right, starting with zero. Also
* known as "Letter Number" or "Tab Number".
* - Tip: This numbering scheme is the same as how regions are
* numbered and displayed in the regions (R) tab, so you can
* use the regions tab to help with counting tiles.
* - For example, in tab A, the first tile is A0 (which in the
* Overworld tileset is ocean).
* - For example, in the default Overworld tileset, use tile code
* A11 for a whirlpool.
* - For example, in the default Overworld tileset, use tile code
* B10 for a pyramid.
* - You can use tile code B0 to erase any tile.
*
* The Tn tile ID code assumes that you have a full
* tileset in Tab A. This includes A1, A2, A3, A4, and A5. If you
* do not have a full tileset in Tab A, refer to the tile code
* cheat sheet below:
*
* 1st code of A1: 0
* 1st code of A2: 16
* 1st code of A3: 48
* 1st code of A4: 80
* 1st code of A5: 128
*
* Exact For this tile code, you must enter the exact tile ID number
* used in RPG Maker's inner code.
* - Tip: The exact tile ID code is only needed if you want to
* set an autotile to an exact shape (ignoring autotiling).
* Note that to ignore autotiling, the "Allow Autotiling"
* option must be Off (or false) in the plugin command
* arguments. (Note: Using exact tile ID for autotiles is
* similar to using Shift+Click in the editor.)
* - Tip: To find the exact tile ID code, while playtesting,
* open the console window by pressing F12 on the keyboard.
* Then, move the party leader character on top of a tile
* with the exact tile appearance you want. Then, hold Ctrl
* while you press Enter. The exact tile IDs at that location
* will be logged to the console.
* - For example, in the default Overworld tileset, use tile code
* 2048 for ocean.
* - For example, in the default Overworld tileset, use tile code
* 2576 for a whirlpool.
* - For example, in the default Overworld tileset, use tile code
* 10 for a pyramid.
* - You can use tile code 0 to erase any tile.
* ============================================================================
* Advanced uses for this plugin:
* - Creep! Creep is calculated after the main fill command has finished. At
* that time, you can add an "appendage" of any tile ID. Creep will by
* default be the same tile ID as the fill; however, you can also define a
* unique tile ID for the creep. The creep can go any distance you like,
* but by default only goes 1 tile further than the fill. Creep uses the
* tiles already filled as a large "origin" from which creep can expand.
* > Creep is especially useful if you want to have fluid that spreads,
* such as flowing water, flowing lava, or flowing poison. However, creep
* can be used with any tile.
* > Note that creep spreads in cardinal directions (north, south, east,
* and west), but not in diagonal directions.
* - Exact tiles! To set an exact tile, you must go to the plugin command's
* options argument, and change Allow Autotiling to false. Then, if you are
* making an exact shape of an autotile, you must know the exact tile ID
* of that shape of the autotile. To find this, create a map with that shape
* of autotile present, then go into playtesting mode. While standing on the
* autotile, hold Ctrl and press OK (Enter) to output the info of the tiles
* at that location to the console window. Press F12 to open the console
* window to see the output info. Use the exact tile ID in the plugin
* command. Setting exact tiles is useful when you want a particular shape
* of an autotile. Note that exact tiles are similar to using Shift+Click
* in the editor, because autotiling is prevented and any autotile can be
* placed anywhere.
* - Hollow filter! You can use this to help you achieve interesting and
* appealing fill shapes! Hollow shapes do respect diagonals. (This is
* different compared to creep or the distance filter, because both creep
* and the distance filter only recognize cardinally neigboring tiles.
* The hollow filter recognizes neighboring tiles both cardinally and
* diagonally.
* - Common Event on OK Press! (And the $gameMap.tileCodeAt(x,y,z) script!)
* You can use this plugin parameter to define a common event that happens
* when the player presses the OK button (Enter for keyboard users). If you
* want the OK press to detect a tile, you can have the common event use the
* $gameMap.tileCodeAt(x,y,z) script call in a conditional branch (see
* example above), so that you know what tiles are located at the player's
* position.
* > If you want to change a tile, it is usually easier to use the Fill
* plugin command, because it has filters. If you use the Fill plugin
* command, you often don't need to use the $gameMap.tileCodeAt(x,y,z)
* script call, because the Fill command has a Tile ID(s) Filter.
* However, if you don't want to change a tile, but just want to know
* what tile code is present, the $gameMap.tileCodeAt(x,y,z) script call
* is useful.
* > You could combine the $gameMap.tileCodeAt(x,y,z) plugin command with
* scripts $gameMap.xWithDirection(x,d) and $gameMap.yWithDirection(y,d)
* to get the tile code in front of the player, or relative to an event.
* However, if you want to modify a tile depending on the player's
* direction, you could also use the Orientational Shift relativity
* option to cause a tile to be modified in front of the player.
* > You could also use a conditional branch to check whether the player
* has a certain item (tool) required to modify a tile.
* ============================================================================
* Reference of how tile information is tracked in RPG Maker:
*
* Exact tile ID reference:
* Tile ID 0 Beginning of Tab B.
* Tile ID 256 Beginning of Tab C.
* Tile ID 512 Beginning of Tab D.
* Tile ID 768 Beginning of Tab E.
* Tile ID 1536 Beginning of Tab A portion A5.
* Tile ID 2048 Beginning of Tab A portion A1. Beginning of autotiles.
* Tile ID 2816 Beginning of Tab A portion A2.
* Tile ID 4352 Beginning of Tab A portion A3.
* Tile ID 5888 Beginning of Tab A portion A4.
* Tile ID 8192 This is the maximum Tile ID.
*
* z Layers:
* z=0: Layer 1 in editor.
* z=1: Layer 2 in editor.
* z=2: Layer 3 in editor.
* z=3: Layer 4 in editor.
* z=4: ShadowBits.
* z=5: Regions.
*
* Shadow Bits:
* Bit 1: Northwest (upper left) corner shadow.
* Bit 2: Northeast (upper right) corner shadow.
* Bit 3: Southwest (lower left) corner shadow.
* Bit 4: Southeast (lower right) corner shadow.
*
* Tile Flags:
* May be expressed as decimal (base 10); binary (base 2, prefix of
* 0b, values of 0 or 1); or hexidecimal (base 16, prefix of 0x, values
* of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, or f).
* Bit 1: Impassible south side of tile. (Hint: 2 key on Numpad.)
* Bit 2: Impassible west side of tile. (Hint: 4 key on Numpad.)
* Bit 3: Impassible east side of tile. (Hint: 6 key on Numpad.)
* Bit 4: Impassible north side of tile. (Hint: 8 key on Numpad.)
* Bit 5: This is a star (*) tile, and so does not affect passage.
* Bit 6: This is a ladder.
* Bit 7: This is a bush.
* Bit 8: This is a counter.
* Bit 9: This is damage floor.
* Bit 10: Impassible to boats.
* Bit 11: Impassible to ships.
* Bit 12: Airships cannot land here (or if bits 1-4 all impassible.)
* Bit 13: Terrain Tags 1 to 7 (in binary).
* Bit 14: Terrain Tags 1 to 7 (in binary).
* Bit 15: Terrain Tags 1 to 7 (in binary).
* ============================================================================
* Visit Tyruswoo.com to ask for help, donate, or browse more of our plugins.
* ============================================================================
* Version History:
*
* v1.0 8/30/2020
* - Tile Control released for RPG Maker MZ!
*
* v1.1 9/12/2020
* - Fixed interpretation of boolean parameters and command arguments in
* some instances.
* - Updates Tile Control to work with Tyruswoo_FollowerControl v1.3 and
* higher.
* - Cleaned up the code so that repetitions are handled more concisely.
*
* v2.0 11/8/2021
* - Fixed bug that was keeping A5 tiles from being placed properly
* when written in the form Ax,y
* - Fixed crash on plugin command calling for a Tile ID from an absent
* tile sheet. Now a warning is logged instead.
* - Fixed bug that kept the map from loading properly in some projects.
* Thanks to Cris Litvin for reporting it and helping us debug!
*
* v3.0 3/10/2023
* - Link Map allows events to change distant maps' tiles.
* - Added the following tile-checking script calls:
* $gameMap.tileIdInList(tileIdList, x, y, z)
* $gameMap.tileIdInListAhead(tileIdList, distance, z)
* $gameMap.tileAhead(tileIdList, distance, z)
* $gameMap.autotileInList(autotileList, x, y, z)
* $gameMap.autotileInListAhead(autotileList, distance, z)
* $gameMap.autotileAhead(autotileList, distance, z)
* - Fixed bug where tile changes were lost if the player opened the
* field menu mid-event.
*
* v3.0.1 8/30/2023
* - This plugin is now free and open source under the MIT license.
*
* v3.0.2 ?/??/2023
* - Now less likely to conflict with other plugins that alter what
* the player's Action Button does.
*
* ============================================================================
* MIT License
*
* Copyright (c) 2023 Kathy Bunn and Scott Tyrus Washburn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the “Software”), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* ============================================================================
* Remember, only you can build your dreams!
* -Tyruswoo
*
* @param Tile Animation Frames
* @type number
* @min 1
* @default 30
* @desc Number of frames elapsed for every animation update of the tilemap. Lower is faster. Higher is slower. Default: 30.
*
* @param Common Event on OK Press
* @type common_event
* @desc Common event to run when the player presses OK (confirm) button. Occurs if other events not triggered. 0 for none.
*
* @param Tile Info on OK Press
* @type boolean
* @default true
* @desc When true, the playtester can hold Ctrl then press the OK (confirm) button to output a tile's ID info to the console.
*
* @command set_tile
* @text Set Tile
* @desc Set a tile by tileId and coordinates. (To find tileId, playtest with "Tile Info on OK Press." See tileId in console with F12.)
*
* @arg tileId
* @type string
* @default A0,0
* @text Tile ID
* @desc Use tile code or exact tile ID. Example codes for same tile (Overworld water): A0,0 or A0 or 2048
*
* @arg coordinates
* @type struct<coordinates>
* @default {"x":"0","y":"0","z":"0"}
* @text X,Y,Z Coordinates
* @desc Coordinates at which to set tile to tileId. +x for east, +y for south. If relative: -x for west, -y for north.
*
* @arg relativity
* @type struct<relativity>
* @default {"mode":"Relative to Event","eventId":"","party_member":"","orientational_shift":"","allowAutotiling":"true","clearUpperLayers":"true"}
* @text Relativity & Options
* @desc Coordinates may be interpreted as absolute, or relative to an event or the player. Also, special options available.
*
* @command fill_tiles
* @text Fill Tiles
* @desc Fill tiles by tileId and filters. (To find tileId, playtest with "Tile Info on OK Press." See tileId in console with F12.)
*
* @arg tileId
* @type string
* @default A0,0
* @text Tile ID
* @desc Use tile code or exact tile ID. Example codes for same tile (Overworld water): A0,0 or A0 or 2048
*
* @arg coordinates
* @type struct<coordinates>
* @default {"x":"0","y":"0","z":"0"}
* @text X,Y,Z Coordinates
* @desc Z layer to fill, and (x,y) at which to begin. +x for east, +y for south. If relative: -x for west, -y for north.
*
* @arg relativity
* @type struct<relativity>
* @default {"mode":"Relative to Event","eventId":"","party_member":"","orientational_shift":"","allowAutotiling":"true","clearUpperLayers":"true"}
* @text Relativity & Options
* @desc Coordinates may be interpreted as absolute, or relative to an event or the player. Also, special options available.
*
* @arg filters
* @type struct<filters>
* @text Filters
* @desc Use these filters to specify which tiles are filled. To be filled, tiles must satisfy all filters.
*
* @command change_animation_frames
* @text Change Animation Frames
* @desc Change the tile animation frames dynamically during gameplay.
* This controls animation speed of water and animated tiles.
*
* @arg tileAnimationFrames
* @type number
* @default 30
* @text Tile Animation Frames
* @desc Higher for slower tile animation. Lower for faster tile animation. Zero makes animated tiles vanish. Default: 30.
*
* @command link_map
* @text Link Map
* @desc Pick a map, and subsequent Tile Control commands will change tiles on that map instead of the current one.
*
* @arg map
* @text Map
* @type text
* @desc Name or ID of the map to link.
*
* @command unlink_map
* @text Unlink Map
* @desc Return to having Tile Control commands affect the map the player is in.
*
*/
/*~struct~coordinates:
* @param x
* @type number
* @default 0
* @min -256
* @max 256
* @text X
* @desc X coordinate value.
*
* @param y
* @type number
* @default 0
* @min -256
* @max 256
* @text Y
* @desc Y coordinate value.
*
* @param z
* @type number
* @default 0
* @min 0
* @max 3
* @text Z
* @desc Z coordinate value. 0 for first layer. 1 for second layer. 2 for third layer. 3 for fourth layer.
*/
/*~struct~relativity:
* @param mode
* @type select
* @option Absolute
* @option Relative to Event
* @option Relative to Player
* @default Relative to Event
* @text Relativity Mode
* @desc Select how coordinates are to be interpreted. If relative, defaults either to this event or to player.
*
* @param eventId
* @parent mode
* @type number
* @text Event ID
* @desc Event ID number of the event whose coordinates are to be used for "Relative to Event." 0 (or empty) for this event.
*
* @param party_member
* @parent mode
* @type select
* @option Player
* @option Leader
* @option Follower 1
* @option Follower 2
* @option Follower 3
* @option Follower 4
* @option Follower 5
* @option Follower 6
* @option Follower 7
* @option Follower 8
* @option Follower 9
* @text Party Member
* @desc Party member whose coordinates are used for "Relative to Player". Default: Player. Can use Follower Control plugin.
*
* @param orientational_shift
* @parent mode
* @type struct<shift>
* @text Orientational Shift
* @desc With "Relative to Event" or "Relative to Player", modify coordinates based on direction character is facing.
*
* @param allowAutotiling
* @type boolean
* @on Allow Autotiling
* @off Exact Tile Only
* @default true
* @text Allow Autotiling
* @desc If false, then autotiling will not occur (which is similar to Shift+Click with the editor.)
*
* @param clearUpperLayers
* @type boolean
* @on ON
* @off OFF
* @default true
* @text Clear Upper Layers
* @desc If true, then any layers above the z coordinate will be replaced with an empty tile (tile B0,0).
*/
/*~struct~shift:
* @param forward_shift
* @type number
* @default 0
* @min -256
* @max 256
* @text Forward Shift
* @desc Modify coordinates based on the direction the character is facing. Positive for forward. Negative for backward.
*
* @param rightward_shift
* @type number
* @default 0
* @min -256
* @max 256
* @text Rightward Shift
* @desc Modify coordinates based on the direction the character is facing. Positive for rightward. Negative for leftward.
*/
/*~struct~filters:
* @param region_filter
* @type number[]
* @text Region(s) Filter
* @desc Region(s) to recognize as appropriate for being filled. 0 to recognize tiles lacking a region.
*
* @param tileId_filter
* @type struct<tileIdFilter>
* @text Tile ID(s) Filter
* @desc Tile ID(s) to recognize as appropriate for being filled. Also, layers (Z coords) to search for these tile ID(s).
*
* @param area_filter
* @type struct<area>
* @text Area Filter
* @desc Coordinates defining the corners of the area to be filled. (Coordinates are affected by relativity, if any.)
*
* @param distance
* @type number
* @text Distance Filter
* @desc Distance to fill adjacent tiles, from start coordinates. Respects boundaries defined by previous filters.
*
* @param hollow
* @type boolean
* @on Hollow
* @off Regular Fill
* @text Hollow Filter
* @desc If hollow, then inside will not be filled. If regular fill, then entire selection is filled. Default: Regular.
*
* @param origin
* @type select
* @option Regular
* @option Never Fill
* @option Always Fill (Before Creep)
* @option Always Fill (After Creep)
* @text Origin Filter
* @desc Special fill condition for the origin. The origin is the location of the (X, Y, Z) Coordinates.
*
* @param creep
* @type struct<creep>
* @text Creep
* @desc After fill space is determined, creep onto additional tiles beyond identified fill space.
*/
/*~struct~area:
* @param x1
* @type number
* @default 0
* @min -256
* @max 256
* @text X1
* @desc X1 coordinate value.
*
* @param y1
* @type number
* @default 0
* @min -256
* @max 256
* @text Y1
* @desc Y1 coordinate value.
*
* @param x2
* @type number
* @default 0
* @min -256
* @max 256
* @text X2
* @desc X2 coordinate value.
*
* @param y2
* @type number
* @default 0
* @min -256
* @max 256
* @text Y2
* @desc Y2 coordinate value.
*/
/*~struct~tileIdFilter:
* @param tileIds_recognized
* @type string[]
* @default
* @text Tile ID(s) Recognized
* @desc Use tile code or exact tile ID. Example codes for same tile (Overworld water): A0,0 or A0 or 2048
*
* @param z_coordinates_recognized
* @type struct<zCoordinatesRecognized>
* @text Z Coord(s) Recognized
* @desc Z layers to recognize as included. By default, all layers are searched for tiles matching the tile ID(s) filter.
*/
/*~struct~zCoordinatesRecognized:
* @param z0
* @type select
* @option Recognize
* @option Skip
* @default Recognize
* @text Layer 1 (z=0)
* @desc "Recognize" to include this layer. "Skip" to exclude this layer.
*
* @param z1
* @type select
* @option Recognize
* @option Skip
* @default Recognize
* @text Layer 2 (z=1)
* @desc "Recognize" to include this layer. "Skip" to exclude this layer.
*
* @param z2
* @type select
* @option Recognize
* @option Skip
* @default Recognize
* @text Layer 3 (z=2)
* @desc "Recognize" to include this layer. "Skip" to exclude this layer.
*
* @param z3
* @type select
* @option Recognize
* @option Skip
* @default Recognize
* @text Layer 4 (z=3)
* @desc "Recognize" to include this layer. "Skip" to exclude this layer.
*/
/*~struct~creep:
* @param creep_distance
* @type number
* @default 1
* @text Creep Distance
* @desc Distance for creep to travel on adjacent tiles. Respects boundaries defined by creep filters. 0 for no creep.
*
* @param creep_tileId
* @type string
* @text Creep Tile ID
* @desc Tile code for creep. Defaults to fill tileId. Example codes for same tile (Overworld water): A0,0 or A0 or 2048
*
* @param creep_z_coordinate
* @type number
* @text Creep Z Coordinate
* @desc Z coordinate for creep. Defaults to fill Z coordinate. 0 for Layer 1. 1 for Layer 2. 2 for layer 3. 3 for layer 4.
*
* @param creep_options
* @type struct<creepOptions>
* @default {"creepAllowAutotiling":"true","creepClearUpperLayers":"true"}
* @text Creep Options
* @desc Special options for creep.
*
* @param creep_filters
* @type struct<creepFilters>
* @text Creep Filters
* @desc Use these filters to specify which tiles can have creep. To receive creep, tiles must satisfy all creep filters.
*/
/*~struct~creepOptions:
* @param creepAllowAutotiling
* @type boolean
* @on Allow Autotiling
* @off Exact Tile Only
* @default true
* @text Allow Autotiling
* @desc If false, then creep autotiling will not occur (which is similar to Shift+Click with the editor.)
*
* @param creepClearUpperLayers
* @type boolean
* @on ON
* @off OFF
* @default true
* @text Clear Upper Layers
* @desc If true, then any layers above the z coordinate will be replaced with an empty tile (tile B0,0).
*/
/*~struct~creepFilters:
* @param creep_region_filter
* @type number[]
* @text Creep Region(s) Filter
* @desc Region(s) to recognize as appropriate for creep. 0 to recognize tiles lacking a region.
*
* @param creep_tileId_filter
* @type struct<tileIdFilter>
* @text Creep TileID(s) Filter
* @desc Tile ID(s) to recognize as appropriate for creep. Also, layers (Z coords) to search for these tile ID(s).
*
* @param creep_area_filter
* @type struct<area>
* @text Creep Area Filter
* @desc Coordinates defining the corners of the area for creep. (Coordinates are affected by relativity, if any.)
*
* @param creep_hollow
* @type boolean
* @on Hollow
* @off Regular Creep
* @text Creep Hollow Filter
* @desc If hollow, then inside will not have creep. If regular, then entire selection receives creep. Default: Regular.
*/
(() => {
const pluginName = "Tyruswoo_TileControl";
Tyruswoo.TileControl.parameters = PluginManager.parameters(pluginName);
Tyruswoo.TileControl.param = Tyruswoo.TileControl.param || {};
// User-Defined Plugin Parameters
Tyruswoo.TileControl.param.tileAnimationFrames = Number(Tyruswoo.TileControl.parameters['Tile Animation Frames']);
Tyruswoo.TileControl.param.tileInfoOnOkPress = (Tyruswoo.TileControl.parameters['Tile Info on OK Press'] == "true") ? true : false;
Tyruswoo.TileControl.param.commonEventOnOkPress = Number(Tyruswoo.TileControl.parameters['Common Event on OK Press']);
// Variables
Tyruswoo.TileControl._tileAnimationFrames = Tyruswoo.TileControl.param.tileAnimationFrames;
Tyruswoo.TileControl._pluginCommandEventId = 0; //Keep track of the most recent event to run a plugin command.
// Default values for plugin command arguments.
const defaultCoordinates = {"x":"0", "y":"0", "z":"0"};
const defaultRelativity = {"mode":"Relative to Event","eventId":"","party_member":"","orientational_shift":"","allowAutotiling":"true","clearUpperLayers":"true"};
const defaultOrientationalShift = {"forward_shift":"0","rightward_shift":"0"};
const defaultFilters = {"region_filter":"","tileId_filter":"","area_filter":"","distance":"","hollow":"","origin":"","creep":""};
const defaultRegionFilter = null;
const defaultTileIdFilter = null;
const defaultTileIdsFilter = null;
const defaultTileIdZFilter = {"z0":"Recognize","z1":"Recognize","z2":"Recognize","z3":"Recognize"};
const defaultAreaFilter = null;
const defaultCreep = {"creep_distance":"","creep_tileId":"","creep_z_coordinate":"","creep_options":"","creep_filters":""};
const defaultCreepOptions = {"creepAllowAutotiling":"true","creepClearUpperLayers":"true"};
const defaultCreepFilters = {"creep_region_filter":"","creep_tileId_filter":"","creep_area_filter":"","creep_hollow":""};
const defaultCreepRegionFilter = null;
const defaultCreepTildIdFilter = null;
const defaultCreepTileIdsFilter = null;
const defaultCreepTileIdZFilter = {"z0":"Recognize","z1":"Recognize","z2":"Recognize","z3":"Recognize"};
const defaultCreepAreaFilter = null;
const TILE_SELECTOR_ROW_SIZE = 8;
const TILES_PER_A_SHEET = [ 0, 16, 32, 32, 48, 128 ];
const FIRST_A_CODE_NUMBER = [ 0, 0, 16, 48, 80, 128 ];
const TILE_SHEET_INDEXES_BY_NAME = {
A1: 0, A2: 1, A3: 2, A4: 3, A5: 4, B: 5, C: 6, D: 7, E: 8
};
//=============================================================================
// Tile Control Functions
//=============================================================================
Tyruswoo.TileControl.loadReferenceMapSync = function(mapId) {
if ($gameMap && mapId == $gameMap.mapId() && $dataMap) {
// It's the currently loaded map. No need to open it again.
return $dataMap;
} else if (Tyruswoo.mapCache && Tyruswoo.mapCache[mapId]) {
// It's a cached map. Retrieve it.
return Tyruswoo.mapCache[mapId];
}
// If we're still here, we need to load a not-yet-cached map.
const fs = require('fs');
const path = "data/Map%1.json".format(mapId.padZero(3));
const json = fs.readFileSync(path, 'utf8');
const mapObj = JSON.parse(json);
Tyruswoo.mapCache = Tyruswoo.mapCache || [];
Tyruswoo.mapCache[mapId] = mapObj;
return mapObj;
};
Tyruswoo.TileControl.tileIdExists = function(tilesetId, tileId) {
const tileSheetName = this.getTileSheetNameOfTileId(tileId);
return this.tileSheetExists(tilesetId, tileSheetName);
};
Tyruswoo.TileControl.getSheetNumberOfCode = function(codeNumber) {
for (var i = 1; i < 5; i++) {
if (codeNumber < FIRST_A_CODE_NUMBER[i+1]) {
return i;
}
}
// It's on or after the first A5 tile.
return 5;
};
Tyruswoo.TileControl.tileSheetExists = function(tilesetId, tileSheetName) {
const sheetIndex = TILE_SHEET_INDEXES_BY_NAME[tileSheetName];
if (undefined === sheetIndex) {
return false;
}
const tileset = $dataTilesets[tilesetId];
const sheetName = tileset.tilesetNames[sheetIndex];
return !!sheetName && sheetName.length > 0;
};
Tyruswoo.TileControl.getTileSheetNameOfTileId = function(tileId) {
if (tileId < Tilemap.TILE_ID_B) {
console.warn("Unexpected negative tile ID: " + tileId);
return "?";
} else if (tileId < Tilemap.TILE_ID_C) {
return "B";
} else if (tileId < Tilemap.TILE_ID_D) {
return "C";
} else if (tileId < Tilemap.TILE_ID_E) {
return "D";
} else if (tileId < Tilemap.TILE_ID_A5) {
return "E";
} else if (Tilemap.isTileA1(tileId)) {
return "A1";
} else if (Tilemap.isTileA2(tileId)) {
return "A2";
} else if (Tilemap.isTileA3(tileId)) {
return "A3";
} else if (Tilemap.isTileA4(tileId)) {
return "A4";
} else if (Tilemap.isTileA5(tileId)) {
return "A5";
} else {
console.warn("Unexpected tile ID: " + tileId);
return "?";
}
};
// New method
// This method takes a tileId as input, and returns the tileCode.
Tyruswoo.TileControl.tileCodeFromId = function(tileId) {
var tileCode = "";
var codeX = 0;
var codeY = 0;
if (tileId >= Tilemap.TILE_ID_A1) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_A1) / (48 * 8));
codeX = Math.floor((tileId - Tilemap.TILE_ID_A1 - codeY * 48 * 8) / 48);
tileCode = "A" + codeX + "," + codeY;
} else if (tileId >= Tilemap.TILE_ID_A5) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_A5) / 8) + 16;
codeX = tileId - Tilemap.TILE_ID_A5 - (codeY - 16) * 8;
tileCode = "A" + codeX + "," + codeY;
} else if (tileId >= Tilemap.TILE_ID_E) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_E) / 8);
codeX = tileId - Tilemap.TILE_ID_E - codeY * 8;
tileCode = "E" + codeX + "," + codeY;
} else if (tileId >= Tilemap.TILE_ID_D) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_D) / 8);
codeX = tileId - Tilemap.TILE_ID_D - codeY * 8;
tileCode = "D" + codeX + "," + codeY;
} else if (tileId >= Tilemap.TILE_ID_C) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_C) / 8);
codeX = tileId - Tilemap.TILE_ID_C - codeY * 8;
tileCode = "C" + codeX + "," + codeY;
} else if (tileId >= Tilemap.TILE_ID_B) {
codeY = Math.floor((tileId - Tilemap.TILE_ID_B) / 8);
codeX = tileId - Tilemap.TILE_ID_B - codeY * 8;
tileCode = "B" + codeX + "," + codeY;
}
return tileCode;
};
// With input of args from Tile Control plugin command, outputs an array [x, y, z], with accounting for relativity options.
Tyruswoo.TileControl.extract_xyz_array = function(args, linkedMap=null) {
const coordinates = args.coordinates ? JSON.parse(args.coordinates) : defaultCoordinates;
const relativity = args.relativity ? JSON.parse(args.relativity) : defaultRelativity;
const orientational_shift = relativity.orientational_shift ? JSON.parse(relativity.orientational_shift) : defaultOrientationalShift;
var x = Number(coordinates.x);
var y = Number(coordinates.y);
const z = Number(coordinates.z);
if (relativity.mode == "Relative to Event") {
const eventId = Number(relativity.eventId) ? Number(relativity.eventId) : Tyruswoo.TileControl._pluginCommandEventId;
let event;
let direction;
if (linkedMap) {
event = linkedMap.events[eventId];
direction = event.direction;
} else {
event = $gameMap.event(eventId);
direction = event.direction();
}
if (event) {
const f = Number(orientational_shift.forward_shift) ? Number(orientational_shift.forward_shift) : 0;
const r = Number(orientational_shift.rightward_shift) ? Number(orientational_shift.rightward_shift) : 0;
const xy_shift = Tyruswoo.TileControl.orientationalShift(direction, f, r);
x = x + event.x + xy_shift[0];
y = y + event.y + xy_shift[1];
}
} else if (relativity.mode == "Relative to Player") {
var p = $gamePlayer; //By default, the party leader is selected.
if (Imported.Tyruswoo_FollowerControl) { //However, if Tyruswoo_FollowerControl is installed, then the currently selected follower is automatically selected.
p = Tyruswoo.FollowerControl.follower();
}
if (relativity.party_member == "Leader") {
p = $gamePlayer; //Regardless of whether Tyruswoo_FollowerControl is installed, the "Leader" option can be used to select the leader.
} else if (relativity.party_member.substr(0, 8) == "Follower") {
const n = Number(relativity.party_member.substr(9)); //Get the number at the end of this string.