Paste #12979: BOSS FIGHT CHECK

Date: 2015/01/15 15:33:33 UTC-08:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045


# Boss Fight - Multistage and Highly Configurable
# Citizens 2 (build #991)
# Denizen 0.9.3 (build #1341)
# Sentry 1.5.3
#
# To assign to an NPC, literally type:
# /npc assign --set "bossname"
#
# DISCLAIMER:
# ===========
# This is an advanced script. You should test this script
# before you use it on your LIVE server. Some of the item drops
# ignore ZONE PROTECTION. So if you play on a strict
# server you will want to disable those items by
# removing them from the "BossName Determine Loot" script.
#
# DESCRIPTION:
# ============
#
# This is a four stage boss fight with a bunch of simple configuration
# options that will allow you to create a unique boss fight.
# You can decide how many stages you want to enable, how difficult the
# boss should be (health, armor, strength), whether it should spawn
# minions and if so, how many, how difficult etc. The boss has several
# different 'special attacks' that can be used directly on players or
# inside a "cuboid", which you have to specify in the constant values
# at the top of the script.
#
# The boss can heal or reset itself if no one is in range.
#
# When the boss is killed, it can drop random loot (from a series of
# item scripts that's located towards the bottom of this script) directly
# into players inventory, on the floor around the boss or into secure chests
# for each of the boss fighters.
#
# At the end of the fight, it will show a text scoreboard that shows total
# damage, hit count, minion kills etc for each player.
#
# FEATURES:
# =========
#  * Boss and/or Minions (quantity, health, armor, strength)
#  * Special Attacks (arrow spells, lightning storm, arrows dropping from ceiling)
#  * Boss heal/reset itself if inactive
#  * Unique item drops, using item scripts and world events
#  * Text scoreboard showing battle summary stats
#  * Shows health bar when you right click boss or minion.
#
# NOTE: 
# ====
# If you want to use this on more than one NPC you simply need to do
# a FIND on the word 'BossName' and REPLACE it with your NPC name. Then
# make another copy of the script and do another FIND/REPLACE for every
# boss NPC that will use this.
#
# CREDITS:
# ========
# Thanks to aufdemrand, davidcernat and mcmonkey for fixing/adding things in
# Denizen. Thanks to Matterom and blankiito for example scripts on the work 
# they've done on custom items and effects.
#
#
# @author mythanical
# @script version 0.2
# @last-updated October 22 2013
# @irc EsperNet IRC Network #denizen-dev
# @Minecraft Server - minecraft.geek.nz
# @Donate Bitcoin: 1Fzacc2gZ5NGRMXg5jWP6NcUkWei34xjzt
# @Donate Litecoin: LhsaGa1QzmVLjMYwg4ZPTVnmSgnBDGc75U


"BossName":
  type: assignment

  default constants:

    # --------------------------------------------------------------------------------------------------------
    # NOTE: 'Player' entity type NPC's are fully supported by Sentry, but other types may give you some
    #       interesting, unexpected or undesired results. Especially when you try and equip them with a
    #       weapon.
    #
    # The following NPC types are available as part of Citizens (http://wiki.citizensnpcs.com/Types):
    #
    # blaze, bat, cave_spider, chicken, creeper, cow, enderman (goes crazy in rain), 
    # ender_dragon (do not recommend), ghast (do not recommend), giant (massive zombie!), iron_golem, 
    # magma_cube (careful! damages nearby players), mushroom_cow, ocelot, pig, pig_zombie, 
    # player (will use skin of player with same name), sheep, silverfish, squid (can't walk on land...duh),
    # snowman, wolf, skeleton, slime, spider, witch, witherboss (does not move), villager, 
    # zombie (burns in sunlight, but invulnerable)
    # --------------------------------------------------------------------------------------------------------

    Boss Entity Type: player

    # adult                 (Normal NPC type)
    # baby                  (Cause the Boss to be a baby. Note: Not all entity types have a baby version)
    Boss Age: adult

    # The following Sentry weapons are fully supported by 'player' type entity (http://wiki.citizensnpcs.com/Sentry):
    # bow                   (Archer - Range is 50 meters on flat ground.)
    # redstone_torch_on     (Pyromancer I - Shoot small, non-incendiary fireballs)
    # torch                 (Pyromancer II -  Shoot fireballs that set the land on fire)
    # blaze_rod             (Pyromancer III - Shoot large, explosive fireballs that set the land on fire)
    # snow_ball             (Ice Magi - Throw snowballs which slow enemies on contact. Snowballs have a range of about 25 blocks on flat ground)
    # egg                   (Bombardiers - explode?  Eggs have a range of about 25 blocks on flat ground)
    # potion                (Witch Doctor - Will throw a splash version of whatever potion type it is equipped with)
    # paper                 (Stormcaller I - Strike single targets with bolts of electricity)
    # book                  (Stormcaller II - Smite multiple foes. This lightning's damage is atmospheric and therefore is not affected by the Sentry's strength)
    # book_and_quill        (Stormcaller III - Bolts instantly kill any living thing they touch regardless of health, armor, or play mode)
    # ender_pearl           (Warlock I - Fling targets high into the air)
    # skull_item            (Warlock II - Mid-range warlock shoots black explosive wither skulls at the enemy)
    # none                  (Brawler - Swords, axes, picks, shovels, rocks, bricks, or even fish, the brawlers take the fight to the enemy, hand to hand)
    Boss Weapon: none

    # The sentry values for the boss, you can check out what these mean at:
    # http://wiki.citizensnpcs.co/Sentry
    Boss Health: 500
    Boss Strength: 1
    Boss Armor: 1
    Boss Agro Range: 15

    # Awareness range will still trigger special attacks.
    Boss Awareness Range: 30
    Boss Movement Speed: 1

    # If all players have left the boss proximity, this enables the boss to heal itself slowly.
    Boss Exit Proximity Self Healing: "Yes"

    # Set the location where your boss will respawn
    Boss Spawn Location: "-151,65,80,world"

    # Set to -1 if you never want the boss to respawn and be permanently destroyed on death.
    Boss Respawn Delay: 600

    # On default, boss fight will reset after 120s of inactivity. Set to 0 if you don't ever want it to reset
    # and allow players to come back later to finish it.
    Boss Reset Timer: 120

    # The item scripts for the loot is located at the bottom. It will give each player, that hit the boss or a minion
    # at least once, a random item.
    Drop Loot on Death: "Yes"

    # The specifies how much loot per player
    Loot Quantity: 1

    # This specifies how the loot should be distributed.
    # player                (Put the item into the players inventory)
    # boss                  (Drop the loot on the ground around the boss)
    # chest                 (Spawn a chest with all the loot inside it where the boss died)
    # playerchest           (Create a chest next to each player that only they can access)
    Loot Distribution: playerchest

    # To prevent any loot chests from staying forever, give them any value other than 0
    # and they will expire..dropping all the loot on the floor.
    Loot Chest Expiry: 600

    # Enable scoreboard (on right side of screen) to show either Minion Kills or Boss Health Damage by each player
    # during the fight. This gets removed when the boss is killed.
    # bosshealth            (Show running damage dealt to boss by each player)
    # minionkills           (Show a count for number of minions killed by players)
    # minionhealth          (Show the running damage dealt to minions by each player)
    # none                  (No running battle scoreboard)
    Scoreboard: bosshealth

    # The cuboid is the square area (a room) where most of the fighting will take place. This area can be used in the options below
    # to allow mobs to be spawned in it or to have some of the boss special fighting skills to take place in. 
    Cuboid Spawn Area Poss 1: "-162,68,77,world"
    Cuboid Spawn Area Poss 2: "-141,63,105,world"

    # What will trigger the start of the boss fight? 
    # proximity             (Activate if a player walks into the proximity specified in the "Boss Awareness Range" constant value above)
    # damage                (Activate boss fight when damaged by a player)
    Bossfight Activator: damage

    # Currently the script supports 4 battle stages. A stage is reached/unlocked when the boss is down to a specified health percentage.
    # You decide the boss health percentage, minion names, the quantity to spawn, NPC types and how/where they spawn.
    # If you want less stages, simply remove them from the list. If you don't want any, type in "none". Make sure to type it as "One|Two|Three|Four".
    # If you only want the first two stages, type it as: One|Two

    Enabled Boss Stages: One|Two|Three|Four

    # The sections below detail the values for each of the 4 stages of the boss fight. You should modify these to make each boss fight unique.
    Stage One Boss Health Percentage: 95

    # none                  (No effect around NPC)
    # flame                 (Create a fiery effect around the boss)
    # heart                 (Surrounds the boss with love hearts - kill you with love??)
    # smoke                 (Create a smokey 'pop' effect around the boss)
    # ender                 (Create the Enderman particles around NPC)
    # potbreak              (Not very good, also makes the pot break sound)
    # explosion             (Creeper explosion effect, causes no damage)
    Stage One Boss Aura: smoke

    # "Poison Arrow"        (Shoot a poisonous arrow towards a randomly chosen player. Only casts when the player is hit)
    # "Wither Arrow"        (Cast wither...)
    # "Weakness Arrow"      (Cast weakness...)
    # "Slowness Arrow"      (Cast slowness...)
    # "Rain Arrows"         (Rain arrows from the sky - note: you need provide values for the "Cuboid Spawn Area Poss x" above for this to work)
    # "Lightning Bolt"      (Hit a single random player with a lightning bolt - this never misses)
    # "Lightning Storm"     (Several damaging lightning bolts - note: you to need provide values for the "Cuboid Spawn Area Poss x" above for this to work)
    # "TNT"                 (Boss tosses a block of primed tnt at a random player)
    # "TNT Drop"            (Drop 5 blocks of TNT in random locations in the cuboid - Minecraft/Bukkit bug prevents this from working)
    # "Throw"               (This will cause 3 players to be thrown from their current position to a random location inside the cuboid)
    # "Firestarter"         (Ignite 10 random blocks in the cuboid)
    # none                  (No special attack)
    Stage One Boss Special Attack: "Poison Arrow"

    # Run the special attack on a loop, once every 20 seconds.
    Stage One Boss Special Attack Delay: 20s

    Stage One Spawn Minions: "Yes"
    Stage One Minion Type: zombie
    Stage One Minion Age: baby
    Stage One Minion Name: RotWalker
    Stage One Minion Weapon: wood_sword
    Stage One Minion Health: 30
    Stage One Minion Quantity: 5
    Stage One Minion Strength: 2
    Stage One Minion Armor: 3
    Stage One Minion Speed: 0.5

    # lightning             (lightning bolt with sound)
    # explode               (harmless explosion effect with sound)
    # none                  (no effect)
    Stage One Minion Spawn Effect: none

    # player: spawn around random player
    # boss: spawn around boss
    # cuboid: spawn anywhere inside the cuboid values you specified above
    Stage One Minion Spawn Location: player

    # Boss - Stage Two
    Stage Two Boss Health Percentage: 75
    Stage Two Boss Aura: ender
    Stage Two Boss Special Attack: "Wither Arrow"
    Stage Two Boss Special Attack Delay: 30s
    Stage Two Spawn Minions: "Yes"
    Stage Two Minion Type: cave_spider
    Stage Two Minion Age: adult
    Stage Two Minion Name: Crawler
    Stage Two Minion Weapon: none
    Stage Two Minion Health: 5
    Stage Two Minion Quantity: 15
    Stage Two Minion Strength: 1
    Stage Two Minion Armor: 1
    Stage Two Minion Speed: 1.5
    Stage Two Minion Spawn Effect: lightning
    Stage Two Minion Spawn Location: cuboid

    # Boss - Stage Three
    Stage Three Boss Health Percentage: 50
    Stage Three Boss Aura: flame
    Stage Three Boss Special Attack: Firestarter
    Stage Three Boss Special Attack Delay: 20s
    Stage Three Spawn Minions: "Yes"
    Stage Three Minion Type: blaze
    Stage Three Minion Age: adult
    Stage Three Minion Name: FireElement
    Stage Three Minion Weapon: none
    Stage Three Minion Health: 30
    Stage Three Minion Quantity: 5
    Stage Three Minion Strength: 2
    Stage Three Minion Armor: 8
    Stage Three Minion Speed: 1
    Stage Three Minion Spawn Effect: explode
    Stage Three Minion Spawn Location: boss

    # Boss - Stage Four
    Stage Four Boss Health Percentage: 25
    Stage Four Boss Aura: heart
    Stage Four Boss Special Attack: "TNT Drop"
    Stage Four Boss Special Attack Delay: 20s
    Stage Four Spawn Minions: "Yes"
    Stage Four Minion Type: iron_golem
    Stage Four Minion Age: adult
    Stage Four Minion Name: Terminator
    Stage Four Minion Weapon: none
    Stage Four Minion Health: 50
    Stage Four Minion Quantity: 5
    Stage Four Minion Strength: 3
    Stage Four Minion Armor: 8
    Stage Four Minion Speed: 1.2
    Stage Four Minion Spawn Effect: lightning
    Stage Four Minion Spawn Location: cuboid

#WARNING# Only continue past this point if you know what you're doing!! #WARNING#

  interact scripts:
  - 10 BossName Script

  actions:
    on assignment:
    # For this script, the click trigger is only used to return the boss's health.
    - trigger name:click toggle:true
    # Proximity set to a radius of 30, you should increase this in the 
    # "Boss Awareness Range" constant above if you're fighting in a large arena.
    - trigger name:proximity toggle:true "radius:<cons:Boss Awareness Range>"
    # Damage trigger does a whole bunch of stuff which I'll explain in that section.
    - trigger name:damage toggle:true

    # Create a NPC flag called "cuboid" that stores the cuboid values in a simple
    # shorter name which makes it easy for reuse.
    - flag npc "cuboid:cu@<cons:Cuboid Spawn Area Poss 1>|<cons:Cuboid Spawn Area Poss 2>"

    # The following commands sets up the Boss using the values specified in the 
    # constants above.
    - execute as_server "npc sel <npc.id>"
    - execute as_server "npc type <cons:Boss Entity Type>"
    - if "<cons:Boss Age>" == baby age <npc> baby
    - execute as_server "npc speed <cons:Boss Movement Speed>"
    - execute as_server "npc lookclose"
    - execute as_server "trait sentry"
    - execute as_server "sentry health <cons:Boss Health>"
    - execute as_server "sentry respawn <cons:Boss Respawn Delay>"
    - execute as_server "sentry speed <cons:Boss Movement Speed>"
    - execute as_server "sentry strength <cons:Boss Strength>"
    - execute as_server "sentry armor <cons:Boss Armor>"
    - execute as_server "sentry range <cons:Boss Agro Range>"
    - if "<cons:Boss Weapon>" != none execute as_server "sentry equip <cons:Boss Weapon>"

    # Put the boss stages into a flag - this will be used throughout to check which boss
    # stages should be activated.
    - flag npc "Enabled Boss Stages:<cons:Enabled Boss Stages>"

    # This is used in world events further down to prevent self/minion harm.
    - flag global ListOfBosses:<npc>

    # This is used by the minions to prevent teleporting to players when the player exits
    # their awareness range. (Temporary until Sentry is fixed)
    - flag npc "Minion Awareness Range:<cons:Boss Awareness Range>"

    on spawn:
    # Teleport boss back to starting point.
    - teleport <npc> "location:<cons:Boss Spawn Location>"

    # Every time the boss spawns after it's been killed, it'll run through the following process
    # to do some 'clean-up' from the previous battle.
    #
    # First it runs through a global "minion" list and check to see whether they are despanwed and
    # if they have a "creator". It then removes them from the global list and executes the "remove"
    # command to permanently get rid of them.
    #
    # Clear the Sentry target list, so it doesn't attack players unprovoked.
    #
    # Remove the "R.I.P" sign it placed when and where it died.
    #
    # Set up the Minecraft scoreboard.
    # First it checks to see if its meant to create a Scoreboard, if so, it'll flag the
    # NPC with what the scoreboard should show:
    #   * bosshealth
    #   * minionkills
    #   * miniondamage
    #
    # It uses the "substring" to put a limit in place for the length of the boss's name because
    # if the name is too long, the scoreboard will fail to create.

    - if <npc.flag[BossDied]> {
      - flag npc BossDied:!

      - foreach <global.flag[AllMinions].aslist> {
        - if <npc[%value%].is_spawned> != true && <npc[%value%].flag[MinionCreator]> != null {
          - flag global AllMinions:<-:%value%
          - remove %value% }
        }

      - execute as_server "npc sel <npc.id>"
      - execute as_server "sentry target clear"

      - if "<location[<npc.flag[DeathLocation]>].block.sign_contents>" contains <npc.name> modifyblock <npc.flag[DeathLocation]> air

      - if <cons:Scoreboard> != none && <npc.flag[Scoreboard]> == null {
        - flag <npc> Scoreboard:<cons:Scoreboard>
        - if <npc.flag[Scoreboard]> == "bosshealth" {
          - execute as_server "scoreboard objectives add <npc.name.substring[1,9]>.Damage dummy"
          - execute as_server "scoreboard objectives setDisplay sidebar <npc.name.substring[1,9]>.Damage" }
          else if <npc.flag[Scoreboard]> == "minionkills" {
            - execute as_server "scoreboard objectives add <npc.name.substring[1,5]>.MinionKills dummy"
            - execute as_server "scoreboard objectives setDisplay sidebar <npc.name.substring[1,5]>.MinionKills" }
          else { 
            - execute as_server "scoreboard objectives add <npc.name.substring[1,6]>.MinionDmg dummy"
            - execute as_server "scoreboard objectives setDisplay sidebar <npc.name.substring[1,6]>.MinionDmg" }
        }
      }

    on death:
    # When the boss dies, there is a bunch of clean-up that needs to happen.
    #
    # It goes through a couple of 'foreach' loops to remove all the minions that were created
    # during the various stages. Each minion was added to the boss flag list and now it simply
    # iterates through removing each minion by substituting %value% with their NPC ID, e.g.  n@123
    - foreach "<npc.flag[Enabled Boss Stages].aslist>" {
              - foreach "<npc.flag[Stage%value%Minions].aslist>" {
                  - if <npc> != %value% remove <npc[%value%]>
              }
      }

    # It then clears the minion list for each battle stage.
    - foreach "<npc.flag[Enabled Boss Stages].aslist>" {
              - flag <npc> "Stage%value%Minions:!"
      }

    # Remove the next 2 lines if you don't like it. What it does is flag where the boss died and put a
    # sign into the ground with the boss's name, followed by "was defeated here". The "|" means go onto
    # the next line on the sign.
    - flag npc DeathLocation:<npc.location.simple>
    - sign <npc.flag[DeathLocation]> "<npc.name>|was defeated|here."

    # The following section builds the text scoreboard that is displayed in the Minecraft chat when
    # the boss has been killed.
    #
    # The IF checks to see if anybody hit the boss at any point (using the "BossHitList" flag).
    # You'll see further down that this list is populated by the damage trigger when the boss is hit
    # by a player.
    #
    # It then announces to the server the result of the battle. It uses a foreach loop to cycle through
    # all players that hit the boss (even those that didn't penetrate its amor) and shows for each player
    # how much damage, their overall damage percentage and the number of times they hit the boss.
    #
    # If the player also damaged and killed minions, it will show another line with minion total damage,
    # hit count and number of minions killed.
    #
    # This is all recorded into flags during the damage trigger and on death action for the boss and minions.
    #
    # At the bottom it shows a list of all players that got into the "Boss Awareness Range" but never
    # damaged/hit the boss or minions, e.g SPECTATORS.
    #
    # During the foreach loop, it also clears all the player flags to ready them for the next battle.
    #
    # Lastly, it checks to see if the "Drop Loot on Death" is set to "Yes", and if so it runs the task
    # called "BossName Drop the Loot" instantly.

    - if <npc.flag[BossHitList]> != null {
      - announce "<red>BOSS EVENT<&co> <white><npc.name><red> has been killed by <yellow><npc.flag[BossHitList].formatted><red>."
      - announce "<green>------------------------------------------"
      - announce "<green><underline>Battle Stats<&co>"
      - announce ""
      - announce "<red><npc.name> Total Health<&co> <npc.health.max.as_int>"
      - foreach <npc.flag[BossHitList].aslist> {
        - define bosspercentage <util.as_element[<m:<player[%value%].flag[BossPlayerTotalDamage]>/<npc.health.max>*100>].asint>
        - announce "<yellow><%value%.name>|"
        - announce "<aqua>Boss Damage <gold><player[%value%].flag[BossPlayerTotalDamage].as_int> (<%bosspercentage%><&pc>) <aqua>- Hits| <gold><player[%value%].flag[BossPlayerHitCount].as_int>"
        - if <player[%value%].flag[MinionTotalDamage]> != null {
          - announce "<aqua>Combined Minion Damage <gold><player[%value%].flag[MinionTotalDamage].as_int || 0> <aqua>- Hits| <gold><player[%value%].flag[MinionHitCount].as_int || 0> <aqua>- Minions Killed| <gold><player[%value%].flag[MinionsKilledCount].as_int || 0>" }
        - flag player:%value% BossPlayerTotalDamage:!
        - flag player:%value% BossPlayerHitCount:!
        - flag player:%value% MinionsKilledCount:!
        - flag player:%value% MinionHitCount:!
        - flag player:%value% MinionTotalDamage:! }
      - announce "<green>------------------------------------------"
      - foreach <npc.flag[BossSpectatorList].aslist> {
        - if <npc.flag[BossHitList].aslist> contains %value% flag npc BossSpectatorList:<-:%value% }
      - if <npc.flag[BossSpectatorList].size> >= 1 announce "Spectators| <npc.flag[BossSpectatorList].formatted>"
      - if "<cons:Drop Loot on Death>" == "Yes" run "BossName Drop the Loot" instantly
      }

    # Remove any visual effects applied at fight stages and clear sentry targets.
    - execute as_server "npc sel <npc.id>"
    - execute as_server "npc effect --play none"
    - execute as_server "sentry target clear"

    # If the scoreboard was enabled, this will remove it so it doesn't stay behind on player's screens.
    - if <npc.flag[Scoreboard]> != null {
      - if <npc.flag[Scoreboard]> == "bosshealth" execute as_server "scoreboard objectives remove <npc.name.substring[1,9]>.Damage"
        else if <npc.flag[Scoreboard]> == "minionkills" execute as_server "scoreboard objectives remove <npc.name.substring[1,5]>.MinionKills"
        else if <npc.flag[Scoreboard]> == "minionhealth" execute as_server "scoreboard objectives remove <npc.name.substring[1,6]>.MinionDmg"
        }

    # Clear all the flags used during the fight to set boss up for the next fight.
    - flag npc BossHitList:!
    - flag npc BossSpectatorList:!
    - flag npc BossStage:!
    - flag npc BossPlayerList:!
    - flag npc BadLoopProtect:!
    - flag npc ActiveSpecialAttackStage:!
    - flag npc MinionSpawnedStage:!
    - flag npc Scoreboard:!
    - flag npc AllMyMinions:!
    - flag npc BossResetTimer:!
    - flag npc HealActive:!

    # This flag is used to prevent certain "on spawn" commands from running unless the boss actually died. 
    - flag npc BossDied

"BossName Script":
  type: interact

  steps:
    1:
      click trigger:
        script:
        # Right clicking the boss will run the "BossName Health Status" task that'll construct a
        # text based health bar that will show in the Minecraft chat window.
        - run "BossName Health Status"

      proximity trigger:
        entry:
          script:
          # When a player enters the proximity set in the "Boss Awareness Range" constant value, it'll check to see
          # if they are already on the list and if not it will add them to the "BossPlayerList" flag. This is used for
          # targetted narrate messages throughout the fight.
          - if <npc.flag[BossPlayerList].aslist> !contains <player> && <player.name> != <npc.name> flag npc BossPlayerList:->:<player>

          # Add players to the spectator list, which shows up in the battle stats after the boss fight.
          - if <npc.flag[BossSpectatorList].aslist> !contains <player> && <player.name> != <npc.name> flag npc BossSpectatorList:->:<player>

          # If proximity was set as the "BossName Fight Activator" in the constant values at the top, this will
          # start the fight if there isn't already an active fight stage.
          - if "<cons:Bossfight Activator>" == "proximity" && <npc.flag[BossStage]> == null {
            - flag npc BossStage:One
            - run "BossName Fight" }
            else if <npc.flag[BossStage]> != null run "BossName Fight"

          # This resets the timer when a player enters proximity so the boss does NOT get reset after the period
          # of inactivity specified in the "BossName Reset Timer" constant value up top.
          - flag npc BossResetTimer:!

        exit:
          script:
          - if <npc.navigator.target_entity> == <player>
            && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1
            attack <npc> "target:<npc.location.find.players.within[<cons:Boss Awareness Range>].get[1]>"
            else attack stop

          # The wait 10 allows for a buffer where players are on the edge of the proximity moving in an out.
          - wait 10

          # If the fight has been activated (it hasn't got a null boss stage), and there are no players in proximity
          # and self healing has been enabled, run the "BossName Self Heal" task.
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" < 1
            && <npc.flag[BossStage]> != null
            && "<cons:Boss Exit Proximity Self Healing>" == "Yes" {
            - run "BossName Self Heal" id:<npc.name>_BossHeal }

          # Same as above, except this kicks off the overall "BossName Reset" task with a delay timer (set in 
          # "BossName Reset Timer" constant above).
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" < 1 && <npc.flag[BossStage]> != null && "<cons:Boss Reset Timer>" >= 1 && <npc.flag[BossResetTimer]> == null {
            - flag <npc> BossResetTimer
            - run "BossName Reset" id:<npc.name>_ResetTimer "delay:<cons:Boss Reset Timer>" }

      damage trigger:
        script:
        # Every time the boss is hit (whether they are actually damaged or not), it will the commands below.
        #
        # The first IF is so save save the current boss health into a defined value called "phealth".
        - ^if <npc.is_spawned> define phealth <npc.health.as_int>

        # This tick is necessary to allow time for the damage value to be applied to the NPC.
        - wait 1t

        # If the player managed to get through the "entry proximity" without being added to the "BossPlayerList"
        # it will do it now.
        - ^if <npc.flag[BossPlayerList].aslist> !contains <player> && <player.name> != <npc.name> flag <npc> BossPlayerList:->:<player>

        # Start counting the number of times the player has hit the boss. Add "+1" every time they trigger this.
        - ^flag player BossPlayerHitCount:++

        # Add the player into the "BossHitList" if they aren't already.
        - ^if <npc.flag[BossHitList].aslist> !contains <player> && <player.name> != <npc.name> flag <npc> BossHitList:->:<player>

        # The following IF is used to check the boss's current health. If their health is lower than the specified
        # percentage in the "Stage One/Two/Three/Four Boss Health Percentage" constant values, it will activate the
        # next fighting stage.
        # It flags (flag npc BossStage:One etc) the stage it's at because this is used to control the flow of
        # stages and also used during the "Special Attack" loop tasks further down.
        - ^if "<npc.flag[Enabled Boss Stages].aslist>" contains One && <npc.flag[BossStage]> == null && <npc.health.percentage.as_int> <= "<cons:Stage One Boss Health Percentage>" {
            - flag npc BossStage:One
            - run "BossName Fight" }
          else if "<npc.flag[Enabled Boss Stages].aslist>" contains Two && <npc.flag[BossStage]> == One && <npc.health.percentage.as_int> <= "<cons:Stage Two Boss Health Percentage>" {
            - flag npc BossStage:Two
            - run "BossName Fight" }
          else if "<npc.flag[Enabled Boss Stages].aslist>" contains Three && <npc.flag[BossStage]> == Two && <npc.health.percentage.as_int> <= "<cons:Stage Three Boss Health Percentage>" {
            - flag npc BossStage:Three
            - run "BossName Fight" }
          else if "<npc.flag[Enabled Boss Stages].aslist>" contains Four && <npc.flag[BossStage]> == Three && <npc.health.percentage.as_int> <= "<cons:Stage Four Boss Health Percentage>" {
            - flag npc BossStage:Four
            - run "BossName Fight" }

        # The new NPC remaining value is then subtracted off the previous damage value. This is then
        # added into a player flag as the total damage value they inflicted. 
        - ^if <npc.is_spawned> define finaldamage <el@val[<m:%phealth%-<npc.health>>].asint>
          else define finaldamage %phealth%
        - ^flag player BossPlayerTotalDamage:+:%finaldamage%

        # Add the damage amount into the Minecraft scoreboard. (Right hand side of players screen).
        - if <npc.flag[Scoreboard]> == bosshealth && %finaldamage% != 0 execute as_server "scoreboard players add <player.name> <npc.name.substring[1,9]>.Damage %finaldamage%"

"BossName Fight":
  type: task

  script:
  # Every time a stage kicks off, this is the part of the script it runs.
  # Initially it announces the boss health percentage to the "BossPlayerList" (so not everyone on the server
  # gets the message, only the participants. It also runs the "BossName Health Status" script which displays
  # a dynamic text based health bar.
  - ^narrate "<red>Boss Stage <npc.flag[BossStage]> - Health <npc.health.percentage.as_int>%" targets:<npc.flag[BossPlayerList].aslist>
  - ^run "BossName Health Status"

  # Flags the boss with the current stage special attack, used by the special attack tasks to run (or not
  # if it's not relevant for that stage anymore).
  - ^flag npc "CurrentSpecialAttack:<cons:Stage <npc.flag[BossStage]> Boss Special Attack>"

  # Each stage can also have a different effect play around/near the boss, this is checked here and
  # applied with the "execute as_server" command.
  # If there is no effect for this stage, it removes it with the "--play none" parameter below.
  - ^if flame|heart|smoke|ender|potbreak|explosion contains "<cons:Stage <npc.flag[BossStage]> Boss Aura>" {
      - execute as_server "npc sel <npc.id>"
      - execute as_server "npc effect --play none"
      - execute as_server "npc effect --play <cons:Stage <npc.flag[BossStage]> Boss Aura>"
    }
    else {
      - execute as_server "npc sel <npc.id>"
      - execute as_server "npc effect --play none" }

  # The next section is where the minions are spawned, if enabled, for the relevant boss stage.
  # For the "repeat" command, it runs the number of times based on the number of minions you've set
  # to spawn in the "... Minion Qunatity" constant values at the top for each stage.
  #
  # It uses a global flag (TempBossId) to store the boss's NPC ID which is then put into a for each of
  # the minions - so it creates a relationship of sorts between the boss & minions so they can be
  # despawned when the boss dies for example.
  #
  # It checks to see where the minions should spawn based on your set spawn location, 'player', 
  # 'cuboid' or 'boss'. Then it uses a great tag combination "get_spawnable_blocks.random" to pick
  # a random "safe" location for the minion to spawn. This prevents *most* NPC's from spawning inside
  # walls.
  #
  # Then, once its got the location it runs the "BossName Spawn Minion" task instantly. This is explained further
  # down when you get to the task.
  #
  # Once the minion has been created, it'll make it a baby if a) you enabled it  b) if the NPC type
  # supports it. It then applies all the sentry values you've set at each stage in the constants
  # at the top of the script. Lastly, it adds "player" type to it's Sentry target list, picks a random 
  # player from the BossPlayerList and..well.. attacks it.

  - if "<cons:Stage <npc.flag[BossStage]> Spawn Minions>" == "Yes" && <npc.flag[MinionSpawnedStage]> != <npc.flag[BossStage]> {
    - flag <npc> MinionSpawnedStage:<npc.flag[BossStage]>
    - repeat "<cons:Stage <npc.flag[BossStage]> Minion Quantity>" {
      - flag global TempBossId:<npc>
      - if "<cons:Stage <npc.flag[BossStage]> Minion Spawn Location>" == "player" {
        - define selplayer "<npc.flag[BossPlayerList].aslist.random>"  
        - flag <npc> SpawnLocation:<cu@<player[%selplayer%].location.add[-4,0,-4].simple>|<player[%selplayer%].location.add[4,1,4].simple>.get_spawnable_blocks.random>
        - run "BossName Spawn Minion" instantly
        }
        else if "<cons:Stage <npc.flag[BossStage]> Minion Spawn Location>" == cuboid {
          - flag <npc> SpawnLocation:<cu@<npc.flag[cuboid]>.get_spawnable_blocks.random>
          - run "BossName Spawn Minion" instantly
        }
        else if "<cons:Stage <npc.flag[BossStage]> Minion Spawn Location>" == "boss" {  
          - flag <npc> SpawnLocation:<cu@<npc.location.add[-4,0,-4].simple>|<npc.location.add[4,1,4].simple>.get_spawnable_blocks.random>
          - run "BossName Spawn Minion" instantly
        }
      }
    - if <npc.flag[Stage<npc.flag[BossStage]>Minions].size> >= 1 {
      - foreach <npc.flag[Stage<npc.flag[BossStage]>Minions].aslist> {
        - execute as_server "npc sel <%value%.id>"
        - if "<cons:Stage <npc.flag[BossStage]> Minion Weapon>" != none equip %value% "hand:<cons:Stage <npc.flag[BossStage]> Minion Weapon>"
        - if "<cons:Stage <npc.flag[BossStage]> Minion Age>" == baby age %value% baby
        - execute as_server "sentry respawn -1"
        - execute as_server "sentry health <cons:Stage <npc.flag[BossStage]> Minion Health>"
        - execute as_server "sentry strength <cons:Stage <npc.flag[BossStage]> Minion Strength>"
        - execute as_server "sentry armor <cons:Stage <npc.flag[BossStage]> Minion Armor>"
        - execute as_server "sentry target add entity<&co>player"
        - attack %value% target:<npc.flag[BossPlayerList].aslist.random>
        }
      }
    }

  # The server then select the boss ID again and also adds "player" type as it's target.
  - ^execute as_server "npc sel <npc.id>"
  - ^execute as_server "sentry target add entity<&co>player"

  # Each stage can have a different special attack. This is where that process kicks off. First it checks
  # what the attack is for the particular stage the boss is on, then flags the NPC with the
  # "ActiveSpecialAttackStage" which is used by the special attack tasks to run or cancel further down.
  - ^if "Poison Arrow|Wither Arrow|Weakness Arrow|Slowness Arrow" contains "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" {
    - flag <npc> ActiveSpecialAttackStage:Arrows
    - run "BossName Special Attack - Arrows" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "Rain Arrows" {
      - flag <npc> "ActiveSpecialAttackStage:Rain Arrows"
      - run "BossName Special Attack - Rain Arrows" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "Lightning Bolt" {
      - flag <npc> "ActiveSpecialAttackStage:Lightning Bolt"
      - run "BossName Special Attack - Lightning Bolt" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "Lightning Storm" {
      - flag <npc> "ActiveSpecialAttackStage:Lightning Storm"
      - run "BossName Special Attack - Lightning Storm" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "TNT" {
      - flag <npc> "ActiveSpecialAttackStage:TNT"
      - run "BossName Special Attack - TNT" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "TNT Drop" {
      - flag <npc> "ActiveSpecialAttackStage:TNT Drop"
      - run "BossName Special Attack - TNT Drop" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "Throw" {
      - flag <npc> "ActiveSpecialAttackStage:Throw"
      - run "BossName Special Attack - Throw" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == "Firestarter" {
      - flag <npc> "ActiveSpecialAttackStage:Firestarter"
      - run "BossName Special Attack - Firestarter" }
    else if "<cons:Stage <npc.flag[BossStage]> Boss Special Attack>" == none flag <npc> ActiveSpecialAttackStage:!

  # If for some reason Sentry is delayed (known issue which I've logged here: https://github.com/jrbudda/Sentry/issues/161) this will
  # make sure if it's got no target to pick the closest player and attack them.
  - ^if <npc.navigator.target_entity> == null attack <npc> "target:<npc.location.find.players.within[<cons:Boss Awareness Range>].get[1]>"

"BossName Spawn Minion":
    type: task

    script:
    # Here it initially defines the boss stage and then use that to pick:
    # 1) Which effect is used to spawn the minion
    # 2) Give it a name, a type, speed and make it a Sentry.

    - define bosstage <npc.flag[BossStage]>
    - if "<cons:Stage %bosstage% Minion Spawn Effect>" == lightning strike no_damage location:<npc.flag[SpawnLocation]>
      else if "<cons:Stage %bosstage% Minion Spawn Effect>" == explode explode power:1 location:<npc.flag[SpawnLocation]>

    # The most effective way to create an NPC is to fit as MANY of the possible parameters into the "npc create" command
    # as possible. This avoids a scenario where the players can witness the NPC's changing or being teleported to where
    # you intended etc.
    - execute as_server "npc create <cons:Stage %bosstage% Minion Name> --at <npc.flag[SpawnLocation]> --type <cons:Stage %bosstage% Minion Type> --speed <cons:Stage %bosstage% Minion Speed> --trait sentry"

    # This sets the minions owner to be the boss. It's not really used in this scrpt but I do it anyway.
    - execute as_server "npc owner <npc.name>"

    # Assign the "BossName Minion Basics" script below to each minion.
    - execute as_server 'npc assign --set "BossName Minion Basics"'

"BossName Minion Basics":
  type: assignment

  actions:
    on assignment:
    - trigger name:click toggle:true
    - trigger name:damage toggle:true

    # Add this NPC id to a global "AllMinions" list.. this is checked by the boss on spawn
    # to clean up any left behind NPC's if something went wrong or server shutdown midway
    # through a fight.
    - ^flag global AllMinions:->:<npc>

    # Flag the minion with the boss ID. This allows the minion to updates flags on the boss,
    # e.g. the "BossPlayerList" or to add itself to the "AllMyMinions" list which is checked
    # during the "BossName Prevent Self Harm" script.
    - ^flag <npc> MinionCreator:<global.flag[TempBossId]>

    # Minion adds itself into the boss's minion list flags.
    - ^flag <npc[<npc.flag[MinionCreator]>]> Stage<npc[<npc.flag[MinionCreator]>].flag[BossStage]>Minions:->:<npc>
    - ^flag <npc[<npc.flag[MinionCreator]>]> AllMyMinions:->:<npc>

    # If player exits this proximity range the minion will stop attacking. (Temporary until Sentry is fixed)
    - ^flag npc "Minion Awareness Range:<npc[<npc.flag[MinionCreator]>].flag[Minion Awareness Range]>"
    - ^trigger name:proximity toggle:true "radius:<npc.flag[Minion Awareness Range]>"

    on death by player:
    # When the minion is killed by a player (rather than by other mobs or the environment) it
    # will add 1 to player flag keeping a count of minions killed.
    - flag player MinionsKilledCount:++

    # Remove the minion from the "AllMinions" global flag (used to clean up if minions left
    # behind for whatever reason).
    - flag global AllMinions:<-:<npc>

    # Remove the minion from the boss's minion list.
    - flag <npc[<npc.flag[MinionCreator]>]> AllMyMinions:<-:<npc>

    # If the scoreboard is set to record minions killed count, add one to the player score.
    - if <npc[<npc.flag[MinionCreator]>].flag[Scoreboard]> == minionkills execute as_server "scoreboard players add <player.name> <npc[<npc.flag[MinionCreator]>].name.substring[1,5]>.MinionKills 1"

  interact scripts:
  - 5 BossName Minion Damage

"BossName Minion Damage":
  type: interact

  steps:
    1:
      damage trigger:
        script:
        # This damage trigger is very similar to the boss's, so won't explain what happens here.
        - ^if <npc.is_spawned> define phealth <npc.health>
        - ^define mincreator <npc.flag[MinionCreator]>
        - wait 1t
        - ^if <npc[%mincreator%].flag[BossPlayerList].aslist> !contains <player> && <player.name> != <npc[%mincreator%].name> flag <npc[%mincreator%]> BossPlayerList:->:<player>
        - ^if <npc[%mincreator%].flag[BossHitList].aslist> !contains <player> && <player.name> != <npc[%mincreator%].name> flag <npc[%mincreator%]> BossHitList:->:<player>
        - ^if <npc.is_spawned> define finaldamage <el@val[<m:%phealth%-<npc.health>>].asint>
          else define finaldamage <el@val[%phealth%].asint>
        - ^flag player MinionTotalDamage:+:%finaldamage%
        - ^flag player MinionHitCount:++
        - ^if <npc[%mincreator%].flag[Scoreboard]> == minionhealth && %finaldamage% != 0 execute as_server "scoreboard players add <player.name> <npc[%mincreator%].name.substring[1,6]>.MinionDmg %finaldamage%"

      click trigger:
        script:
        - run "BossName Health Status"

      proximity trigger:
        exit:
          script:
          - if <npc.navigator.target_entity> == <player>
            && "<npc.location.find.players.within[<npc.flag[Minion Awareness Range]>].size>" >= 1
            attack <npc> "target:<npc.location.find.players.within[<npc.flag[Minion Awareness Range]>].get[1]>"
            else attack stop

#-------------------------------------------------------------------------------#
# There is a chance the NPC (boss or minions) can hurt themselves, so even
# though it's not the most effective world script, it will at least check to
# see if the "damager" is the boss or a minion and if so, cancel the damage
#
# I'm specifically checking the NPC flags so it doesn't cancel damage on other
# NPC's on the server.
#
#-------------------------------------------------------------------------------#

"BossName Prevent Self Harm":
  type: world
  events:
    on npc damaged:
    - if <context.entity> == <context.damager> && <global.flag[ListOfBosses].aslist> contains <context.entity> determine cancelled
      else if <context.entity> == <context.damager> && <global.flag[AllMinions].aslist> contains <context.entity> determine cancelled
      else if <context.damager> == <npc.flag[MinionCreator]> determine cancelled
      else if <npc.flag[AllMyMinions].aslist> contains <context.damager> determine cancelled

#-------------------------------------------------------------------------------#
# If you typed "Yes" in the  "Boss Exit Proximity Self Healing" constant value,
# a exit proximity trigger will check to see if there are any players left in
# proximity.. if not, it will run this task below which will heal the NPC 1
# health every 5 seconds.
#
# If players enter proximity, this task is cancelled and the boss will stop
# healing.
#
#-------------------------------------------------------------------------------#

"BossName Self Heal":
    type: task

    script:
    - if <npc.health> < <npc.health.max> && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" < 1 && <npc.flag[HealActive]> == null {
      - flag <npc> HealActive
      - heal <npc> 1
      - wait 5
      - flag <npc> HealActive:!
      - run "BossName Self Heal" }

#-------------------------------------------------------------------------------#
# The following script builds up a health bar for the NPC. It does
# this by dividing their current health by 10, the result of that, say 7.2 is
# then rounded down to 7. It then repeats a loop 7 times, each time adding
# 10 "|" characters into a flag. So 7 x ||||||||||.. the remaining 2 (7.2)
# then just gets added onto that, e.g. ||
#
# The reason I did it this way was so that it didn't repeat the loop 70 times to
# build up the number of health bars.
#
# In the example, 72 bars will be <GREEN> and the remaining 28 bars will be
# <RED>.
#
# This can be used with any NPC regardless of how much health they have 
# because it uses their "percentage" of health rather than max value health.
#-------------------------------------------------------------------------------#

"BossName Health Status":
  type: task
  script:
  - ^if <npc.health.percentage> == 100
    narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||<white>]"

    else {
      - ^define GreenTenCount <el@val[<m:floor(<npc.health.percentage>/10)>].asint>
      - ^define GreenTenTotal <el@val[<m:%GreenTenCount%*10>].asint>
      - ^define GreenOneCount <el@val[<m:<npc.health.percentage>-%GreenTenTotal%>].asint>

      - ^define RedTenCount <el@val[<m:floor(<m:100-<npc.health.percentage>>/10)>].asint>
      - ^define RedTenTotal <el@val[<m:%RedTenCount%*10>].asint>
      - ^define RedOneCount <el@val[<m:<m:100-<npc.health.percentage>>-%RedTenTotal%>].asint>

      - ^repeat %GreenTenCount% {
        - flag <npc> "GreenBars:<npc.flag[GreenBars].replace[null]>||||||||||" }

      - ^repeat %GreenOneCount% {
        - flag <npc> "GreenBars:<npc.flag[GreenBars].replace[null]>|" }

      - ^repeat %RedTenCount% {
        - flag <npc> "RedBars:<npc.flag[RedBars].replace[null]>||||||||||" }

      - ^repeat %RedOneCount% {
        - flag <npc> "RedBars:<npc.flag[RedBars].replace[null]>|" }

      - ^if <npc.flag[RedBars]> == null narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green><npc.flag[GreenBars]><white>]"
        else narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green><npc.flag[GreenBars]><red><npc.flag[RedBars].replace[null]><white>]"
      - ^flag npc GreenBars:!
      - ^flag npc RedBars:!
    }

#-------------------------------------------------------------------------------#
# The next script is used to RESET the boss back to start (health back to 100%,
# all spawned minions removed, all player damage/counter flags reset, all boss
# targets, effects and flags cleared and Minecraft scoreboard removed.
#
# This task will only run if the "Boss Reset Timer" constant value is set to
# 1 or higher and when the last player leaves the boss proximity. When a
# player enters proximity, the "BossResetTimer" flag timer is NULL'ed, so when
# the task runs it fails on the first IF and boss is not reset.
#-------------------------------------------------------------------------------#

"BossName Reset":
    type: task

    script:
    - ^if <npc.flag[BossResetTimer]> != null {
      - foreach "<npc.flag[Enabled Boss Stages].aslist>" {
        - foreach <npc.flag[Stage%value%Minions].aslist> {
          - if <npc> != %value% remove <npc[%value%]>
          }
        }

      - foreach "<npc.flag[Enabled Boss Stages].aslist>" {
        - flag <npc> Stage%value%Minions:! }

      - announce "<red>BOSS EVENT<&co> <white><npc.name><red> has been reset."
      - foreach <npc.flag[BossHitList].aslist> {
        - flag player:%value% BossPlayerTotalDamage:!
        - flag player:%value% BossPlayerHitCount:!
        - flag player:%value% MinionsKilledCount:!
        - flag player:%value% MinionHitCount:!
        - flag player:%value% MinionTotalDamage:! }
      - foreach <npc.flag[BossSpectatorList].aslist> {
        - if <npc.flag[BossHitList].aslist> contains %value% flag <npc> BossSpectatorList:<-:%value% }
      - execute as_server "npc sel <npc.id>"
      - execute as_server "npc effect --play none"
      - execute as_server "sentry target clear"
      - if <npc.flag[Scoreboard]> != null {
        - if <npc.flag[Scoreboard]> == bosshealth execute as_server "scoreboard objectives remove <npc.name.substring[1,9]>.Damage"
          else if <npc.flag[Scoreboard]> == minionkills execute as_server "scoreboard objectives remove <npc.name.substring[1,5]>.MinionKills"
          else if <npc.flag[Scoreboard]> == minionhealth execute as_server "scoreboard objectives remove <npc.name.substring[1,6]>.MinionDmg"
        }
      - teleport "<npc>" "location:<cons:Boss Spawn Location>"
      - heal <npc>
      - flag <npc> BossHitList:!
      - flag <npc> BossSpectatorList:!
      - flag <npc> BossStage:!
      - flag <npc> BossPlayerList:!
      - flag <npc> BadLoopProtect:!
      - flag <npc> ActiveSpecialAttackStage:!
      - flag <npc> MinionSpawnedStage:!
      - flag <npc> Scoreboard:!
      - flag <npc> AllMyMinions:!
      - flag <npc> BossResetTimer:!
      - flag <npc> HealActive:!
     }

#-------------------------------------------------------------------------------#
# The following section contains several scripts that are all used by the 
# "special attack" that is enabled in the constant values "Stage One/Two/Three
# /Four Boss Special Attack" at the top of the script.
#
# When the task is executed, it checks the following criteria:
# * PreventDoubleAttack: This flag is to prevent the task from running
#   when it's already active. If the flag wasn't there it would've happened when
#   another player entered the boss's proximity.
#
# * Find players within a radius specified in constant "Boss Awareness Range"
#   from the NPC: This prevents the task from running if no one is there.
#
# * Boss Stage: This is used to check if the boss is in an attack stage, e.g.
#   the fight isn't over.
#
# * Active Special Attack Stage: Checks if the "Arrows" attack is still
#   relevant for the particular boss stage we're in.
#
# If all of those are met, it waits 5 seconds and then runs the task again. If
# the criteria isn't met, it moves onto the "else if" section where it 
# checks whether the ActiveSpecialAttackStage is null (first time a special
# attack script is executed) OR whether it's looping for a second time and 
# "Arrows" is still the relevant special attack. It then does another check to
# see if there are players within a "Boss Awareness Range" block radius.
#
# After that, it flags the NPC with its current active special attack and puts
# the "PreventDoubleAttack" protection flag in place, with an expiry (just in
# time for the next intended delayed attack). It then finds a random player
# within a "Boss Awareness Range" block radius and uses the "shoot" command to
# shoot the arrow towards their location. Each arrow (entity) that gets fired is
# recorded into a global flag called "ArrowList". This list is used later in the
# world script to check who the arrow came from and what "special attack" to
# apply. e.g. poison, blindness etc.
#
# It then waits for the period of time specified in the "Stage One/Two/Three/Four
# Boss Special Attack Delay", does a quick check to see if there are at least
# one player in proximity and also if this attack is still relevant, e.g. the
# boss isn't into the next stage which may be using another special attack.
#-------------------------------------------------------------------------------#

"BossName Special Attack - Arrows":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Arrows" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Arrows" run "BossName Special Attack - Arrows" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Arrows" {
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> ActiveSpecialAttackStage:Arrows
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - define arrowplayer "<npc.location.find.players.within[<cons:Boss Awareness Range>].random>"
          - narrate "<red><npc.name> shoots a <npc.flag[CurrentSpecialAttack]> towards <yellow><%arrowplayer%.name><red>..." targets:<npc.flag[BossPlayerList].aslist>
          - shoot i@arrow origin:<npc> destination:<player[%arrowplayer%].location> Height:0.1 save:shot
          - ^foreach <entry[shot].shot_entities> {
            - flag global ArrowList:->:%value% }
          - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Arrows" run "BossName Special Attack - Arrows" id:Boss<npc.id>SpecialAttack
          }
      }

#-------------------------------------------------------------------------------#
# This script uses a "Cuboid" which are the two values you specified in the
# constant values "Cuboid Spawn Area Poss 1" and "Cuboid Spawn Area Poss 2" at
# the top of the script.
#
# The cuboid should be a square INSIDE your fighting room. If the cuboid is
# larger than your room, you'll have arrows spawning outside of the room.
# 
# If you want to see where your cuboid outline is, type the following command in
# Minecraft, with the NPC selected, and it'll create fake glass blocks that will 
# disappear in 10 seconds:
#
#     /ex showfake glass <<npc.flag[cuboid]>.get_outline> duration:10s
#-------------------------------------------------------------------------------#

"BossName Special Attack - Rain Arrows":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Rain Arrows" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Rain Arrows" run "BossName Special Attack - Rain Arrows" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Rain Arrows" {
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> "ActiveSpecialAttackStage:Rain Arrows"
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - narrate "<red><npc.name> causes it to <npc.flag[CurrentSpecialAttack]>..." targets:<npc.flag[BossPlayerList].aslist>
          - repeat 50 {
            - define roof <cu@<npc.flag[cuboid]>.max.y.add[-1]>
            - define Xrange <util.random.int[<cu@<npc.flag[cuboid]>.min.x.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.x.add[-1].as_int>]>
            - define Zrange <util.random.int[<cu@<npc.flag[cuboid]>.min.z.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.z.add[-1].as_int>]>
            - spawn i@arrow origin:%Xrange%,%roof%,%Zrange%,world
            }
          - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Rain Arrows" run "BossName Special Attack - Rain Arrows" id:Boss<npc.id>SpecialAttack
          }
      }

"BossName Special Attack - Lightning Bolt":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Bolt" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Bolt" run "BossName Special Attack - Lightning Bolt" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Lightning Bolt" {
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> "ActiveSpecialAttackStage:Lightning Bolt"
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - define lightningplayer "<npc.location.find.players.within[<cons:Boss Awareness Range>].random>"
          - narrate "<red><npc.name> calls a <npc.flag[CurrentSpecialAttack]> to hit <yellow><%lightningplayer%.name><red>..." targets:<npc.flag[BossPlayerList].aslist>
          - strike destination:<player[%lightningplayer%].location>
          - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Bolt" run "BossName Special Attack - Lightning Bolt"
          }
      }

"BossName Special Attack - Lightning Storm":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Storm" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Storm" run "BossName Special Attack - Lightning Storm" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Lightning Storm" {
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> "ActiveSpecialAttackStage:Lightning Storm"
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - narrate "<red><npc.name> calls a <npc.flag[CurrentSpecialAttack]> ..." targets:<npc.flag[BossPlayerList].aslist>
          - repeat 10 {
            - define floor <cu@<npc.flag[cuboid]>.min.y>
            - define Xrange <util.random.int[<cu@<npc.flag[cuboid]>.min.x.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.x.add[-1].as_int>]>
            - define Zrange <util.random.int[<cu@<npc.flag[cuboid]>.min.z.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.z.add[-1].as_int>]>
            - strike "destination:%Xrange%,%floor%,%Zrange%,world"
          }
          - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Lightning Storm" run "BossName Special Attack - Lightning Storm"
          }
      }

"BossName Special Attack - TNT":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT" run "BossName Special Attack - TNT" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "TNT" {
        - if  "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> ActiveSpecialAttackStage:TNT
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - define targetplayer "<npc.location.find.players.within[<cons:Boss Awareness Range>].random>"
          - narrate "<red><npc.name> lobs <npc.flag[CurrentSpecialAttack]> at <yellow><%targetplayer%.name><red>..." targets:<npc.flag[BossPlayerList].aslist>
          - playsound location:<player[%targetplayer%].location> sound:fuse
          - shoot e@primed_tnt origin:<npc> destination:<player[%targetplayer%].location.simple> Height:0.5
          - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT" run "BossName Special Attack - TNT" id:Boss<npc.id>SpecialAttack
          }
      }

"BossName Special Attack - TNT Drop":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT Drop" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT Drop" run "BossName Special Attack - TNT Drop" id:Boss<npc.id>SpecialAttack
      }

      else if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "TNT Drop" {
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
          - flag <npc> "ActiveSpecialAttackStage:TNT Drop"
          - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
          - narrate "<red><npc.name> drops primed TNT.. TAKE COVER!" targets:<npc.flag[BossPlayerList].aslist>
          - repeat 5 {
            - define roof <cu@<npc.flag[cuboid]>.max.y.add[-1]>
            - define Xrange <util.random.int[<cu@<npc.flag[cuboid]>.min.x.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.x.add[-1].as_int>]>
            - define Zrange <util.random.int[<cu@<npc.flag[cuboid]>.min.z.add[+1].as_int>].to[<cu@<npc.flag[cuboid]>.max.z.add[-1].as_int>]>
            - spawn e@primed_tnt origin:%Xrange%,%roof%,%Zrange%,world }
        - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT Drop" run "BossName Special Attack - TNT Drop" id:Boss<npc.id>SpecialAttack
        }
      }


# The section below is disabled until https://github.com/aufdemrand/Denizen/issues/408 is fixed.
#
#"BossName Special Attack - Invisible":
#    type: task
#
#    script:
#    - ^if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Invisible" flag npc ActiveSpecialAttackStage:Invisible
#    - ^if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
#      - narrate "<red><npc.name> goes <npc.flag[CurrentSpecialAttack]>..." "targets:<npc.flag[BossPlayerList].aslist>"
#      - execute as_server "npc sel <npc.id>"
#      - execute as_server "npc effect --play none"
#      - invisible npc state:true
#      - flag npc NoBlood
#      - define teleportplayer "<npc.location.find.players.within[<cons:Boss Awareness Range>].random>"
#      - teleport "<npc>" "location:%teleportplayer%"
#      - wait 10
#      - invisible npc state:false
#      - flag npc NoBlood:!
#      - narrate "<red><npc.name> reappears from thin air..." "targets:<npc.flag[BossPlayerList].aslist>"
#      - execute as_server "npc effect --play <cons:Stage <npc.flag[BossStage]> Boss Aura>
#      - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
#      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "TNT" run "BossName Special Attack - TNT" id:Boss<npc.id>SpecialAttack
#      }

"BossName Special Attack - Throw":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Throw" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Throw" run "BossName Special Attack - Throw" id:Boss<npc.id>SpecialAttack }
      else if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Throw" {
      - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
      - if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == "Throw" flag <npc> ActiveSpecialAttackStage:Throw
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
        - flag <npc> "ThrowList:|:<npc.location.find.players.within[<cons:Boss Awareness Range>].random[3]>"
        - narrate "<red><npc.name> throws <npc.flag[Throwlist].formatted>..." targets:<npc.flag[BossPlayerList].aslist>
        - foreach <npc.flag[Throwlist].aslist> {
          - flag <npc> ThrowList:<-:%value%
          - define roof <cu@<npc.flag[cuboid]>.max.y.add[-1]>
          - define Xrange <util.random.int[<cu@<npc.flag[cuboid]>.min.x.as_int>].to[<cu@<npc.flag[cuboid]>.max.x.as_int>]>
          - define Zrange <util.random.int[<cu@<npc.flag[cuboid]>.min.z.as_int>].to[<cu@<npc.flag[cuboid]>.max.z.as_int>]>
          - shoot %value% origin:<player[%value%].location.simple> destination:%Xrange%,%roof%,%Zrange%,world height:1.8 gravity:0.32
          }
        - flag <npc> ThrowList:!
        - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Throw" run "BossName Special Attack - Throw" id:Boss<npc.id>SpecialAttack
        }
      }

"BossName Special Attack - Firestarter":
    type: task

    script:
    - ^if <npc.flag[PreventDoubleAttack]> != null && "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Firestarter" {
      - wait 5s
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == Firestarter run "BossName Special Attack - Firestarter" id:Boss<npc.id>SpecialAttack }

      else if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == Firestarter {
      - flag <npc> PreventDoubleAttack "duration:<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
      - if <npc.flag[ActiveSpecialAttackStage]> == null || <npc.flag[ActiveSpecialAttackStage]> == Firestarter flag <npc> ActiveSpecialAttackStage:Firestarter
      - if "<npc.location.find.players.within[<cons:Boss Awareness Range>]>" != null {
        - narrate "<red><npc.name> sets the place on fire..." targets:<npc.flag[BossPlayerList].aslist>
        - repeat 10 {
          - modifyblock location:<cu@<npc.flag[cuboid]>.get_spawnable_blocks.random> fire
          }
        - wait "<cons:Stage <npc.flag[BossStage]> Boss Special Attack Delay>"
        - if "<npc.location.find.players.within[<cons:Boss Awareness Range>].size>" >= 1 && <npc.flag[BossStage]> != null && <npc.flag[ActiveSpecialAttackStage]> == "Firestarter" run "BossName Special Attack - Firestarter" id:Boss<npc.id>SpecialAttack
        }
      }

#-------------------------------------------------------------------------------#
# This section is primarily to handle the different types of arrows the boss
# can shoot as part of it's special attacks. It determines which spell to "cast"
# based on what the current active special attack is.
#
# It'll also narrate a random message to the boss player list about who got hit
# and what the effect is.
#
# The other purpose here is to show the "blood" effect when you hit the NPC. It
# uses the the "drip_lava" effect but draws 300 of them to make it look like a
# bloody mist. Thanks to blankiito for this effect!
#-------------------------------------------------------------------------------#

"BossName Special Attack Handler":
  type: world
  events:

    on npc damaged by player:
    - if <context.entity> contains <global.flag[ListOfBosses]> && <npc[<context.entity>].flag[NoBlood]> == null {
      - playeffect location:<context.entity.location> effect:DRIP_LAVA radius:10 qty:300 offset:0.15 }

    on player damaged by arrow:
    - ^if <context.projectile> contains <global.flag[ArrowList]> {
      - flag global ArrowList:<-:<context.projectile>
      - if <npc[<context.damager>].flag[CurrentSpecialAttack]> == "Poison Arrow" {
        - cast poison duration:3 power:1 <context.entity>
        - random {
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to bleed from the ears." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing agonising pain and loss of health." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing itchy and burning skin blisters." targets:<npc[<context.damager>].flag[BossPlayerList].aslist> }
        }
        else if <npc[<context.damager>].flag[CurrentSpecialAttack]> == "Wither Arrow" {
        - cast wither duration:3 power:1 <context.entity>
        - random {
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing their skin to peel off." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing their limbs to decay." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing their skin to ooze." targets:<npc[<context.damager>].flag[BossPlayerList].aslist> }
        }
        else if <npc[<context.damager>].flag[CurrentSpecialAttack]> == "Weakness Arrow" {
        - cast weakness duration:3 power:1 <context.entity>
        - random {
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to become weak and tired." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to deal less damage." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to hit like a little girl." targets:<npc[<context.damager>].flag[BossPlayerList].aslist> }
        }
        else if <npc[<context.damager>].flag[CurrentSpecialAttack]> == "Slowness Arrow" {
        - cast slow duration:10 power:3 <context.entity>
        - random {
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to become slow and lazy." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to walk at a snails pace." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than a speeding microorganism." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than a 1 legged dog on tranquilizers." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than a geriatric slug on a salted snowed-in street." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than a snail traveling through peanut butter." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than Java." targets:<npc[<context.damager>].flag[BossPlayerList].aslist>
          - narrate "<red>...and hits <yellow><context.entity.name><red>, causing them to be slower than quadriplegic in a sack race." targets:<npc[<context.damager>].flag[BossPlayerList].aslist> }
        }
      }

#-------------------------------------------------------------------------------#
# Loot can be delivered in 3 different ways. 
# 1) In the player inventory, using the "give" command.
# 2) Drop around where the boss died.
# 3) Inside a chest that spawns in close proximity to where the boss died.
#
# How does it decide the loot? By using a procedure script of course! This
# type of script returns us a single value. Further explained in the next
# section.
#-------------------------------------------------------------------------------#

"BossName Drop the Loot":
    type: task

    script:
    - if "<cons:Loot Distribution>" == "player" {
      - foreach <npc.flag[BossHitList].aslist> {
        - flag <npc> Looter:%value%
        - repeat "<cons:Loot Quantity>" {
          - give to:<player[<npc.flag[looter]>].inventory> "i@<proc:BossName Determine Loot>"
          }
        }
      }

      else if "<cons:Loot Distribution>" == boss {
        - foreach <npc.flag[BossHitList].aslist> {
          - repeat "<cons:Loot Quantity>" {
            - drop "i@<proc:BossName Determine Loot>" location:<npc.flag[DeathLocation]>
          }
        }
      }

      else if "<cons:Loot Distribution>" == chest {
      - define chestlocation <cu@<npc.location.add[-2,0,-2].simple>|<npc.location.add[2,1,2].simple>.get_spawnable_blocks.random>
      - modifyblock location:%chestlocation% chest
      - foreach <npc.flag[BossHitList].aslist> {
        - repeat "<cons:Loot Quantity>" {
          - give "i@<proc:BossName Determine Loot>" to:<in@location[%chestlocation%]> }
        }
      }

      else if "<cons:Loot Distribution>" == playerchest {
      - foreach <npc.flag[BossHitList].aslist> {
        - define chestlocation <cu@<%value%.location.add[-2,0,-2].simple>|<%value%.location.add[2,1,2].simple>.get_spawnable_blocks.random.as_location.block>
        - flag %value% LootChestLocation:%chestlocation%
        - flag <npc> LootChestLocationList:->:%chestlocation%
        - flag global GlobalLootChestLocationList:->:%chestlocation%
        - modifyblock location:%chestlocation% chest
        - repeat "<cons:Loot Quantity>" {
          - give "i@<proc:BossName Determine Loot>" to:<in@location[%chestlocation%]> }
        }
      - flag <npc> PlayersGettingChest:<npc.flag[BossHitList]>        
      }
    - if <npc.flag[LootChestLocationList].size> >= 1 && "<cons:Loot Chest Expiry>" >= 1 run "BossName Loot Chest Expiry" "delay:<cons:Loot Chest Expiry>"

#-------------------------------------------------------------------------------#
# This task will run with a delay specified in the "Loot Chest Expiry" constant
# value at the top of the script.
#
# It simply removes the chests and drop the items on the floor.
#-------------------------------------------------------------------------------#

"BossName Loot Chest Expiry":
    type: task

    script:
    - ^foreach <npc.flag[LootChestLocationList].aslist> {
      - if <location[%value%].block.material> == m@chest {
        - flag global GlobalLootChestLocationList:<-:%value%
        - modifyblock %value% air }
      }
    - ^foreach <npc.flag[PlayersGettingChest].aslist> {
      - flag %value% LootChestLocation:! }
    - ^flag <npc> PlayersGettingChest:!
    - ^flag <npc> LootChestLocationList:!

#-------------------------------------------------------------------------------#
# The next section is a PROCEDURE script used to return a SINGLE value back to
# our main script. In this case, we just want an ITEM SCRIPT name to be returned.
#
# The script "rolls" a value between 0 to a 100 for each player. If
# it rolls between 0 to 40, set the quality to "Common". If its anywhere between
# 40 to 70, set it to "Uncommon" etc etc.
#
# Then, after the quality has been defined, check which section we'll be getting
# the item from. So, if the %quality% is "Common", it'll go into the
# corresponding braces and run the first command "random 8", which will then
# jump to any one of the following 8 lines.
#
# If it then lands on "Durable Diamond Helmet", that's the value the procedure
# script will return to the main boss script and that's the item that will
# dropped/given to the player.
#-------------------------------------------------------------------------------#

"BossName Determine Loot":
    type: procedure

    script:
    - define roll <util.random.int[1].to[100]>
    - if %roll% >= 0 && %roll% < 40 define quality "Common"
      else if %roll% >= 40 && %roll% < 70 define quality "Uncommon"
      else if %roll% >= 70 && %roll% < 85 define quality "Rare"
      else if %roll% >= 85 && %roll% < 95 define quality "Epic"
      else if %roll% >= 95 define quality "Legendary"

    - if %quality% == Common random {
      - determine "Trusty Diamond Axe"
      - determine "Trusty Diamond Sword"
      - determine "Trusty Diamond Hoe"
      - determine "Trusty Diamond Spade"
      - determine "Durable Diamond Helmet"
      - determine "Thorny Diamond Chestplate"
      - determine "Diamond Sword of Looting"
      - determine "Efficient Diamond Pickaxe" }

      else if %quality% == Uncommon random {
        - determine "Herder"
        - determine "MerryGoRound"
        - determine "FoolsGold"
        - determine "Doppelganger"
        - determine "PTD" }

      else if %quality% == Rare random {
        - determine "Aquamarine"
        - determine "Karthlan Warrior Axe"
        - determine "Flamebane"
        - determine "PhaseShifter" }

      else if %quality% == Epic random {
        - determine "Meteorite"
        - determine "Sunflare"
        - determine "Heartburn" }

      else if %quality% == Legendary random {
        - determine "Bow of Decay"
        - determine "Hammer of the Gods"
        - determine "Lifestealer"
        - determine "Bloodsucker"
        - determine "Mobcorn" }

#-------------------------------------------------------------------------------#
# This section of the script defines the items, their lore and Minecraft
# enchantments. To replace/add enchantments check out the following link:
#
#   http://jd.bukkit.org/rb/apidocs/org/bukkit/enchantments/Enchantment.html
# 
# To get one of these items without fighting the boss, as op, simply substitute
# the name of the item and type the following into your Minecraft chat:
#
#   /ex drop "item:Hammer of the Gods" "location:<player.location>"
#
#--------------------------------- Common Items --------------------------------#

"Trusty Diamond Axe":
   type: item
   material: diamond_axe
   display name: "Trusty Diamond Axe"
   lore:
   - A trusty diamond axe.
   - Common Item
   enchantments:
   - durability:1
   - damage_all:1

"Trusty Diamond Sword":
   type: item
   material: diamond_sword
   display name: "Trusty Diamond Sword"
   lore:
   - A trusty diamond sword.
   - Common Item
   enchantments:
   - durability:1
   - damage_all:1

"Trusty Diamond Hoe":
   type: item
   material: diamond_hoe
   display name: "Trusty Diamond Hoe"
   lore:
   - A trusty diamond hoe.
   - Common Item
   enchantments:
   - durability:1

"Trusty Diamond Spade":
   type: item
   material: diamond_spade
   display name: "Trusty Diamond Spade"
   lore:
   - A trusty diamond spade.
   - Common Item
   enchantments:
   - durability:1

"Durable Diamond Helmet":
   type: item
   material: diamond_helmet
   display name: "Durable Diamond Helmet"
   lore:
   - A durable diamond helmet.
   - Common Item
   enchantments:
   - durability:1

"Thorny Diamond Chestplate":
   type: item
   material: diamond_chestplate
   display name: "Thorny Diamond Chestplate"
   lore:
   - A thorny diamond chestplate.
   - Common Item
   enchantments:
   - durability:2
   - thorns:1

"Diamond Sword of Looting":
   type: item
   material: diamond_sword
   display name: "Diamond Sword of Looting"
   lore:
   - Increased loot drops with this diamond
   - sword.
   - Common Item
   enchantments:
   - loot_bonus_mobs:1
   - durability:2

"Efficient Diamond Pickaxe":
   type: item
   material: diamond_pickaxe
   display name: "Efficient Diamond Pickaxe"
   lore:
   - A fast and durable pickaxe.
   enchantments:
   - durability:2
   - dig_speed:5

#-------------------------------- Uncommon Items -------------------------------#

"MerryGoRound":
   type: item
   material: bow
   display name: "MerryGoRound"
   lore:
   - A twisted circus owner forged this to
   - use on his 'less willing' performers.
   - Uncommon Item
   enchantments:
   - durability:3

"PhaseShifter":
   type: item
   material: diamond_sword
   display name: "PhaseShifter"
   lore:
   - Now you see me.. now you don't.
   - Uncommon Item
   enchantments:
   - durability:3

"Herder":
   type: item
   material: diamond_hoe
   display name: "Herder"
   lore:
   - Capture up to 3 friendly mobs inside
   - this magical hoe.
   - Uncommon Item
   enchantments:
   - durability:3

"FoolsGold":
   type: item
   material: gold_nugget
   display name: "Fool's Gold"
   lore:
   - Lure your victims with Fool's Gold
   - and strike them from behind!
   - Uncommon Item

"Doppelganger":
   type: item
   material: feather
   display name: "Doppelganger"
   lore:
   - Doppelganger is a paranormal double
   - of a living enity.
   - Uncommon Item

"PTD":
   type: item
   material: diamond_sword
   display name: "PTD"
   lore:
   - Personal Teleportation Device v0.3
   - Uncommon Item

#--------------------------------- Rare Items --------------------------------#

"Flamebane":
   type: item
   material: diamond_chestplate
   display name: "Flamebane"
   lore:
   - Forged in the fires of Mount Regaros
   - for workers to survive extreme mining
   - conditions.
   - Rare Item
   enchantments:
   - protection_explosions:4
   - protection_fire:4
   - protection_environmental:4

"Aquamarine":
   type: item
   material: diamond_helmet
   display name: "Aquamarine"
   lore:
   - Created by the Great Engineers of Karthlan
   - to allow working and mining underwater.
   - Rare Item
   enchantments:
   - water_worker:1
   - oxygen:3
   - durability:3

"Karthlan Warrior Axe":
   type: item
   material: diamond_axe
   display name: "Karthlan Warrior Axe"
   lore:
   - A super durable 2000 year old axe from the
   - destroyed Karthlan dynasty.
   - Rare Item
   enchantments:
   - knockback:2
   - damage_all:5
   - durability:3

#--------------------------------- Epic Items --------------------------------#

"Meteorite":
   type: item
   material: stick
   display name: "Meteorite"
   lore:
   - Same as dodgeball, but with flaming
   - hot, explosive magma.
   - Epic Item
   enchantments:
   - durability:3

"Sunflare":
   type: item
   material: diamond_sword
   display name: "Sunflare"
   lore:
   - A forgotten elementalist imbued this sword with
   - the power of the sun to set its victims on fire.
   - Epic Item
   enchantments:
   - fire_espect:2
   - damage_all:5
   - durability:3

"Heartburn":
   type: item
   material: bow
   display name: "Heartburn"
   lore:
   - Coated arrow tips set alight even
   - with the slightest wind friction.
   - Epic Item
   enchantments:
   - arrow_fire:2
   - damage_all:5
   - durability:3

#----------------------------- Legendary Items -----------------------------#

"Bow of Decay":
   type: item
   material: bow
   display name: "Bow of Decay"
   lore:
   - A legion of tormented souls imprisoned in this bow fills 
   - each arrow with a millenia of despair and insanity.
   - Legendary Item
   enchantments:
   - durability:3

"Hammer of the Gods":
   type: item
   material: diamond_axe
   display name: "Hammer of the Gods"
   lore:
   - Long lost where even the gods couldn't find it, yet this
   - hammer mysteriously ended up in your hands.
   - Legendary Item
   enchantments:
   - durability:3
   - damage_all:5

"Lifestealer":
   type: item
   material: diamond_sword
   display name: "Lifestealer"
   lore:
   - A sacrifice gone wrong, the sword was removed from 
   - the hands of a baby, dressed in necromancer robes.
   - Legendary Item
   enchantments:
   - durability:3
   - damage_all:5

"Mobcorn":
   type: item
   material: stick
   display name: "Mobcorn"
   lore:
   - What happens when you put a magnetron inside
   - a cow? Only one way to find out.
   - Legendary Item

"Mobcorn Time":
    type: task

    script:
    - narrate "<white><<%1%>.entity_type><red> is going to explode in..." targets:<player.location.find.players.within[10]>
    - if <%1%.is_spawned> { 
      - narrate "<red>3...." targets:<player.location.find.players.within[10]>
      - playsound location:<%1%.location> sound:fuse
      - playeffect location:<%1%.location> effect:fireworks_spark qty:10 }
      else {
        - queue clear 
        - flag player "Mobcorn Cooldown:!" }
    - wait 1
    - if <%1%.is_spawned> { 
      - narrate "<red>2...." targets:<player.location.find.players.within[10]>
      - playeffect location:<%1%.location> effect:fireworks_spark qty:10 }
      else {
        - queue clear 
        - flag player "Mobcorn Cooldown:!" }
    - wait 1 
    - if <%1%.is_spawned> { 
      - narrate "<red>1...." targets:<player.location.find.players.within[10]>
      - playeffect location:<%1%.location> effect:fireworks_spark qty:10 }
      else {
        - queue clear 
        - flag player "Mobcorn Cooldown:!" }
    - wait 1
    - if <%1%.is_spawned> {
      - explode power:2 location:<%1%.location> fire breakblocks
      - if <%1%.is_spawned> remove %1% }
      else {
        - queue clear
        - flag player "Mobcorn Cooldown:!" }


#------------------- Bloodsucker Legendary Item Section -------------------#
# This item requires its own section because it does a little more than
# the other items. Below is a script similar to the minion script above
# but a lot simpler.
#
# The primary points here are:
# 1) Create the bats
# 2) Add bats to player flag and remove them permanently on death
# 3) Remove bats if their owner or their target exits their proximity.
# 4) Remove the bat after 60 seconds regardless of what it's doing.
#
# Further down there are a couple of world events to remove the bats when
# the player dies or quits the server.
#------------------- Bloodsucker Legendary Item Section -------------------#


"Bloodsucker":
   type: item
   material: diamond_sword
   display name: "Bloodsucker"
   lore:
   - Those squeaky noises, glowing red eyes..
   - .... I hope my end is quick.
   - Legendary Item
   enchantments:
   - durability:3

"Spawn Bloodsucker Bat":
    type: task

    script:
    - playeffect location:%1% effect:LARGE_SMOKE
    - execute as_server "npc create Bloodsucker --at %1% --type bat --speed 1.3"
    - execute as_server "npc owner <player.name>"
    - execute as_server 'npc assign --set "Bloodsucker Bat"'

"Bloodsucker Bat":
  type: assignment

  actions:
    on assignment:
    - flag <npc.owner> "BloodsuckerBatList:->:<npc>"
    - trigger name:proximity toggle:true radius:15
    - trigger name:damage toggle:true
    - execute as_server "npc sel <npc.id>"
    - execute as_server "npc lookclose"
    - execute as_server "npc vulnerable"
    - execute as_server "npc health --set 1"
    - flag <npc> Exists
    - run "Bloodsucker Despawn Timer" delay:60s

    on death:
    - flag <npc.owner> "BloodsuckerBatList:<-:<npc>"
    - flag <npc> Exists:!
    - remove <npc>

  interact scripts:
  - 5 Bloodsucker Interaction

"Bloodsucker Interaction":
  type: interact

  steps:
    1:
      damage trigger:
        script:
        - playsound location:<npc.location> sound:bat_idle

      proximity trigger:
        exit:
          script:
          - ^if "<player[<npc.owner>].flag[Bloodsucker Target]>" == <player> || <player.name> == <npc.owner> {
            - flag <npc.owner> "BloodsuckerBatList:<-:<npc>"
            - remove <npc> }

"Bloodsucker Despawn Timer":
    type: task

    script:
    - if <npc.flag[Exists]> remove <npc>

#-------------------------------------------------------------------------------#
# The section below handles the world events to make all the "cool stuff"
# possible. It means that every time one of these events occur in the world, it
# will be evaluated against some criteria to see if the "cool stuff" should
# happen.
#
# For example, every time any entity (<context.entity>) in the world is damaged
# by an arrow, it checks to see if the person (<context.damager>) that fired the
# arrow is holding an item with the following two lore descriptions:
#
#   * A legion of tormented souls imprisoned in this bow fills
#   * A twisted circus owner forged this to
#
# If they are and there are no cooldowns in effect, it'll run the relevant
# (cast or rotate) commands on the entity that got hit.
#-------------------------------------------------------------------------------#

"Legendary and Epic Item Effects":
  type: world
  events:

    on entity damaged by arrow:
    - if "<player[<context.damager>].item_in_Hand.lore.contains[A legion of tormented souls imprisoned in this bow fills]>" == true {
      - cast wither duration:10 power:1 <context.entity>
      - playsound location:<context.entity.location> sound:wither_death volume:2 pitch:0.01
      - if <context.entity.is_player> && "<player[<context.entity>].flag[Hit by Bow of Decay]>" == null {
        - flag <context.entity> "Hit by Bow of Decay" duration:120s
        - narrate "<red>You feel your flesh peeling away...strange voices in your head..so much hate.." targets:<context.entity>
        }
      }

      else if "<player[<context.damager>].item_in_Hand.lore.contains[A twisted circus owner forged this to]>" == true {
      - if <context.entity.is_player> && "<player[<context.entity>].flag[Hit by MerryGoRound]>" == null {
        - flag <context.entity> "Hit by MerryGoRound" duration:5s
        - narrate "<red>The eery twisted music of a deserted, foggy circus makes you turn...round and round..." targets:<context.entity> }
      - rotate <context.entity> duration:5s
      }

    # This handles the effect on an entity getting hit directly by a player. Since it knows
    # who the player is, you can just use <player...> rather than <context.damager>. Which
    # makes it a bit easier to flag the player etc.
    #
    # It compares 3 different weapons, using the "lore" as the method, in this case, to
    # identify which weapon was used.
    on entity damaged by player:
    - if "<player.item_in_Hand.lore.contains[Long lost where even the gods couldn't find it, yet this]>" {
      - if <context.entity.is_player> && "<player.flag[Hit by Hammer of the Gods]>" == null {
        - flag <player> "Hit by Hammer of the Gods" duration:120s
        - narrate "<red>The gods curse you... your end is near..." targets:<context.entity> }
      - strike destination:<context.entity.location> }

      else if "<player.item_in_Hand.lore.contains[A sacrifice gone wrong, the sword was removed from]>" {
        - playsound location:<context.entity.location> sound:enderdragon_growl volume:0.2 pitch:0.01
        - heal <context.damager> 1
        - hurt <context.entity> 1
      }

      else if "<player.item_in_Hand.lore.contains[Those squeaky noises, glowing red eyes..]>" {
        - if "<player.flag[Bloodsucker Cooldown]>" == null && "<player.flag[BloodsuckerBatList].size>" == 0 && <context.entity> !contains <player.flag[BloodsuckerBatList].aslist> {
          - flag <player> "Bloodsucker Cooldown" duration:10s
          - flag <player> "Bloodsucker Target:<context.entity>"
          - foreach <cu@<context.entity.location.add[-2,0,-2].simple>|<context.entity.location.add[2,1,2].simple>.get_spawnable_blocks.random[3]> {
            - run instantly "Spawn Bloodsucker Bat" context:%value% }
          - foreach <player.flag[BloodsuckerBatList].aslist> {
            - attack %value% target:<context.entity> }
          }

          else if <player.flag[BloodsuckerBatList].size> >= 1 && <context.entity> contains <player.flag[BloodsuckerBatList].aslist> {
            - flag <player> "Bloodsucker Target:<context.entity>"
            - foreach <player.flag[BloodsuckerBatList].aslist> {
              - playeffect location:<cu@<context.entity.location.add[-2,0,-2].simple>|<context.entity.location.add[2,2,2].simple>.get_spawnable_blocks.random> effect:large_smoke
              - teleport %value% location:<cu@<context.entity.location.add[-2,-1,-2].simple>|<context.entity.location.add[2,1,2].simple>.get_spawnable_blocks.random> }
            - foreach <player.flag[BloodsuckerBatList].aslist> {
              - attack %value% target:<context.entity> }
          }
      }

      else if "<player.item_in_Hand.lore.contains[Personal Teleportation Device v0.3]>" determine cancelled

    on player right clicks with i@PTD:
    - if "<player.flag[PTD Locations]>" != null {
      - playsound location:<player.location> sound:enderman_teleport
      - playeffect location:<player.location> effect:large_smoke
      - narrate "<red>Teleporting to Saved Location [<yellow><player.flag[PTD Locations].size><red>]<&co><white> <player.flag[PTD Locations].get[<player.flag[PTD Locations].size>]>"
      - teleport <player> "location:<player.flag[PTD Locations].get[<player.flag[PTD Locations].size>]>"
      - flag <player> "PTD Locations[<player.flag[PTD Locations].size>]:<-"
      - playsound location:<player.location> sound:enderman_teleport
      - playeffect location:<player.location> effect:large_smoke }

      else narrate "<red>You have no coordinates loaded in your PTD..."

    on player left clicks block with i@PTD:
    - if "<player.flag[PTD Locations]>" == null {
      - flag <player> "PTD Locations:<player.location.cursor_on.add[0,1,0].simple>"
      - narrate "<red>Saved Location [<yellow><player.flag[PTD Locations].size>/3<red>]<&co><white> <player.flag[PTD Locations].get[<player.flag[PTD Locations].size>]>" }

      else if "<player.flag[PTD locations].size>" = 1 {
        - flag <player> "PTD Locations:->:<player.location.cursor_on.add[0,1,0].simple>"
        - narrate "<red>Saved Location [<yellow><player.flag[PTD Locations].size>/3<red>]<&co><white> <player.flag[PTD Locations].get[<player.flag[PTD Locations].size>]>" }

      else if "<player.flag[PTD locations].size>" = 2 {
        - flag <player> "PTD Locations:->:<player.location.cursor_on.add[0,1,0].simple>"
        - narrate "<red>Saved Location [<yellow><player.flag[PTD Locations].size>/3<red>]<&co><white> <player.flag[PTD Locations].get[<player.flag[PTD Locations].size>]>" }

      else narrate "<red>Your PTD v0.3 is out of memory. You cannot store any more coordinates."

    # Here we specifically only fire this event if the player right clicks, an entity (mobs only), using the item "Herder".
    # It checks the entity type and store the value inside a player flag. It then "removes" the entity but
    # makes it seem like their soul was captured inside the Herder.
    on player right clicks entity with i@Herder:
    - if <player.flag[HerderList].size> >= 3 narrate "<red>The <white>Herder<red> is full and cannot capture any more souls..."
      else if <context.entity.is_mob> {
        - flag <player> HerderList:->:<context.entity.entity_type>
        - playeffect location:<context.entity.location> effect:witch_magic
        - remove <context.entity>
        - if <player.flag[HerderList].size> == 1 narrate "<red>You have trapped the soul of a <player.flag[HerderList].formatted>..."
          else if <player.flag[HerderList].size> >= 2 narrate "<red>You have trapped the souls of <player.flag[HerderList].formatted>.."
      }

    # In this event, it checks to see if there are any entity types in the "HerderList" player flag, if so it
    # spawns the mobs at the cursor location, using the "safe spawn" tag "get_spawnable_blocks".
    on player right clicks block with i@Herder:
    - if <player.flag[HerderList]> != null {
      - narrate "<red>Releasing <player.flag[HerderList].formatted>..."
      - foreach <player.flag[HerderList].aslist> {
        - spawn %value% location:<cu@<player.location.cursor_on.add[-1,0,-1].simple>|<player.location.cursor_on.add[1,2,1].simple>.get_spawnable_blocks.random> }
      - flag <player> "HerderList:!"
      }

    # This section also uses the "get_spawnable_blocks" tag to find an appropriate location to "showfake"
    # a few valuable blocks. They automatically despawn after 120s unless they are destroyed earlier.
    # WARNING: Will allow spawning fake blocks in protected areas.
    on player right clicks block with i@FoolsGold:
    - if "<player.flag[Fools Gold Cooldown]>" == null {
      - flag player "Fools Gold Cooldown" duration:120s
      - showfake diamond_block location:<cu@<player.location.cursor_on.add[-1,0,-1].simple>|<player.location.cursor_on.add[1,2,1].simple>.get_spawnable_blocks.random> duration:120s
      - showfake gold_block location:<cu@<player.location.cursor_on.add[-1,0,-1].simple>|<player.location.cursor_on.add[1,2,1].simple>.get_spawnable_blocks.random> duration:120s
      - showfake chest location:<cu@<player.location.cursor_on.add[-1,0,-1].simple>|<player.location.cursor_on.add[1,2,1].simple>.get_spawnable_blocks.random> duration:120s
      }
      else narrate "<white><player.flag[Fools Gold Cooldown].expiration.formatted><red> before you can use <white>Fool's Gold<red> again."

    # This item script checks to see if the entity clicked is a mob and if the cooldown expired,
    # then runs a script called "Mobcorn Time", which provides a count down timer before
    # the mob explodes!
    # WARNING: Can probably damage and set protected zones on fire!!
    on player right clicks entity with i@Mobcorn:
    - if "<player.flag[Mobcorn Cooldown]>" == null && <context.entity.is_mob> {
      - flag <player> "Mobcorn Cooldown" duration:10s
      - run "Mobcorn Time" def:<context.entity>
      }
       else if "<player.flag[Mobcorn Cooldown]>" != null narrate "<red>Please wait for Mobcorn to cooldown..."


    on player right clicks entity with i@Doppelganger:
    - if <context.entity.equipment.helmet.skin> == <player.name> narrate "<red>Entity is already your Doppelganger."
      else if <context.entity.is_mob> || <context.entity.is_player> {
        - if "<player.flag[Doppelganger Cooldown]>" == null {
          - if "<context.entity.equipment.helmet>" != null && <context.entity.is_player> {
            - give to:<context.entity.inventory> <context.entity.equipment.helmet> }
          - flag <player> "Doppelganger Cooldown" duration:30s
          - head <context.entity> skin:<player> }
      }

      else if "<player.flag[Doppelganger Cooldown]>" != null narrate "<white><player.flag[Doppelganger Cooldown].expiration.formatted><red> before you can use <white>Doppelganger<red> again."

    # Shoot fireballs in the direction of where the cursor is, they have "weight" so it gives
    # a "bullet drop" effect.
    # WARNING: Can probably damage and set protected zones on fire!!
    on player right clicks with i@Meteorite:
    - if "<player.flag[Meteorite Cooldown]>" == null {
      - flag <player> "Meteorite Cooldown" duration:3s
      - shoot e@fireball height:0.05 gravity:0.01 }

    # This script will teleport any player, where no cooldown is in effect, to a "safe" location within
    # a 20 block radius. Above or below ground.
    # WARNING: This will allow players to get into protected buildings!!
    on player right clicks with i@PhaseShifter:
    - if "<player.flag[PhaseShifter Cooldown]>" == null {
      - flag <player> "PhaseShifter Cooldown" duration:3s
      - if "<player.flag[PhaseShifter Narrate Cooldown]>" == null {
        - random {
          - narrate "<white><player.name><red> shimmer and disappears..." targets:<player.location.find.players.within[10]>
          - narrate "<white><player.name><red> teleports to a nearby location..." targets:<player.location.find.players.within[10]>
          - narrate "<white>With a puff of smoke, <white><player.name><red> teleports not too far away.." targets:<player.location.find.players.within[10]> }
        }
      - flag <player> "PhaseShifter Narrate Cooldown" duration:30s
      - playsound location:<player.location> sound:enderman_teleport
      - playeffect location:<player.location> effect:large_smoke
      - teleport <player> location:<cu@<player.location.add[-20,-10,-20].simple>|<player.location.add[20,20,20].simple>.get_spawnable_blocks.random>
      - playsound location:<player.location> sound:enderman_teleport
      - playeffect location:<player.location> effect:large_smoke }

    # This section is relevant if the boss drop uses the "playerchest" method. It controls who can
    # access the contents of the chest. If the player flag "LootChestLocation" does not match
    # the location of the chest it uses "determine cancelled" to prevent the inventory window from
    # showing up.
    on player opens chest:
    - if <global.flag[GlobalLootChestLocationList].aslist> contains <context.inventory.location> {
      - if <player.flag[LootChestLocation]> != <context.inventory.location> {
        - narrate "<red>You cannot access the contents of this chest."
        - determine cancelled }
      }

    # If the chest location is on the player flag and the global "GlobalLootChestLocation" list
    # it will despawn when it's closed.
    on player closes chest:
     - if <player.flag[LootChestLocation]> == <context.inventory.location> && <global.flag[GlobalLootChestLocationList].aslist> contains <context.inventory.location> && <context.inventory.location> != null {
       - narrate "<red>Chest has been despawned..."
       - flag <player> LootChestLocation:!
       - flag global GlobalLootChestLocationList:<-:<context.inventory.location>
       - modifyblock <context.inventory.location> air }

    # The following two events run when a player quits or dies. This is to clean up/remove
    # any bats that were spawned with the Bloodsucker item.
    on player quits:
    - if <player.flag[BloodsuckerBatList].size> >= 1 {
      - foreach <player.flag[BloodsuckerBatList].aslist> {
        - flag <player> BloodsuckerBatList:<-:%value%
        - remove %value% }
      - flag <player> BloodsuckerBatList:!
      }

    on player dies:
    - if <player.flag[BloodsuckerBatList].size> >= 1 {
      - foreach <player.flag[BloodsuckerBatList].aslist> {
        - flag <player> BloodsuckerBatList:<-:%value%
        - remove %value% }
      - flag <player> BloodsuckerBatList:!
      }