diff --git a/base/assets/translations.csv b/base/assets/translations.csv
index b83b9d444b..8a188c4894 100644
--- a/base/assets/translations.csv
+++ b/base/assets/translations.csv
@@ -1,3 +1,3 @@
key,en_us
-advancement.gm4.root.title,"Gamemode 4",
-advancement.gm4.root.description,"Semi-funny blurb about GM4",
+advancement.gm4.root.title,Gamemode 4
+advancement.gm4.root.description,Semi-funny blurb about GM4
diff --git a/gm4/modeldata_registry.json b/gm4/modeldata_registry.json
index 3d0cd6842e..2910528ada 100644
--- a/gm4/modeldata_registry.json
+++ b/gm4/modeldata_registry.json
@@ -50,6 +50,9 @@
"axolotl_bucket": {
"gm4_metallurgy:shamir/infinitas": 100
},
+ "azalea_leaves": {
+ "gm4_monsters_unbound:item/spore/default": 1
+ },
"bamboo_hanging_sign": {
"gm4_trapped_signs:item/secret_trapped_bamboo_hanging_sign": 1,
"gm4_trapped_signs:item/trapped_bamboo_hanging_sign": 2
@@ -170,6 +173,7 @@
"gm4_animi_shamir:shamir/animi": 124
},
"chainmail_chestplate": {
+ "gm4_monsters_unbound:guidebook_icon/monsters_unbound": 1,
"gm4_weighted_armour:shamir/helious": 103,
"gm4_metallurgy:shamir/defuse": 106,
"gm4_iacio_shamir:shamir/iacio": 122,
@@ -189,6 +193,9 @@
"gm4_trapped_signs:item/secret_trapped_cherry_hanging_sign": 1,
"gm4_trapped_signs:item/trapped_cherry_hanging_sign": 2
},
+ "cherry_leaves": {
+ "gm4_monsters_unbound:item/spore/cherry": 1
+ },
"cherry_sign": {
"gm4_trapped_signs:item/trapped_cherry_sign": 1,
"gm4_trapped_signs:item/secret_trapped_cherry_sign": 2
@@ -579,6 +586,9 @@
"gm4_animi_shamir:shamir/animi": 124,
"gm4_orb_of_ankou:guidebook_icon/orb_of_ankou": 200
},
+ "flowering_azalea_leaves": {
+ "gm4_monsters_unbound:item/spore/flowering": 1
+ },
"furnace": {
"gm4_smelteries:gui/advancement/smelteries": 1,
"gm4_forming_press:guidebook_icon/forming_press": 2,
@@ -962,6 +972,7 @@
},
"leather_chestplate": {
"gm4_combat_expanded:gui/advancement/combat_expanded_identify": 1,
+ "gm4_survival_refightalized:guidebook_icon/survival_refightalized": 2,
"gm4_weighted_armour:shamir/helious": 103,
"gm4_metallurgy:shamir/defuse": 106,
"gm4_iacio_shamir:shamir/iacio": 122,
@@ -995,6 +1006,9 @@
"lime_concrete_powder": {
"gm4_zauber_cauldrons:block/liquid_magicol/lime": 300
},
+ "lime_glazed_terracotta": {
+ "gm4_monsters_unbound:item/elite_headwear/mending": 1
+ },
"lingering_potion": {
"gm4_midnight_menaces:guidebook_icon/illusioner_nights": 1,
"gm4_lightning_in_a_bottle:item/lingering_lightning_in_a_bottle": 4,
@@ -1229,10 +1243,16 @@
"oxidized_cut_copper": {
"gm4_tinkering_compressors:block/tinkering_compressor_plate": 1
},
+ "packed_ice": {
+ "gm4_monsters_unbound:item/elite_headwear/glacial": 1
+ },
"paper": {
"gm4_book_binders:item/enchanted_page": 1,
"gm4_book_binders:gui/advancement/book_binders_debind": 2
},
+ "pearlescent_froglight": {
+ "gm4_monsters_unbound:item/elite_headwear/pearlescent": 1
+ },
"phantom_membrane": {
"gm4_midnight_menaces:guidebook_icon/enlarging_phantoms": 1
},
diff --git a/gm4_guidebook/triggers.json b/gm4_guidebook/triggers.json
index b4b7ed6745..61c6886edf 100644
--- a/gm4_guidebook/triggers.json
+++ b/gm4_guidebook/triggers.json
@@ -1,6 +1,6 @@
{
"__important__": "Generated by generate_guidebooks.py. Don't manually update this",
- "__next__": 119,
+ "__next__": 121,
"animi_shamir": 91,
"apple_trees": 83,
"arborenda_shamir": 20,
@@ -66,6 +66,7 @@
"metallurgy": 28,
"mob_curing": 38,
"moneo_shamir": 18,
+ "monsters_unbound": 120,
"mountaineering": 110,
"musical_shamir": 29,
"mysterious_midnights": 42,
@@ -98,6 +99,7 @@
"standard_crafting": 93,
"standard_liquids": 64,
"sunken_treasure": 4,
+ "survival_refightalized": 119,
"sweethearts": 33,
"teleportation_anchors": 114,
"tinker_shamir": 26,
diff --git a/gm4_monsters_unbound/README.md b/gm4_monsters_unbound/README.md
new file mode 100644
index 0000000000..58c390c479
--- /dev/null
+++ b/gm4_monsters_unbound/README.md
@@ -0,0 +1,14 @@
+# Monsters Unbound
+
+Use special weapon and armour modifiers to defend against mobs that grow ever stronger!
+
+
+
+### Features
+- The longer you stay alive the stronger mobs will become.
+- Different biomes grant special buffs to mobs that spawn in them, creating bigger Slimes or Spore Zombies that keep regrowing!
+- Weaker Phantoms that take damage if they try to fly into water, as they deserve.
+- Mobs will drop new Modified armour and weapons. These come with special attributes that allow you to customize your gear!
+- Modifiers range from a ramping speed boost to a loyal immortal dog to fight by your side. Or a piece of armour that teleports you randomly, if that's what you like.
+
+A full list of all modifiers to mobs, weapons and armor can be found at the [Wiki](https://wiki.gm4.co/Monsters_Unbound).
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/glacial.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/glacial.json
new file mode 100644
index 0000000000..2d792a5ee7
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/glacial.json
@@ -0,0 +1,278 @@
+{
+ "textures": {
+ "0": "gm4_monsters_unbound:item/elite_headwear/glacial",
+ "particle": "gm4_monsters_unbound:item/elite_headwear/glacial"
+ },
+ "elements": [
+ {
+ "from": [3, 1, 8],
+ "to": [8, 15, 8],
+ "rotation": {"angle": 45, "axis": "z", "origin": [5.5, 4, 8]},
+ "faces": {
+ "north": {"uv": [0, 0, 5, 14], "texture": "#0"},
+ "south": {"uv": [0, 0, 5, 14], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.5, 1.5, 7],
+ "to": [8.5, 6.5, 21],
+ "rotation": {"angle": -22.5, "axis": "x", "origin": [8.5, 4, 10]},
+ "faces": {
+ "east": {"uv": [0, 0, 5, 14], "rotation": 270, "texture": "#0"},
+ "west": {"uv": [0, 0, 5, 14], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [6, 4, 7],
+ "to": [11, 4, 21],
+ "rotation": {"angle": -22.5, "axis": "x", "origin": [8.5, 4, 10]},
+ "faces": {
+ "up": {"uv": [0, 0, 5, 14], "rotation": 180, "texture": "#0"},
+ "down": {"uv": [0, 0, 5, 14], "texture": "#0"}
+ }
+ },
+ {
+ "from": [9.5, 4, 2.5],
+ "to": [9.5, 18, 7.5],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [9.5, 7, 5]},
+ "faces": {
+ "east": {"uv": [0, 0, 5, 14], "texture": "#0"},
+ "west": {"uv": [0, 0, 5, 14], "texture": "#0"}
+ }
+ },
+ {
+ "from": [7, 4, 5],
+ "to": [12, 18, 5],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [9.5, 7, 5]},
+ "faces": {
+ "north": {"uv": [0, 0, 5, 14], "texture": "#0"},
+ "south": {"uv": [0, 0, 5, 14], "texture": "#0"}
+ }
+ },
+ {
+ "from": [7, 2, -3.675],
+ "to": [12, 2, 10.325],
+ "rotation": {"angle": -22.5, "axis": "y", "origin": [9.5, 2, 7.325]},
+ "faces": {
+ "up": {"uv": [0, 0, 5, 14], "texture": "#0"},
+ "down": {"uv": [0, 0, 5, 14], "rotation": 180, "texture": "#0"}
+ }
+ },
+ {
+ "from": [9.5, -0.5, -3.675],
+ "to": [9.5, 4.5, 10.325],
+ "rotation": {"angle": -22.5, "axis": "y", "origin": [9.5, 2, 7.325]},
+ "faces": {
+ "east": {"uv": [0, 0, 5, 14], "rotation": 90, "texture": "#0"},
+ "west": {"uv": [0, 0, 5, 14], "rotation": 270, "texture": "#0"}
+ }
+ },
+ {
+ "from": [5.5, 1, 5.5],
+ "to": [5.5, 15, 10.5],
+ "rotation": {"angle": 45, "axis": "z", "origin": [5.5, 4, 8]},
+ "faces": {
+ "east": {"uv": [0, 0, 5, 14], "texture": "#0"},
+ "west": {"uv": [0, 0, 5, 14], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.75, 5, -2.75],
+ "to": [11.75, 5, 6.25],
+ "rotation": {"angle": 22.5, "axis": "x", "origin": [10.25, 5, 4.25]},
+ "faces": {
+ "up": {"uv": [5, 0, 8, 9], "texture": "#0"},
+ "down": {"uv": [5, 0, 8, 9], "rotation": 180, "texture": "#0"}
+ }
+ },
+ {
+ "from": [-2.75, 1.5, 7.25],
+ "to": [6.25, 4.5, 7.25],
+ "rotation": {"angle": -22.5, "axis": "y", "origin": [4.25, 3, 7.25]},
+ "faces": {
+ "north": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"},
+ "south": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"}
+ }
+ },
+ {
+ "from": [-2.75, 3, 5.75],
+ "to": [6.25, 3, 8.75],
+ "rotation": {"angle": -22.5, "axis": "y", "origin": [4.25, 3, 7.25]},
+ "faces": {
+ "up": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"},
+ "down": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"}
+ }
+ },
+ {
+ "from": [9.25, 3, 5.75],
+ "to": [18.25, 3, 8.75],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [11.25, 3, 7.25]},
+ "faces": {
+ "up": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"},
+ "down": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [9.25, 0.5, 7.25],
+ "to": [18.25, 3.5, 7.25],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [11.25, 2, 7.25]},
+ "faces": {
+ "north": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"},
+ "south": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [3.75, 2, 10.25],
+ "to": [6.75, 2, 19.25],
+ "rotation": {"angle": -45, "axis": "y", "origin": [5.25, 2, 12.25]},
+ "faces": {
+ "up": {"uv": [5, 0, 8, 9], "rotation": 180, "texture": "#0"},
+ "down": {"uv": [5, 0, 8, 9], "texture": "#0"}
+ }
+ },
+ {
+ "from": [5.25, 0.5, 10.25],
+ "to": [5.25, 3.5, 19.25],
+ "rotation": {"angle": -45, "axis": "y", "origin": [5.25, 2, 12.25]},
+ "faces": {
+ "east": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"},
+ "west": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [10.75, 2, 7.25],
+ "to": [13.75, 2, 16.25],
+ "rotation": {"angle": 45, "axis": "y", "origin": [12.25, 2, 9.25]},
+ "faces": {
+ "up": {"uv": [5, 0, 8, 9], "rotation": 180, "texture": "#0"},
+ "down": {"uv": [5, 0, 8, 9], "texture": "#0"}
+ }
+ },
+ {
+ "from": [12.25, 0.5, 7.25],
+ "to": [12.25, 3.5, 16.25],
+ "rotation": {"angle": 45, "axis": "y", "origin": [12.25, 2, 9.25]},
+ "faces": {
+ "east": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"},
+ "west": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [10.25, 3.5, -2.75],
+ "to": [10.25, 6.5, 6.25],
+ "rotation": {"angle": 22.5, "axis": "x", "origin": [10.25, 5, 4.25]},
+ "faces": {
+ "east": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"},
+ "west": {"uv": [5, 0, 8, 9], "rotation": 270, "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.25, 4, 8.75],
+ "to": [23.25, 4, 11.75],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [12.25, 4, 10.25]},
+ "faces": {
+ "up": {"uv": [9, 0, 12, 15], "rotation": 90, "texture": "#0"},
+ "down": {"uv": [9, 0, 12, 15], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [4.75, 5, 9.25],
+ "to": [7.75, 20, 9.25],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [6.25, 9, 9.25]},
+ "faces": {
+ "north": {"uv": [9, 0, 12, 15], "texture": "#0"},
+ "south": {"uv": [5, 0, 8, 9], "texture": "#0"}
+ }
+ },
+ {
+ "from": [6.25, 5, 7.75],
+ "to": [6.25, 20, 10.75],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [6.25, 9, 9.25]},
+ "faces": {
+ "east": {"uv": [9, 0, 12, 15], "texture": "#0"},
+ "west": {"uv": [9, 0, 12, 15], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.75, 3, 10.25],
+ "to": [11.75, 18, 10.25],
+ "rotation": {"angle": -45, "axis": "z", "origin": [10.25, 7, 10.25]},
+ "faces": {
+ "north": {"uv": [9, 0, 12, 15], "texture": "#0"},
+ "south": {"uv": [5, 0, 8, 9], "texture": "#0"}
+ }
+ },
+ {
+ "from": [10.25, 3, 8.75],
+ "to": [10.25, 18, 11.75],
+ "rotation": {"angle": -45, "axis": "z", "origin": [10.25, 7, 10.25]},
+ "faces": {
+ "east": {"uv": [9, 0, 12, 15], "texture": "#0"},
+ "west": {"uv": [9, 0, 12, 15], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.25, 2.5, 10.25],
+ "to": [23.25, 5.5, 10.25],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [12.25, 4, 10.25]},
+ "faces": {
+ "north": {"uv": [9, 0, 12, 15], "rotation": 270, "texture": "#0"},
+ "south": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.75, 2, 6.25],
+ "to": [11.75, 2, 21.25],
+ "rotation": {"angle": 22.5, "axis": "x", "origin": [10.25, 2, 10.25]},
+ "faces": {
+ "up": {"uv": [9, 0, 12, 15], "rotation": 180, "texture": "#0"},
+ "down": {"uv": [9, 0, 12, 15], "texture": "#0"}
+ }
+ },
+ {
+ "from": [10.25, 0.5, 6.25],
+ "to": [10.25, 3.5, 21.25],
+ "rotation": {"angle": 22.5, "axis": "x", "origin": [10.25, 2, 10.25]},
+ "faces": {
+ "east": {"uv": [9, 0, 12, 15], "rotation": 270, "texture": "#0"},
+ "west": {"uv": [5, 0, 8, 9], "rotation": 90, "texture": "#0"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "rotation": [0, -22.5, 0],
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/mending.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/mending.json
new file mode 100644
index 0000000000..46f78b1029
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/mending.json
@@ -0,0 +1,251 @@
+{
+ "textures": {
+ "0": "gm4_monsters_unbound:item/elite_headwear/mending",
+ "particle": "gm4_monsters_unbound:item/elite_headwear/mending"
+ },
+ "elements": [
+ {
+ "from": [4, 0, 3.5],
+ "to": [12, 8, 3.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 3.5]},
+ "faces": {
+ "north": {"uv": [0, 0, 4, 4], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 4], "texture": "#0"},
+ "south": {"uv": [0, 0, 4, 4], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 4], "texture": "#0"},
+ "up": {"uv": [4, 0, 0, 0], "texture": "#0"},
+ "down": {"uv": [4, 0, 0, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [4, 7, 7],
+ "to": [6, 12, 8],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [4, 8, 7]},
+ "faces": {
+ "north": {"uv": [1, 5.5, 2, 8], "texture": "#0"},
+ "east": {"uv": [1, 5.5, 1.5, 8], "texture": "#0"},
+ "south": {"uv": [1, 5.5, 2, 8], "texture": "#0"},
+ "west": {"uv": [1, 5.5, 1.5, 8], "texture": "#0"},
+ "up": {"uv": [4, 4.5, 3, 4], "texture": "#0"},
+ "down": {"uv": [6, 2.5, 5, 3], "texture": "#0"}
+ }
+ },
+ {
+ "from": [11.60685, 14.31283, 7],
+ "to": [12.60685, 16.31283, 8],
+ "rotation": {"angle": 22.5, "axis": "z", "origin": [11.60685, 14.31283, 7]},
+ "faces": {
+ "north": {"uv": [0.5, 4, 1, 5], "texture": "#0"},
+ "east": {"uv": [0.5, 4, 1, 5], "texture": "#0"},
+ "south": {"uv": [0.5, 4, 1, 5], "texture": "#0"},
+ "west": {"uv": [0.5, 4, 1, 5], "texture": "#0"},
+ "up": {"uv": [3.5, 5, 3, 4.5], "texture": "#0"},
+ "down": {"uv": [4.5, 2.5, 4, 3], "texture": "#0"}
+ }
+ },
+ {
+ "from": [11.53073, 11.69552, 7],
+ "to": [12.53073, 14.69552, 8],
+ "rotation": {"angle": 0, "axis": "y", "origin": [11.53073, 11.69552, 7]},
+ "faces": {
+ "north": {"uv": [0.5, 4.5, 1, 6], "texture": "#0"},
+ "east": {"uv": [0.5, 4.5, 1, 6], "texture": "#0"},
+ "south": {"uv": [0.5, 4.5, 1, 6], "texture": "#0"},
+ "west": {"uv": [0.5, 4.5, 1, 6], "texture": "#0"},
+ "up": {"uv": [3, 5.5, 2.5, 5], "texture": "#0"},
+ "down": {"uv": [5.5, 3, 5, 3.5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [10, 7, 7],
+ "to": [12, 12, 8],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [12, 8, 7]},
+ "faces": {
+ "north": {"uv": [0, 5.5, 1, 8], "texture": "#0"},
+ "east": {"uv": [0.5, 5.5, 1, 8], "texture": "#0"},
+ "south": {"uv": [0, 5.5, 1, 8], "texture": "#0"},
+ "west": {"uv": [0.5, 5.5, 1, 8], "texture": "#0"},
+ "up": {"uv": [3, 4.5, 2, 4], "texture": "#0"},
+ "down": {"uv": [5, 3, 4, 3.5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [3.46927, 11.69552, 7],
+ "to": [4.46927, 14.69552, 8],
+ "rotation": {"angle": 0, "axis": "z", "origin": [4.46927, 11.69552, 7]},
+ "faces": {
+ "north": {"uv": [1, 4.5, 1.5, 6], "texture": "#0"},
+ "east": {"uv": [1, 4.5, 1.5, 6], "texture": "#0"},
+ "south": {"uv": [1, 4.5, 1.5, 6], "texture": "#0"},
+ "west": {"uv": [1, 4.5, 1.5, 6], "texture": "#0"},
+ "up": {"uv": [3.5, 5.5, 3, 5], "texture": "#0"},
+ "down": {"uv": [6, 3, 5.5, 3.5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [3.39315, 14.31283, 7],
+ "to": [4.39315, 16.31283, 8],
+ "rotation": {"angle": -22.5, "axis": "z", "origin": [4.39315, 14.31283, 7]},
+ "faces": {
+ "north": {"uv": [1, 4, 1.5, 5], "texture": "#0"},
+ "east": {"uv": [1, 4, 1.5, 5], "texture": "#0"},
+ "south": {"uv": [1, 4, 1.5, 5], "texture": "#0"},
+ "west": {"uv": [1, 4, 1.5, 5], "texture": "#0"},
+ "up": {"uv": [3, 5, 2.5, 4.5], "texture": "#0"},
+ "down": {"uv": [5, 2.5, 4.5, 3], "texture": "#0"}
+ }
+ },
+ {
+ "from": [6.5, 8, 6.5],
+ "to": [9.5, 13, 7.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [7.5, 8, 6.5]},
+ "faces": {
+ "north": {"uv": [4, 0, 5.5, 2.5], "texture": "#0"},
+ "east": {"uv": [4, 0, 4.5, 2.5], "texture": "#0"},
+ "south": {"uv": [4, 0, 5.5, 2.5], "texture": "#0"},
+ "west": {"uv": [5, 0, 5.5, 2.5], "texture": "#0"},
+ "up": {"uv": [5.5, 0.5, 4, 0], "texture": "#0"},
+ "down": {"uv": [5.5, 2, 4, 2.5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [4, 10.5, 7.25],
+ "to": [5, 14.5, 7.25],
+ "rotation": {"angle": 45, "axis": "z", "origin": [4, 14.5, 7.25]},
+ "faces": {
+ "north": {"uv": [4.5, 3.5, 5, 5.5], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "south": {"uv": [4.5, 3.5, 5, 5.5], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "up": {"uv": [0, 0, 0.5, 0], "texture": "#0"},
+ "down": {"uv": [0, 0, 0.5, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [11, 10.5, 7.25],
+ "to": [12, 14.5, 7.25],
+ "rotation": {"angle": -45, "axis": "z", "origin": [12, 14.5, 7.25]},
+ "faces": {
+ "north": {"uv": [5.5, 3.5, 5, 5.5], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "south": {"uv": [5.5, 3.5, 5, 5.5], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "up": {"uv": [0.5, 0, 0, 0], "texture": "#0"},
+ "down": {"uv": [0.5, 0, 0, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8, 10.5, 7.25],
+ "to": [12, 11.5, 7.25],
+ "rotation": {"angle": 0, "axis": "z", "origin": [12, 10.5, 7.25]},
+ "faces": {
+ "north": {"uv": [3, 5.5, 3.5, 7.5], "rotation": 270, "texture": "#0"},
+ "east": {"uv": [0.5, 0, 1, 0], "rotation": 90, "texture": "#0"},
+ "south": {"uv": [3, 5.5, 3.5, 7.5], "rotation": 90, "texture": "#0"},
+ "west": {"uv": [0.5, 0, 1, 0], "rotation": 90, "texture": "#0"},
+ "up": {"uv": [0, 0, 0, 2], "rotation": 90, "texture": "#0"},
+ "down": {"uv": [0, 0, 0, 2], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [4, 10.5, 7.25],
+ "to": [8, 11.5, 7.25],
+ "rotation": {"angle": 0, "axis": "y", "origin": [4, 10.5, 7.25]},
+ "faces": {
+ "north": {"uv": [2.5, 7.5, 3, 5.5], "rotation": 270, "texture": "#0"},
+ "east": {"uv": [0.5, 0, 1, 0], "rotation": 90, "texture": "#0"},
+ "south": {"uv": [2.5, 7.5, 3, 5.5], "rotation": 90, "texture": "#0"},
+ "west": {"uv": [0.5, 0, 1, 0], "rotation": 90, "texture": "#0"},
+ "up": {"uv": [0, 2, 0, 0], "rotation": 90, "texture": "#0"},
+ "down": {"uv": [0, 2, 0, 0], "rotation": 90, "texture": "#0"}
+ }
+ },
+ {
+ "from": [3.15224, 1, 4.26537],
+ "to": [4.15224, 2, 4.26537],
+ "rotation": {"angle": 22.5, "axis": "y", "origin": [2.15224, 1, 4.26537]},
+ "faces": {
+ "north": {"uv": [3, 2.5, 3.5, 3], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 1], "texture": "#0"},
+ "south": {"uv": [2.5, 2.5, 3, 3], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 1], "texture": "#0"},
+ "up": {"uv": [0, 0, 1, 0], "texture": "#0"},
+ "down": {"uv": [0, 0, 1, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [11.84776, 4, 4.26537],
+ "to": [12.84776, 5, 4.26537],
+ "rotation": {"angle": -22.5, "axis": "y", "origin": [13.84776, 4, 4.26537]},
+ "faces": {
+ "north": {"uv": [3.5, 2.5, 3, 3], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 1], "texture": "#0"},
+ "south": {"uv": [3, 2.5, 2.5, 3], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 1], "texture": "#0"},
+ "up": {"uv": [1, 0, 0, 0], "texture": "#0"},
+ "down": {"uv": [1, 0, 0, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [1.66191, 1, 5.2969],
+ "to": [3.66191, 3, 5.2969],
+ "rotation": {"angle": 45, "axis": "y", "origin": [1.66191, 1, 5.2969]},
+ "faces": {
+ "north": {"uv": [3.5, 5.5, 4.5, 6.5], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "south": {"uv": [4.5, 5.5, 5.5, 6.5], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "up": {"uv": [0, 0, 2, 0], "texture": "#0"},
+ "down": {"uv": [0, 0, 2, 0], "texture": "#0"}
+ }
+ },
+ {
+ "from": [12.33809, 4, 5.2969],
+ "to": [14.33809, 6, 5.2969],
+ "rotation": {"angle": -45, "axis": "y", "origin": [14.33809, 4, 5.2969]},
+ "faces": {
+ "north": {"uv": [4.5, 5.5, 3.5, 6.5], "texture": "#0"},
+ "east": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "south": {"uv": [5.5, 5.5, 4.5, 6.5], "texture": "#0"},
+ "west": {"uv": [0, 0, 0, 2], "texture": "#0"},
+ "up": {"uv": [2, 0, 0, 0], "texture": "#0"},
+ "down": {"uv": [2, 0, 0, 0], "texture": "#0"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/pearlescent.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/pearlescent.json
new file mode 100644
index 0000000000..d837ccdd68
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/elite_headwear/pearlescent.json
@@ -0,0 +1,139 @@
+{
+ "textures": {
+ "0": "gm4_monsters_unbound:item/elite_headwear/pearlescent",
+ "particle": "gm4_monsters_unbound:item/elite_headwear/pearlescent"
+ },
+ "elements": [
+ {
+ "from": [8.5, 2, 3],
+ "to": [11.5, 5, 4],
+ "rotation": {"angle": 0, "axis": "y", "origin": [3.5, -3, -4]},
+ "faces": {
+ "north": {"uv": [2, 2, 5, 5], "texture": "#0"},
+ "east": {"uv": [0, 2, 2, 5], "texture": "#0"},
+ "south": {"uv": [12, 2, 15, 5], "texture": "#0"},
+ "west": {"uv": [5, 2, 7, 5], "texture": "#0"},
+ "up": {"uv": [5, 2, 2, 0], "texture": "#0"},
+ "down": {"uv": [5, 7, 2, 5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [8.25, 1.75, 2.475],
+ "to": [11.75, 5.25, 3.475],
+ "rotation": {"angle": 0, "axis": "y", "origin": [3.5, -3, -4.525]},
+ "faces": {
+ "east": {"uv": [7, 2, 8, 5], "texture": "#0"},
+ "south": {"uv": [11, 2, 8, 5], "texture": "#0"},
+ "west": {"uv": [11, 2, 12, 5], "texture": "#0"},
+ "up": {"uv": [11, 1, 8, 2], "texture": "#0"},
+ "down": {"uv": [11, 5, 8, 6], "texture": "#0"}
+ }
+ },
+ {
+ "from": [11.75, 5.25, 3.475],
+ "to": [8.25, 1.75, 2.475],
+ "rotation": {"angle": 0, "axis": "y", "origin": [7, 0.5, -3.025]},
+ "faces": {
+ "north": {"uv": [11, 5, 8, 2], "texture": "#0"},
+ "east": {"uv": [11, 5, 12, 2], "texture": "#0"},
+ "west": {"uv": [7, 5, 8, 2], "texture": "#0"},
+ "up": {"uv": [8, 5, 11, 6], "texture": "#0"},
+ "down": {"uv": [8, 1, 11, 2], "texture": "#0"}
+ }
+ },
+ {
+ "from": [3.5, 2.5, 3.5],
+ "to": [12.5, 4.5, 12.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [4, 3, 4]},
+ "faces": {
+ "north": {"uv": [0, 7, 8, 9], "texture": "#0"},
+ "east": {"uv": [8, 9, 0, 11], "texture": "#0"},
+ "south": {"uv": [0, 11, 8, 13], "texture": "#0"},
+ "west": {"uv": [0, 9, 8, 11], "texture": "#0"}
+ }
+ },
+ {
+ "from": [12.5, 4.5, 12.5],
+ "to": [3.5, 2.5, 3.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [12, 4, 12]},
+ "faces": {
+ "north": {"uv": [8, 13, 0, 11], "texture": "#0"},
+ "east": {"uv": [8, 11, 0, 9], "texture": "#0"},
+ "south": {"uv": [8, 9, 0, 7], "texture": "#0"},
+ "west": {"uv": [8, 11, 0, 9], "texture": "#0"}
+ }
+ },
+ {
+ "from": [4.5, 2, 3],
+ "to": [7.5, 5, 4],
+ "rotation": {"angle": 0, "axis": "y", "origin": [12.5, -3, -4]},
+ "faces": {
+ "north": {"uv": [5, 2, 2, 5], "texture": "#0"},
+ "east": {"uv": [7, 2, 5, 5], "texture": "#0"},
+ "south": {"uv": [15, 2, 12, 5], "texture": "#0"},
+ "west": {"uv": [2, 2, 0, 5], "texture": "#0"},
+ "up": {"uv": [2, 2, 5, 0], "texture": "#0"},
+ "down": {"uv": [2, 7, 5, 5], "texture": "#0"}
+ }
+ },
+ {
+ "from": [7.75, 5.25, 3.475],
+ "to": [4.25, 1.75, 2.475],
+ "rotation": {"angle": 0, "axis": "y", "origin": [9, 0.5, -3.025]},
+ "faces": {
+ "north": {"uv": [8, 5, 11, 2], "texture": "#0"},
+ "east": {"uv": [8, 5, 7, 2], "texture": "#0"},
+ "west": {"uv": [12, 5, 11, 2], "texture": "#0"},
+ "up": {"uv": [11, 5, 8, 6], "texture": "#0"},
+ "down": {"uv": [11, 1, 8, 2], "texture": "#0"}
+ }
+ },
+ {
+ "from": [4.25, 1.75, 2.475],
+ "to": [7.75, 5.25, 3.475],
+ "rotation": {"angle": 0, "axis": "y", "origin": [12.5, -3, -4.525]},
+ "faces": {
+ "east": {"uv": [12, 2, 11, 5], "texture": "#0"},
+ "south": {"uv": [8, 2, 11, 5], "texture": "#0"},
+ "west": {"uv": [8, 2, 7, 5], "texture": "#0"},
+ "up": {"uv": [8, 1, 11, 2], "texture": "#0"},
+ "down": {"uv": [8, 5, 11, 6], "texture": "#0"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/cherry.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/cherry.json
new file mode 100644
index 0000000000..9cd3170d59
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/cherry.json
@@ -0,0 +1,90 @@
+{
+ "textures": {
+ "1": "gm4_monsters_unbound:item/spore/cherry"
+ },
+ "elements": [
+ {
+ "from": [3.5, -0.5, 3.5],
+ "to": [12.5, 8.5, 12.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 4, 8, 8], "texture": "#1"},
+ "east": {"uv": [0, 4, 4, 8], "texture": "#1"},
+ "south": {"uv": [12, 4, 16, 8], "texture": "#1"},
+ "west": {"uv": [8, 4, 12, 8], "texture": "#1"},
+ "up": {"uv": [4, 0, 8, 4], "texture": "#1"}
+ }
+ },
+ {
+ "from": [12.5, 8.5, 12.5],
+ "to": [3.5, -0.5, 3.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 8, 16, 4], "texture": "#1"},
+ "east": {"uv": [8, 8, 12, 4], "texture": "#1"},
+ "south": {"uv": [4, 8, 8, 4], "texture": "#1"},
+ "west": {"uv": [0, 8, 4, 4], "texture": "#1"},
+ "down": {"uv": [8, 4, 4, 0], "texture": "#1"}
+ }
+ },
+ {
+ "from": [3, -1, 3],
+ "to": [13, 9, 13],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 12, 8, 16], "texture": "#1"},
+ "east": {"uv": [0, 12, 4, 16], "texture": "#1"},
+ "south": {"uv": [12, 12, 16, 16], "texture": "#1"},
+ "west": {"uv": [8, 12, 12, 16], "texture": "#1"},
+ "up": {"uv": [4, 8, 8, 12], "texture": "#1"}
+ }
+ },
+ {
+ "from": [13, 9, 13],
+ "to": [3, -1, 3],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 16, 16, 12], "texture": "#1"},
+ "east": {"uv": [8, 16, 12, 12], "texture": "#1"},
+ "south": {"uv": [4, 16, 8, 12], "texture": "#1"},
+ "west": {"uv": [0, 16, 4, 12], "texture": "#1"},
+ "down": {"uv": [8, 12, 4, 8], "texture": "#1"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/default.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/default.json
new file mode 100644
index 0000000000..c1b2d877f8
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/default.json
@@ -0,0 +1,90 @@
+{
+ "textures": {
+ "1": "gm4_monsters_unbound:item/spore/default"
+ },
+ "elements": [
+ {
+ "from": [3.5, -0.5, 3.5],
+ "to": [12.5, 8.5, 12.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 4, 8, 8], "texture": "#1"},
+ "east": {"uv": [0, 4, 4, 8], "texture": "#1"},
+ "south": {"uv": [12, 4, 16, 8], "texture": "#1"},
+ "west": {"uv": [8, 4, 12, 8], "texture": "#1"},
+ "up": {"uv": [4, 0, 8, 4], "texture": "#1"}
+ }
+ },
+ {
+ "from": [12.5, 8.5, 12.5],
+ "to": [3.5, -0.5, 3.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 8, 16, 4], "texture": "#1"},
+ "east": {"uv": [8, 8, 12, 4], "texture": "#1"},
+ "south": {"uv": [4, 8, 8, 4], "texture": "#1"},
+ "west": {"uv": [0, 8, 4, 4], "texture": "#1"},
+ "down": {"uv": [8, 4, 4, 0], "texture": "#1"}
+ }
+ },
+ {
+ "from": [3, -1, 3],
+ "to": [13, 9, 13],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 12, 8, 16], "texture": "#1"},
+ "east": {"uv": [0, 12, 4, 16], "texture": "#1"},
+ "south": {"uv": [12, 12, 16, 16], "texture": "#1"},
+ "west": {"uv": [8, 12, 12, 16], "texture": "#1"},
+ "up": {"uv": [4, 8, 8, 12], "texture": "#1"}
+ }
+ },
+ {
+ "from": [13, 9, 13],
+ "to": [3, -1, 3],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 16, 16, 12], "texture": "#1"},
+ "east": {"uv": [8, 16, 12, 12], "texture": "#1"},
+ "south": {"uv": [4, 16, 8, 12], "texture": "#1"},
+ "west": {"uv": [0, 16, 4, 12], "texture": "#1"},
+ "down": {"uv": [8, 12, 4, 8], "texture": "#1"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/flowering.json b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/flowering.json
new file mode 100644
index 0000000000..575da0e580
--- /dev/null
+++ b/gm4_monsters_unbound/assets/gm4_monsters_unbound/models/item/spore/flowering.json
@@ -0,0 +1,90 @@
+{
+ "textures": {
+ "1": "gm4_monsters_unbound:item/spore/flowering"
+ },
+ "elements": [
+ {
+ "from": [3.5, -0.5, 3.5],
+ "to": [12.5, 8.5, 12.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 4, 8, 8], "texture": "#1"},
+ "east": {"uv": [0, 4, 4, 8], "texture": "#1"},
+ "south": {"uv": [12, 4, 16, 8], "texture": "#1"},
+ "west": {"uv": [8, 4, 12, 8], "texture": "#1"},
+ "up": {"uv": [4, 0, 8, 4], "texture": "#1"}
+ }
+ },
+ {
+ "from": [12.5, 8.5, 12.5],
+ "to": [3.5, -0.5, 3.5],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 8, 16, 4], "texture": "#1"},
+ "east": {"uv": [8, 8, 12, 4], "texture": "#1"},
+ "south": {"uv": [4, 8, 8, 4], "texture": "#1"},
+ "west": {"uv": [0, 8, 4, 4], "texture": "#1"},
+ "down": {"uv": [8, 4, 4, 0], "texture": "#1"}
+ }
+ },
+ {
+ "from": [3, -1, 3],
+ "to": [13, 9, 13],
+ "rotation": {"angle": 0, "axis": "y", "origin": [5, 6, 5]},
+ "faces": {
+ "north": {"uv": [4, 12, 8, 16], "texture": "#1"},
+ "east": {"uv": [0, 12, 4, 16], "texture": "#1"},
+ "south": {"uv": [12, 12, 16, 16], "texture": "#1"},
+ "west": {"uv": [8, 12, 12, 16], "texture": "#1"},
+ "up": {"uv": [4, 8, 8, 12], "texture": "#1"}
+ }
+ },
+ {
+ "from": [13, 9, 13],
+ "to": [3, -1, 3],
+ "rotation": {"angle": 0, "axis": "y", "origin": [13, 14, 13]},
+ "faces": {
+ "north": {"uv": [12, 16, 16, 12], "texture": "#1"},
+ "east": {"uv": [8, 16, 12, 12], "texture": "#1"},
+ "south": {"uv": [4, 16, 8, 12], "texture": "#1"},
+ "west": {"uv": [0, 16, 4, 12], "texture": "#1"},
+ "down": {"uv": [8, 12, 4, 8], "texture": "#1"}
+ }
+ }
+ ],
+ "display": {
+ "thirdperson_righthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "thirdperson_lefthand": {
+ "rotation": [75, 45, 0],
+ "translation": [0, 2.5, 0],
+ "scale": [0.375, 0.375, 0.375]
+ },
+ "firstperson_righthand": {
+ "rotation": [0, 45, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "firstperson_lefthand": {
+ "rotation": [0, 225, 0],
+ "scale": [0.4, 0.4, 0.4]
+ },
+ "ground": {
+ "translation": [0, 3, 0],
+ "scale": [0.25, 0.25, 0.25]
+ },
+ "gui": {
+ "rotation": [30, 225, 0],
+ "scale": [0.625, 0.625, 0.625]
+ },
+ "head": {
+ "translation": [0, 6.45, 0],
+ "scale": [1.61, 1.61, 1.61]
+ },
+ "fixed": {
+ "scale": [0.5, 0.5, 0.5]
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/glacial.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/glacial.png
new file mode 100644
index 0000000000..128bb844a5
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/glacial.png differ
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/mending.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/mending.png
new file mode 100644
index 0000000000..14eb641d30
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/mending.png differ
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/pearlescent.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/pearlescent.png
new file mode 100644
index 0000000000..f2f65039eb
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/elite_headwear/pearlescent.png differ
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/cherry.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/cherry.png
new file mode 100644
index 0000000000..068b0bbdc7
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/cherry.png differ
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/default.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/default.png
new file mode 100644
index 0000000000..1155c9bca2
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/default.png differ
diff --git a/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/flowering.png b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/flowering.png
new file mode 100644
index 0000000000..f754f40b72
Binary files /dev/null and b/gm4_monsters_unbound/assets/gm4_monsters_unbound/textures/item/spore/flowering.png differ
diff --git a/gm4_monsters_unbound/assets/model_data.yaml b/gm4_monsters_unbound/assets/model_data.yaml
new file mode 100644
index 0000000000..c20d40d302
--- /dev/null
+++ b/gm4_monsters_unbound/assets/model_data.yaml
@@ -0,0 +1,13 @@
+model_data:
+ - item: pearlescent_froglight
+ reference: item/elite_headwear/pearlescent
+ - item: lime_glazed_terracotta
+ reference: item/elite_headwear/mending
+ - item: packed_ice
+ reference: item/elite_headwear/glacial
+ - item: azalea_leaves
+ reference: item/spore/default
+ - item: flowering_azalea_leaves
+ reference: item/spore/flowering
+ - item: cherry_leaves
+ reference: item/spore/cherry
diff --git a/gm4_monsters_unbound/beet.yaml b/gm4_monsters_unbound/beet.yaml
new file mode 100644
index 0000000000..20fb7ccde9
--- /dev/null
+++ b/gm4_monsters_unbound/beet.yaml
@@ -0,0 +1,38 @@
+id: gm4_monsters_unbound
+name: Monsters Unbound
+version: 1.0.X
+
+data_pack:
+ load: .
+
+resource_pack:
+ load: .
+
+pipeline:
+ - gm4.plugins.extend.module
+ - gm4.plugins.include.lib_forceload
+ - gm4.plugins.include.lib_lore
+
+meta:
+ gm4:
+ versioning:
+ required:
+ lib_forceload: 1.3.0
+ lib_lore: 1.1.0
+ gm4_survival_refightalized: 1.0.0
+ schedule_loops:
+ - tick
+ - main
+ - slow_clock
+ website:
+ description: Mobs gain special effects based on their biome.
+ video: null
+ wiki: https://wiki.gm4.co/wiki/Monsters_Unbound
+ credits:
+ Creator:
+ - Thanathor
+ Icon Design:
+ - Hozz
+ Textures:
+ - Kyrius
+ - rednls
diff --git a/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill.json b/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill.json
new file mode 100644
index 0000000000..9f6fb2f878
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill.json
@@ -0,0 +1,34 @@
+{
+ "display": {
+ "icon": {
+ "id": "minecraft:iron_axe"
+ },
+ "title": {
+ "translate": "advancement.gm4.monsters_unbound.elite_kill.title",
+ "fallback": "Elite Hunter"
+ },
+ "description": {
+ "translate": "advancement.gm4.monsters_unbound.elite_kill.description",
+ "fallback": "Kill any Elite monster",
+ "color": "gray"
+ },
+ "frame": "task"
+ },
+ "parent": "gm4:survival_refightalized_armor_damage",
+ "criteria": {
+ "kill_elite": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite\"]}"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill_all.json b/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill_all.json
new file mode 100644
index 0000000000..47814434c8
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4/advancement/monsters_unbound_elite_kill_all.json
@@ -0,0 +1,178 @@
+{
+ "display": {
+ "icon": {
+ "id": "minecraft:diamond_axe"
+ },
+ "title": {
+ "translate": "advancement.gm4.monsters_unbound.elite_kill_all.title",
+ "fallback": "Elites Hunted"
+ },
+ "description": {
+ "translate": "advancement.gm4.monsters_unbound.elite_kill_all.description",
+ "fallback": "Kill one of every Elite monster",
+ "color": "gray"
+ },
+ "frame": "challenge"
+ },
+ "parent": "gm4:monsters_unbound_elite_kill",
+ "criteria": {
+ "blazing": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.blazing\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "gargantuan": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.gargantuan\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "glacial": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.glacial\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "mending": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.mending\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "pearlescent": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.pearlescent\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "splitting": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.splitting\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "volatile": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.volatile\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "vorpal": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.vorpal\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "zephyr": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.zephyr\"]}"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blazing"
+ ],
+ [
+ "gargantuan"
+ ],
+ [
+ "glacial"
+ ],
+ [
+ "mending"
+ ],
+ [
+ "pearlescent"
+ ],
+ [
+ "splitting"
+ ],
+ [
+ "volatile"
+ ],
+ [
+ "vorpal"
+ ],
+ [
+ "zephyr"
+ ]
+ ],
+ "rewards": {
+ "experience": 100
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/charging.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/charging.json
new file mode 100644
index 0000000000..cdfb40abcf
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/charging.json
@@ -0,0 +1,17 @@
+{
+ "criteria": {
+ "requirement": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "source_entity": {
+ "nbt": "{Tags:[\"gm4_mu_charging_attack\"]}"
+ }
+ }
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_monsters_unbound:mob/process/attack_effect/charging_attack"
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/slowing.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/slowing.json
new file mode 100644
index 0000000000..774b625a6c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/slowing.json
@@ -0,0 +1,30 @@
+{
+ "criteria": {
+ "requirement": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_frozen\"]}"
+ }
+ }
+ }
+ ],
+ "damage": {
+ "blocked": false,
+ "source_entity": {
+ "nbt": "{Tags:[\"gm4_mu_slowing_attack\"]}"
+ }
+ }
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_monsters_unbound:mob/process/attack_effect/slowing_attack"
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/toxic.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/toxic.json
new file mode 100644
index 0000000000..6af221acf6
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/toxic.json
@@ -0,0 +1,18 @@
+{
+ "criteria": {
+ "requirement": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "blocked": false,
+ "source_entity": {
+ "nbt": "{Tags:[\"gm4_mu_toxic_attack\"]}"
+ }
+ }
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_monsters_unbound:mob/process/attack_effect/toxic_attack"
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/weakness.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/weakness.json
new file mode 100644
index 0000000000..08e7460766
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/damaged/attack_effect/weakness.json
@@ -0,0 +1,19 @@
+{
+ "criteria": {
+ "requirement": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "blocked": false,
+ "source_entity": {
+ "nbt": "{Tags:[\"gm4_mu_weakness_attack\"]}"
+ }
+ }
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_monsters_unbound:mob/process/attack_effect/weakness_attack"
+ }
+}
+
\ No newline at end of file
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/elite/on_hit.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/elite/on_hit.json
new file mode 100644
index 0000000000..e1ffca6508
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/advancement/elite/on_hit.json
@@ -0,0 +1,21 @@
+{
+ "criteria": {
+ "requirement": {
+ "trigger": "minecraft:player_hurt_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.on_hit\"]}"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_monsters_unbound:mob/process/elite/on_hit/run"
+ }
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/check_item.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/check_item.mcfunction
new file mode 100644
index 0000000000..ba34635580
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/check_item.mcfunction
@@ -0,0 +1,14 @@
+# check items on ground for Survival Refightalized items
+# @s = item
+# at unspecified
+# run from tick
+
+# tag item as checked and try to process
+tag @s add gm4_mu_item_checked
+scoreboard players set $item_processed gm4_mu_data 0
+
+# check for spores
+execute if items entity @s contents *[custom_data~{gm4_mu_spore:{}}] run function gm4_monsters_unbound:mob/process/spore/initialise
+
+# check for elite death markers
+execute if items entity @s contents *[custom_data~{gm4_mu_elite_on_death:{}}] at @s run function gm4_monsters_unbound:mob/process/elite/on_death/run
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/fear.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/fear.mcfunction
new file mode 100644
index 0000000000..739518c259
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/fear.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for fear effect
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from effect/fear/apply
+
+scoreboard players set $keep_tick.feared_entity gm4_mu_keep_tick 0
+execute as @a[tag=gm4_mu_feared] at @s run function gm4_monsters_unbound:effect/fear/tick
+
+execute if score $keep_tick.feared_entity gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/effect/fear 5t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/freeze.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/freeze.mcfunction
new file mode 100644
index 0000000000..ff17e282b9
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/effect/freeze.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for freeze effect
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from effect/freeze/apply
+
+scoreboard players set $keep_tick.frozen_entity gm4_mu_keep_tick 0
+execute as @e[tag=gm4_mu_frozen] at @s run function gm4_monsters_unbound:effect/freeze/tick
+
+execute if score $keep_tick.frozen_entity gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/effect/freeze 5t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/blazing_flare.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/blazing_flare.mcfunction
new file mode 100644
index 0000000000..13e62a8cee
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/blazing_flare.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for blazing elite flare
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from mob/process/elite/blazing/init_flare
+
+scoreboard players set $keep_tick.elite_process_flare gm4_mu_keep_tick 0
+execute as @e[type=block_display,tag=gm4_mu_elite_flare] at @s run function gm4_monsters_unbound:mob/process/elite/blazing/process_flare
+
+execute if score $keep_tick.elite_process_flare gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/blazing_flare 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/glacial_death.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/glacial_death.mcfunction
new file mode 100644
index 0000000000..da8019f60a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/glacial_death.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for glacial elite death
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from mob/process/elite/glacial/death
+
+scoreboard players set $keep_tick.elite_glacial_death gm4_mu_keep_tick 0
+execute as @e[type=marker,tag=gm4_mu_elite.glacial_processing] at @s run function gm4_monsters_unbound:mob/process/elite/glacial/process_explosion
+
+execute if score $keep_tick.elite_glacial_death gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/glacial_death 2t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/volatile_pillar.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/volatile_pillar.mcfunction
new file mode 100644
index 0000000000..85ea19c7da
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/volatile_pillar.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for volatile elite pillars
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from mob/process/elite/volatile/pillar_location
+
+scoreboard players set $keep_tick.elite_pillar_volatile gm4_mu_keep_tick 0
+execute as @e[type=marker,tag=gm4_mu_elite.volatile_pillar] at @s run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_process
+
+execute if score $keep_tick.elite_pillar_volatile gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/volatile_pillar 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/vorpal_death.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/vorpal_death.mcfunction
new file mode 100644
index 0000000000..10153daf94
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/vorpal_death.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for vorpal elite death skull
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from mob/process/elite/vorpal/init_fear_cloud
+
+scoreboard players set $keep_tick.elite_death_vorpal gm4_mu_keep_tick 0
+execute as @e[type=item_display,tag=gm4_mu_elite.fear_cloud] at @s run function gm4_monsters_unbound:mob/process/elite/vorpal/process_fear_cloud
+
+execute if score $keep_tick.elite_death_vorpal gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/vorpal_death 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/zephyr_process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/zephyr_process.mcfunction
new file mode 100644
index 0000000000..7f5dd785bc
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/clocks/elite/zephyr_process.mcfunction
@@ -0,0 +1,10 @@
+# temporary clock for skeleton zephyr elite charging
+# @s = unspecified
+# at unspecified
+# schedule from here
+# schedule from mob/process/elite/zephyr/skeleton/start
+
+scoreboard players set $keep_tick.elite_process_zephyr gm4_mu_keep_tick 0
+execute as @e[type=#gm4_survival_refightalized:skeleton_types,tag=gm4_mu_elite.zephyr_skeleton_burst] at @s run function gm4_monsters_unbound:mob/process/elite/zephyr/skeleton/arrow_burst
+
+execute if score $keep_tick.elite_process_zephyr gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/zephyr_process 3t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/skeleton.mcfunction
new file mode 100644
index 0000000000..10d06d2cb7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 46
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/zombie.mcfunction
new file mode 100644
index 0000000000..aef515b4cc
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/blazing/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 46
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/skeleton.mcfunction
new file mode 100644
index 0000000000..c05abbd66c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 96
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/zombie.mcfunction
new file mode 100644
index 0000000000..38fb726a96
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/gargantuan/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 96
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/skeleton.mcfunction
new file mode 100644
index 0000000000..0ee9e2dbfc
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 1
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/zombie.mcfunction
new file mode 100644
index 0000000000..82ff3e7eef
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/glacial/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 1
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/skeleton.mcfunction
new file mode 100644
index 0000000000..fe90e407c5
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 16
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/zombie.mcfunction
new file mode 100644
index 0000000000..a2cbac1ceb
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/mending/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 16
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/skeleton.mcfunction
new file mode 100644
index 0000000000..02a172b96e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 86
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/zombie.mcfunction
new file mode 100644
index 0000000000..5493328c87
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/pearlescent/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 86
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/skeleton.mcfunction
new file mode 100644
index 0000000000..8b18bd3b39
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 66
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/zombie.mcfunction
new file mode 100644
index 0000000000..02d3bde46c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/splitting/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 66
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/skeleton.mcfunction
new file mode 100644
index 0000000000..3a647c4758
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 76
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/zombie.mcfunction
new file mode 100644
index 0000000000..23aa9cdd8c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/volatile/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 76
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/skeleton.mcfunction
new file mode 100644
index 0000000000..b3cfb44401
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 56
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/zombie.mcfunction
new file mode 100644
index 0000000000..608f70da6d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/vorpal/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 56
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/skeleton.mcfunction
new file mode 100644
index 0000000000..25a76b60ad
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/skeleton.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 31
+summon skeleton ~ ~ ~ {Tags:["gm4_mu_elite","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/zombie.mcfunction
new file mode 100644
index 0000000000..70dd38c0e4
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/debug/spawn_elite/zephyr/zombie.mcfunction
@@ -0,0 +1,4 @@
+
+scoreboard players set $prepicked_elite gm4_mu_data 31
+summon zombie ~ ~ ~ {Tags:["gm4_sr_was_baby","gm4_mu_debug_mob"]}
+execute as @n[tag=gm4_mu_debug_mob] run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/apply.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/apply.mcfunction
new file mode 100644
index 0000000000..fb77d62c56
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/apply.mcfunction
@@ -0,0 +1,32 @@
+# apply fear to this player
+# @s = player to hit with fear
+# at @s
+# run from mob/process/elite/vorpal/fear_hit
+
+# failsafe - don't fear spectators
+execute if entity @s[gamemode=spectator] run return 0
+
+# particles and sound
+particle dust{color:[0.000,0.000,0.000],scale:1} ~ ~ ~ 0.0666 0.0666 0.0666 2 6 normal
+playsound minecraft:entity.witch.celebrate hostile @s ~ ~ ~ 1 2
+playsound minecraft:entity.witch.death hostile @s ~ ~ ~ 1 0.666
+
+# set timer
+scoreboard players operation $add_fear_time gm4_mu_data = $fear_seconds gm4_mu_data
+scoreboard players operation $add_fear_time gm4_mu_data *= #4 gm4_mu_data
+
+# effects
+effect give @s blindness 3 0 true
+effect give @s darkness 3 0 true
+effect give @s nausea 3 0 true
+effect give @s wither 1 0 true
+
+# apply attributes
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:feared -0.5 add_multiplied_total
+attribute @s minecraft:attack_speed modifier add gm4_monsters_unbound:feared -0.5 add_multiplied_total
+attribute @s minecraft:block_break_speed modifier add gm4_monsters_unbound:feared -0.5 add_multiplied_total
+
+# apply fear
+scoreboard players operation @s gm4_mu_feared_time += $add_fear_time gm4_mu_data
+tag @s add gm4_mu_feared
+execute unless score $keep_tick.feared_entity gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/effect/fear 5t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/playsound.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/playsound.mcfunction
new file mode 100644
index 0000000000..f095b84792
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/playsound.mcfunction
@@ -0,0 +1,16 @@
+# play fear sounds
+# @s = player with fear effect
+# at @s
+# run from effect/fear/tick
+
+execute store result score $picksound gm4_mu_data run random value 1..11
+
+execute if score $picksound gm4_mu_data matches 1..2 run playsound entity.creeper.primed hostile @s ^1 ^ ^-1 1 1
+execute if score $picksound gm4_mu_data matches 3..4 run playsound entity.creeper.primed hostile @s ^-1 ^ ^-1 1 1
+execute if score $picksound gm4_mu_data matches 5 run playsound entity.zombie.ambient hostile @s ^2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 6 run playsound entity.zombie.ambient hostile @s ^-2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 7 run playsound entity.skeleton.ambient hostile @s ^2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 8 run playsound entity.skeleton.ambient hostile @s ^-2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 9 run playsound entity.spider.ambient hostile @s ^2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 10 run playsound entity.spider.ambient hostile @s ^-2 ^ ^-3 1 1
+execute if score $picksound gm4_mu_data matches 11 run playsound entity.witch.ambient hostile @s ^2 ^ ^-3 1 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/remove.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/remove.mcfunction
new file mode 100644
index 0000000000..1050f55aea
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/remove.mcfunction
@@ -0,0 +1,10 @@
+# remove fear from this player
+# @s = player with fear effect
+# at @s
+# run from effect/fear/tick
+
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:feared
+attribute @s minecraft:attack_speed modifier remove gm4_monsters_unbound:feared
+attribute @s minecraft:block_break_speed modifier remove gm4_monsters_unbound:feared
+
+tag @s remove gm4_mu_feared
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/tick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/tick.mcfunction
new file mode 100644
index 0000000000..8e81f7a85b
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/fear/tick.mcfunction
@@ -0,0 +1,26 @@
+# tick fear effect for this player
+# @s = player with fear effect
+# at @s
+# run from clocks/effect/fear
+
+# tick down effect, remove if it reaches 0
+scoreboard players remove @s gm4_mu_feared_time 1
+execute if score @s gm4_mu_feared_time matches ..0 run return run function gm4_monsters_unbound:effect/fear/remove
+
+# re-apply effects
+effect give @s[scores={gm4_mu_feared_time=9..}] blindness 3 0 true
+effect give @s[scores={gm4_mu_feared_time=9..}] darkness 3 0 true
+effect give @s[scores={gm4_mu_feared_time=9..}] nausea 3 0 true
+effect give @s wither 1 0 true
+
+# sounds
+scoreboard players operation $playsound gm4_mu_data = @s gm4_mu_feared_time
+scoreboard players operation $playsound gm4_mu_data %= #4 gm4_mu_data
+execute if score $playsound gm4_mu_data matches 0 if predicate {condition:"random_chance",chance:0.666} run function gm4_monsters_unbound:effect/fear/playsound
+
+# particles
+execute anchored eyes run particle dust{color:[0.000,0.000,0.000],scale:4} ^ ^ ^0.15 0.2 0.2 0.2 2 6 force @s
+execute anchored eyes run particle dust{color:[0.000,0.000,0.000],scale:4} ^ ^ ^0.75 0.4 0.4 0.4 2 18 force @s
+
+# keep clock running
+scoreboard players set $keep_tick.feared_entity gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply.mcfunction
new file mode 100644
index 0000000000..6094c5d129
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply.mcfunction
@@ -0,0 +1,25 @@
+# apply freeze to this entity
+# @s = entity to freeze
+# at @s
+# run from effect/freeze/apply_from_slow
+# run from mob/process/elite/glacial/explode
+
+# don't freeze spectators
+execute if entity @s[gamemode=spectator] run return 0
+
+# take tiny fraction of damage for show
+damage @s 0.01 freeze
+
+# set timer
+scoreboard players operation $add_freeze_time gm4_mu_data = $freeze_seconds gm4_mu_data
+scoreboard players operation $add_freeze_time gm4_mu_data *= #4 gm4_mu_data
+scoreboard players reset $freeze_seconds gm4_mu_data
+
+# set attributes based on entity type
+execute if entity @s[type=player] run function gm4_monsters_unbound:effect/freeze/apply_player
+execute if entity @s[type=!player] run function gm4_monsters_unbound:effect/freeze/apply_entity
+
+# apply freeze
+scoreboard players operation @s gm4_mu_frozen_time += $add_freeze_time gm4_mu_data
+tag @s add gm4_mu_frozen
+execute unless score $keep_tick.frozen_entity gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/effect/freeze 5t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_chill.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_chill.mcfunction
new file mode 100644
index 0000000000..74b67150d9
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_chill.mcfunction
@@ -0,0 +1,15 @@
+# apply a stack of chill
+# @s = player that was hit
+# at unspecified
+# run from mob/process/attack_effect/slowing_attack
+
+execute if entity @s[tag=gm4_mu_immune_slowness] run return 0
+
+scoreboard players set $slowness_level gm4_mu_data -1
+execute if data entity @s active_effects[{id:"minecraft:slowness"}] store result score $slowness_level gm4_mu_data run data get entity @s active_effects[{id:"minecraft:slowness"}].amplifier
+execute store result storage gm4_monsters_unbound:temp slowness.level int 1 run scoreboard players add $slowness_level gm4_mu_data 1
+
+execute unless score $slowness_level gm4_mu_data matches 6.. run function gm4_monsters_unbound:effect/freeze/stack_slow with storage gm4_monsters_unbound:temp slowness
+execute if score $slowness_level gm4_mu_data matches 6.. run function gm4_monsters_unbound:effect/freeze/apply_from_slow
+
+data remove storage gm4_monsters_unbound:temp slowness
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_entity.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_entity.mcfunction
new file mode 100644
index 0000000000..ea4e87d330
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_entity.mcfunction
@@ -0,0 +1,11 @@
+# apply freeze to this non-player entity
+# @s = non-player entity to freeze
+# at @s
+# run from effect/freeze/apply
+
+# apply attributes
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:follow_range modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:jump_strength modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:frozen 1 add_value
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_from_slow.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_from_slow.mcfunction
new file mode 100644
index 0000000000..7f09cc1918
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_from_slow.mcfunction
@@ -0,0 +1,8 @@
+# apply freeze from Chill slow
+# @s = entity with 7 stacks of Chill
+# at @s
+# run from effect/freeze/apply_chill
+
+effect clear @s slowness
+execute unless score $freeze_seconds gm4_mu_data matches 1.. run scoreboard players set $freeze_seconds gm4_mu_data 3
+function gm4_monsters_unbound:effect/freeze/apply
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_player.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_player.mcfunction
new file mode 100644
index 0000000000..f3f6d8dde1
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/apply_player.mcfunction
@@ -0,0 +1,12 @@
+# apply freeze to this player
+# @s = player to freeze
+# at @s
+# run from effect/freeze/apply
+
+# apply attributes
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:attack_speed modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:jump_strength modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:frozen 1 add_multiplied_total
+attribute @s minecraft:entity_interaction_range modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
+attribute @s minecraft:block_interaction_range modifier add gm4_monsters_unbound:frozen -1 add_multiplied_total
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/stack_slow.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/stack_slow.mcfunction
new file mode 100644
index 0000000000..fb26b0f40f
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/stack_slow.mcfunction
@@ -0,0 +1,6 @@
+# stack slowness level on multiple Chill hits
+# @s = entity with slowness effect
+# at @s
+# run from effect/freeze/apply_chill
+
+$effect give @s slowness 15 $(level)
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_entity.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_entity.mcfunction
new file mode 100644
index 0000000000..168421fdb7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_entity.mcfunction
@@ -0,0 +1,14 @@
+# thaw entity
+# @s = entity with freeze effect
+# at @s
+# run from effect/freeze/tick
+
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:follow_range modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:jump_strength modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:knockback_resistance modifier remove gm4_monsters_unbound:frozen
+
+playsound minecraft:block.snow.break player @a ~ ~ ~ 1.5 1.25
+
+tag @s remove gm4_mu_frozen
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_player.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_player.mcfunction
new file mode 100644
index 0000000000..187ebb4d8d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/thaw_player.mcfunction
@@ -0,0 +1,15 @@
+# thaw player
+# @s = player with freeze effect
+# at @s
+# run from effect/freeze/tick
+
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:attack_speed modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:jump_strength modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:knockback_resistance modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:entity_interaction_range modifier remove gm4_monsters_unbound:frozen
+attribute @s minecraft:block_interaction_range modifier remove gm4_monsters_unbound:frozen
+
+playsound minecraft:block.snow.break player @a ~ ~ ~ 1.5 1.25
+
+tag @s remove gm4_mu_frozen
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/tick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/tick.mcfunction
new file mode 100644
index 0000000000..0dc72e83f2
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/effect/freeze/tick.mcfunction
@@ -0,0 +1,13 @@
+# tick freeze effect for this entity
+# @s = entity with freeze effect
+# at @s
+# run from clocks/effect/freeze
+
+scoreboard players remove @s gm4_mu_frozen_time 1
+execute if score @s[type=player] gm4_mu_frozen_time matches ..0 run return run function gm4_monsters_unbound:effect/freeze/thaw_player
+execute if score @s[type=!player] gm4_mu_frozen_time matches ..0 run return run function gm4_monsters_unbound:effect/freeze/thaw_entity
+
+particle dust{color:[0.725,0.910,0.918],scale:2} ~ ~0.9 ~ 0.3 0.65 0.3 0 1 normal
+particle snowflake ~ ~0.9 ~ 0.3 0.65 0.3 0 6 normal
+
+scoreboard players set $keep_tick.frozen_entity gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/init.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/init.mcfunction
new file mode 100644
index 0000000000..7cb1b35d4e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/init.mcfunction
@@ -0,0 +1,57 @@
+execute unless score monsters_unbound gm4_modules matches 1 run data modify storage gm4:log queue append value {type:"install",module:"Monsters Unbound"}
+execute unless score monsters_unbound gm4_earliest_version < monsters_unbound gm4_modules run scoreboard players operation monsters_unbound gm4_earliest_version = monsters_unbound gm4_modules
+scoreboard players set monsters_unbound gm4_modules 1
+
+# scoreboards
+scoreboard objectives add gm4_mu_data dummy
+scoreboard objectives add gm4_mu_timer dummy
+scoreboard objectives add gm4_mu_generation dummy
+scoreboard objectives add gm4_mu_frozen_time dummy
+scoreboard objectives add gm4_mu_feared_time dummy
+scoreboard objectives add gm4_mu_keep_tick dummy
+
+# configs
+execute unless score $spawn_phantoms gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $spawn_phantoms gm4_sr_config 1
+
+# disable natural phantom spawning
+execute unless score $phantoms_disabled gm4_mu_data matches 1 run gamerule doInsomnia false
+execute unless score $phantoms_disabled gm4_mu_data matches 1 run data modify storage gm4:log queue append value {type:"text",message:{"text":"[INFO] Monsters Unbound changed gamerule doInsomnia to false"}}
+scoreboard players set $phantoms_disabled gm4_mu_data 1
+execute store result score $doinsomnia gm4_mu_data run gamerule doInsomnia
+execute if score $spawn_phantoms gm4_sr_config matches 1 if score $doinsomnia gm4_mu_data matches 1 run data modify storage gm4:log queue append value {type:"text",message:[{"text":"[WARN]","color":"red"},{"text":" Monsters Unbound requires doInsomnia to be false, but it is true. ","color":"white"},{"text":"click here to fix","color":"red","clickEvent":{"action":"suggest_command","value":"/gamerule doInsomnia false"}}]}
+
+# mob caps
+execute unless score $mob_limit.husk_army gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $mob_limit.husk_army gm4_sr_config 128
+execute unless score $mob_limit.spore_zombie gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $mob_limit.spore_zombie gm4_sr_config 128
+execute unless score $mob_limit.phantom gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $mob_limit.phantom gm4_sr_config 48
+
+# elite teams
+team add gm4_mu_elite.glacial
+team modify gm4_mu_elite.glacial prefix {"translate":"text.gm4.monsters_unbound.elite_name.glacial","fallback":"Glacial "}
+team add gm4_mu_elite.mending
+team modify gm4_mu_elite.mending prefix {"translate":"text.gm4.monsters_unbound.elite_name.slate","fallback":"Slate "}
+team add gm4_mu_elite.blazing
+team modify gm4_mu_elite.blazing prefix {"translate":"text.gm4.monsters_unbound.elite_name.blazing","fallback":"Blazing "}
+team add gm4_mu_elite.zephyr
+team modify gm4_mu_elite.zephyr prefix {"translate":"text.gm4.monsters_unbound.elite_name.zephyr","fallback":"Zephyr "}
+team add gm4_mu_elite.gargantuan
+team modify gm4_mu_elite.gargantuan prefix {"translate":"text.gm4.monsters_unbound.elite_name.gargantuan","fallback":"Gargantuan "}
+team add gm4_mu_elite.vorpal
+team modify gm4_mu_elite.vorpal prefix {"translate":"text.gm4.monsters_unbound.elite_name.vorpal","fallback":"Vorpal "}
+team add gm4_mu_elite.splitting
+team modify gm4_mu_elite.splitting prefix {"translate":"text.gm4.monsters_unbound.elite_name.splitting","fallback":"Splitting "}
+team add gm4_mu_elite.split
+team modify gm4_mu_elite.split prefix {"translate":"text.gm4.monsters_unbound.elite_name.split","fallback":"Split "}
+team add gm4_mu_elite.volatile
+team modify gm4_mu_elite.volatile prefix {"translate":"text.gm4.monsters_unbound.elite_name.volatile","fallback":"Volatile "}
+team add gm4_mu_elite.pearlescent
+team modify gm4_mu_elite.pearlescent prefix {"translate":"text.gm4.monsters_unbound.elite_name.pearlescent","fallback":"Pearlescent "}
+
+# constants
+scoreboard players set #2 gm4_mu_data 2
+scoreboard players set #4 gm4_mu_data 4
+
+# start clocks
+schedule function gm4_monsters_unbound:tick 1t
+schedule function gm4_monsters_unbound:main 1t
+schedule function gm4_monsters_unbound:slow_clock 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/main.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/main.mcfunction
new file mode 100644
index 0000000000..10acd29ed2
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/main.mcfunction
@@ -0,0 +1,15 @@
+schedule function gm4_monsters_unbound:main 16t
+
+# process cloaked creepers
+execute as @e[type=creeper,tag=gm4_mu_cloaked_creeper] at @s if entity @a[gamemode=!spectator,gamemode=!creative,distance=..3.1] run function gm4_monsters_unbound:mob/process/cloaked_creeper
+
+# zombie spores
+execute as @e[type=item,tag=gm4_mu_spore] at @s run function gm4_monsters_unbound:mob/process/spore/advance
+execute as @e[type=#gm4_survival_refightalized:zombie_types,tag=gm4_mu_spore_zombie,predicate=gm4_monsters_unbound:technical/on_fire] run function gm4_monsters_unbound:mob/process/spore/burn_on_head
+
+# traps
+execute as @e[type=marker,tag=gm4_mu_snowy_trap] at @s if entity @a[gamemode=!spectator,gamemode=!creative,distance=..7] run function gm4_monsters_unbound:mob/process/reveal_snowy_trap
+execute as @e[type=marker,tag=gm4_mu_dripstone_trap] at @s positioned ~-3.5 ~-34 ~-3.5 if entity @a[gamemode=!spectator,gamemode=!creative,dx=6,dy=28,dz=6] at @s run function gm4_monsters_unbound:mob/process/reveal_dripstone_trap
+
+# elites
+execute as @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_elite.process] at @s run function gm4_monsters_unbound:mob/process/elite/check_type
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/pick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/pick.mcfunction
new file mode 100644
index 0000000000..83c3683f9d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/pick.mcfunction
@@ -0,0 +1,78 @@
+# pick elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/mob_type/skeleton/base
+# run from mob/init/mob_type/zombie/base
+
+tag @s add gm4_mu_elite
+
+# zombie villagers are not replaced
+execute if entity @s[type=zombie_villager] run return 0
+
+# don't allow elites to be jockeys
+ride @s dismount
+
+# don't allow entities from splits to be elites
+execute if entity @s[tag=gm4_mu_split_entity] run return 0
+
+# pick a random elite, or use prepicked if set
+execute store result score $elite_pick gm4_mu_data run random value 1..100
+execute if score $prepicked_elite gm4_mu_data matches 1..100 run scoreboard players operation $elite_pick gm4_mu_data = $prepicked_elite gm4_mu_data
+scoreboard players reset $prepicked_elite gm4_mu_data
+
+# do not allow Gargantuan Elite if there is no space
+execute if score $elite_pick gm4_mu_data matches 96.. unless block ~ ~1 ~ #gm4:no_collision store result score $elite_pick gm4_mu_data run random value 1..95
+
+# GLACIAL 15%
+# 3.5x health, 45% KB resist
+# attacks apply chill (15 sec stacking slowness, applies freeze at 7 stacks)
+# explode in a ball of frost on death, exploding after a delay to freeze entities inside for 3 seconds
+# frozen entities cannot act
+execute if score $elite_pick gm4_mu_data matches ..15 run return run function gm4_monsters_unbound:mob/init/elite/type/glacial
+
+# MENDING 15%
+# 2.5x health, -25% speed
+# heals undead in LoS, restoring 24 health and granting them resistance II for 1 second
+# explode in a healing orb on death, heals nearby mobs, can be destroyed to grant everything in radius regeneration
+execute if score $elite_pick gm4_mu_data matches 16..30 run return run function gm4_monsters_unbound:mob/init/elite/type/mending
+
+# ZEPHYR 15%
+# 3x health, +15% speed, +0.5 attack knockback, immune to fall damage
+# after spotting a player stand still to charge for ~4 seconds, then activate:
+# zombie: charge at the player, dealing 25% increased damage
+# skeleton: fire up to 16 arrows in rapid succession that deal 0.5 arrow damage, then gain a speed boost
+execute if score $elite_pick gm4_mu_data matches 31..45 run return run function gm4_monsters_unbound:mob/init/elite/type/zephyr
+
+# BLAZING 10%
+# 3.5x health, -45% speed, -99% damage, can't burn
+# fire aspect II / flame II
+# occasionally stops to shoot homing fireballs at the closest player, exploding when they hit terrain / a player to deal 5 explosion damage
+execute if score $elite_pick gm4_mu_data matches 46..55 run return run function gm4_monsters_unbound:mob/init/elite/type/blazing
+
+# VORPAL 10%
+# 3.5x health
+# can teleports up to 8 blocks away when hit, 65% chance
+# On Death shoot a black cloud tracking the closest player, causing them to go blind, obscuring their vision and removing sounds
+execute if score $elite_pick gm4_mu_data matches 56..65 run return run function gm4_monsters_unbound:mob/init/elite/type/vorpal
+
+# SPLITTING 10%
+# 3.5x health
+# on death splits into 5 miniature versions of the entity, with -50% in scale and reduced stats
+execute if score $elite_pick gm4_mu_data matches 66..75 run return run function gm4_monsters_unbound:mob/init/elite/type/splitting
+
+# VOLATILE 10%
+# 3.5x health, +20% movement speed, +25% attack damage, arrow delay set to 0
+# calls down pillars of energy that explode after 4 seconds, leaving a dragon_fireball
+execute if score $elite_pick gm4_mu_data matches 76..85 run return run function gm4_monsters_unbound:mob/init/elite/type/volatile
+
+# PEARLESCENT 10%
+# 3.5x health
+# occasionally slow to shoot a beam of light at a player, damaging them over time
+execute if score $elite_pick gm4_mu_data matches 86..95 run return run function gm4_monsters_unbound:mob/init/elite/type/pearlescent
+
+# GARGANTUAN 5%
+# 6.5x health (4.5x for skeleton), +50% size, +35% attack damage, 1.75 attack knockback, 85% movement efficiency, -35% speed
+# projectile protection 4, skeletons have punch II and power I on bow
+# based on missing health gain up to 150% speed, 50% attack damage and from 85-100% knockback resistance
+# Occasionally charges up a stomp attack that slows and deals 75% damage to players within 7 blocks
+execute if score $elite_pick gm4_mu_data matches 96.. run return run function gm4_monsters_unbound:mob/init/elite/type/gargantuan
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/blazing.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/blazing.mcfunction
new file mode 100644
index 0000000000..5a54f17ae9
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/blazing.mcfunction
@@ -0,0 +1,23 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.blazing
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.fire 2.5 add_multiplied_total
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:elite_buff.fire -0.99 add_multiplied_total
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.fire -0.45 add_multiplied_total
+attribute @s minecraft:burning_time modifier add gm4_monsters_unbound:elite_buff.fire -1 add_multiplied_total
+
+enchant @s[type=#gm4_survival_refightalized:skeleton_types] flame
+scoreboard players set @s[type=#gm4_survival_refightalized:skeleton_types] gm4_sr_arrow.damage_change -18
+scoreboard players add @s[type=#gm4_survival_refightalized:skeleton_types] gm4_sr_arrow.fire_delay 2
+item replace entity @s[type=!#gm4_survival_refightalized:skeleton_types] weapon.mainhand with blaze_rod[enchantments={fire_aspect:2}]
+data modify entity @s drop_chances.mainhand set value 0
+
+item replace entity @s armor.head with magma_block[enchantments={binding_curse:1},enchantment_glint_override=false]
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.blazing
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/gargantuan.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/gargantuan.mcfunction
new file mode 100644
index 0000000000..ba9e87eaec
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/gargantuan.mcfunction
@@ -0,0 +1,27 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.gargantuan
+tag @s add gm4_mu_elite.process
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.giant 5.5 add_multiplied_total
+attribute @s minecraft:gravity modifier add gm4_monsters_unbound:elite_buff.giant 0.5 add_multiplied_total
+attribute @s minecraft:jump_strength modifier add gm4_monsters_unbound:elite_buff.giant 0.5 add_multiplied_total
+attribute @s minecraft:attack_knockback modifier add gm4_monsters_unbound:elite_buff.giant 1.75 add_value
+attribute @s minecraft:water_movement_efficiency modifier add gm4_monsters_unbound:elite_buff.giant 0.85 add_value
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.giant -0.35 add_multiplied_total
+
+attribute @s[type=#gm4_survival_refightalized:skeleton_types] minecraft:scale modifier add gm4_monsters_unbound:elite_buff.giant_size 0.507537 add_multiplied_total
+attribute @s[type=!#gm4_survival_refightalized:skeleton_types] minecraft:scale modifier add gm4_monsters_unbound:elite_buff.giant_size 0.538461 add_multiplied_total
+
+enchant @s[type=#gm4_survival_refightalized:skeleton_types] punch 2
+enchant @s[type=#gm4_survival_refightalized:skeleton_types] power 1
+
+scoreboard players set @s[type=#gm4_survival_refightalized:skeleton_types] gm4_sr_arrow.fire_delay 7
+
+item replace entity @s armor.head with cobblestone[enchantment_glint_override=false,minecraft:enchantments={projectile_protection:5,binding_curse:1}] 1
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.gargantuan
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/glacial.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/glacial.mcfunction
new file mode 100644
index 0000000000..88da0b8e6e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/glacial.mcfunction
@@ -0,0 +1,15 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_slowing_attack
+tag @s add gm4_mu_elite.glacial
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.frost 2.5 add_multiplied_total
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:elite_buff.frost 0.45 add_value
+
+loot replace entity @s armor.head loot gm4_monsters_unbound:elite/glacial
+data modify entity @s drop_chances.head set value 1
+
+team join gm4_mu_elite.glacial
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/mending.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/mending.mcfunction
new file mode 100644
index 0000000000..4092c80adb
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/mending.mcfunction
@@ -0,0 +1,15 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.mending
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.heal 1.5 add_multiplied_total
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.heal -0.25 add_multiplied_total
+
+loot replace entity @s armor.head loot gm4_monsters_unbound:elite/mending
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.mending
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/pearlescent.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/pearlescent.mcfunction
new file mode 100644
index 0000000000..02b651b548
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/pearlescent.mcfunction
@@ -0,0 +1,16 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.pearlescent
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.pearlescent 2.5 add_multiplied_total
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.pearlescent 0.2 add_multiplied_total
+
+item replace entity @s weapon.mainhand with air
+loot replace entity @s armor.head loot gm4_monsters_unbound:elite/pearlescent
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.pearlescent
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/splitting.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/splitting.mcfunction
new file mode 100644
index 0000000000..868c60d9dc
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/splitting.mcfunction
@@ -0,0 +1,15 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.splitting
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.vorpal 2.5 add_multiplied_total
+
+loot replace entity @s[type=!#gm4_survival_refightalized:skeleton_types] armor.head loot gm4_monsters_unbound:elite/splitting_zombie
+loot replace entity @s[type=#gm4_survival_refightalized:skeleton_types] armor.head loot gm4_monsters_unbound:elite/splitting_skeleton
+data modify entity @s drop_chances.head set value 1
+
+team join gm4_mu_elite.splitting
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/volatile.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/volatile.mcfunction
new file mode 100644
index 0000000000..9c4d1e4e3d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/volatile.mcfunction
@@ -0,0 +1,17 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.volatile
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.volatile 2.5 add_multiplied_total
+
+loot replace entity @s armor.head loot gm4_monsters_unbound:elite/volatile
+data modify entity @s drop_chances.head set value 1
+
+team join gm4_mu_elite.volatile
+
+scoreboard players set @s gm4_sr_arrow.fire_delay 0
+scoreboard players set @s gm4_sr_arrow.damage_change -10
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/vorpal.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/vorpal.mcfunction
new file mode 100644
index 0000000000..66cfbd505e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/vorpal.mcfunction
@@ -0,0 +1,17 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.vorpal
+tag @s add gm4_mu_elite.on_hit
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.vorpal 2.5 add_multiplied_total
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:elite_buff.vorpal 0.25 add_multiplied_total
+
+loot replace entity @s armor.head loot gm4_monsters_unbound:elite/vorpal
+data modify entity @s drop_chances.head set value 1
+
+scoreboard players add @s gm4_sr_arrow.damage_change 5
+
+team join gm4_mu_elite.vorpal
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/zephyr.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/zephyr.mcfunction
new file mode 100644
index 0000000000..546c9b5a10
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/elite/type/zephyr.mcfunction
@@ -0,0 +1,22 @@
+# pick this elite type to spawn
+# @s = zombie / skeleton types
+# at @s
+# run from mob/init/elite/pick
+
+tag @s add gm4_mu_elite.process
+tag @s add gm4_mu_elite.zephyr
+
+effect give @s wind_charged infinite 0 true
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:elite_buff.speed 2.5 add_multiplied_total
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.speed 0.15 add_multiplied_total
+attribute @s minecraft:attack_knockback modifier add gm4_monsters_unbound:elite_buff.speed 0.5 add_value
+attribute @s minecraft:fall_damage_multiplier modifier add gm4_monsters_unbound:elite_buff.speed -1 add_multiplied_total
+
+item replace entity @s armor.head with white_wool[enchantments={binding_curse:1},enchantment_glint_override=false]
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.zephyr
+
+scoreboard players set @s gm4_sr_arrow.fire_delay 0
+scoreboard players set @s gm4_sr_arrow.damage_change -15
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type.mcfunction
new file mode 100644
index 0000000000..cb80d56d63
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type.mcfunction
@@ -0,0 +1,13 @@
+# check what mob is being processed
+# @s = mobs that can be buffed
+# at @s
+# run from function call gm4_survival_refightalized:init_mob, from gm4_survival_refightalized:mob/init/initiate
+
+# zombie, zombie_villager, husk, drowned
+execute if entity @s[type=#gm4_survival_refightalized:zombie_types] run return run function gm4_monsters_unbound:mob/init/mob_type/zombie/base
+# skeleton, bogged, stray
+execute if entity @s[type=#gm4_survival_refightalized:skeleton_types,type=!wither_skeleton] run return run function gm4_monsters_unbound:mob/init/mob_type/skeleton/base
+execute if entity @s[type=spider] run return run function gm4_monsters_unbound:mob/init/mob_type/spider/spider
+execute if entity @s[type=creeper] run return run function gm4_monsters_unbound:mob/init/mob_type/creeper/base
+execute if entity @s[type=cave_spider] run return run function gm4_monsters_unbound:mob/init/mob_type/spider/cave_spider
+execute if entity @s[type=enderman] run return run function gm4_monsters_unbound:mob/init/mob_type/enderman/base
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/base.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/base.mcfunction
new file mode 100644
index 0000000000..ebb31255f4
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/base.mcfunction
@@ -0,0 +1,23 @@
+# calculate modifiers for newly spawned creeper
+# @s = creeper
+# at @s
+# run from mob/init/mob_type
+
+# | Biome Modifiers
+# snowy
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/snowy] run function gm4_monsters_unbound:mob/init/mob_type/creeper/snowy
+# mountainous
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.30},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/mountainous"}]} run function gm4_monsters_unbound:mob/init/mob_type/creeper/mountainous
+# burned
+execute if predicate gm4_monsters_unbound:biome/burned store result entity @s Fuse int 0.75 run data get entity @s Fuse
+# flowering
+execute if predicate gm4_monsters_unbound:biome/flowering run function gm4_monsters_unbound:mob/init/mob_type/creeper/flowering
+# toxic
+tag @s[predicate=gm4_monsters_unbound:biome/toxic] add gm4_mu_toxic_creeper
+execute if entity @s[tag=gm4_mu_toxic_creeper] run function gm4_monsters_unbound:mob/process/toxic_creeper
+# growth
+attribute @s[predicate=gm4_monsters_unbound:biome/growth] minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.growth 0.2 add_multiplied_base
+# underground
+data modify entity @s[predicate=gm4_survival_refightalized:mob/underground] ExplosionRadius set value 4s
+# dripstone caves
+execute if biome ~ ~ ~ dripstone_caves if block ~.875 ~ ~.875 #gm4:no_collision if block ~.875 ~ ~-.875 #gm4:no_collision if block ~-.875 ~ ~.875 #gm4:no_collision if block ~-.875 ~ ~-.875 #gm4:no_collision run function gm4_monsters_unbound:mob/init/mob_type/creeper/dripstone_caves
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/dripstone_caves.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/dripstone_caves.mcfunction
new file mode 100644
index 0000000000..27330cb684
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/dripstone_caves.mcfunction
@@ -0,0 +1,10 @@
+# replace with spider
+# @s = creeper
+# at @s
+# run from mob/init/mob_type/creeper/base
+
+summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/flowering.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/flowering.mcfunction
new file mode 100644
index 0000000000..0228c6d9a9
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/flowering.mcfunction
@@ -0,0 +1,8 @@
+# apply invisibility to creeper
+# @s = creeper
+# at @s
+# run from mob/init/mob_type/creeper/base
+
+tag @s add gm4_mu_cloaked_creeper
+effect give @s invisibility 35 0
+data modify entity @s ExplosionRadius set value 2s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/mountainous.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/mountainous.mcfunction
new file mode 100644
index 0000000000..e15a891037
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/mountainous.mcfunction
@@ -0,0 +1,7 @@
+# make this creeper stronger
+# @s = creeper
+# at @s
+# run from mob/init/mob_type/creeper/base
+
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:stat_change.gargantuan 0.4 add_value
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.gargantuan 0.25 add_multiplied_total
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/snowy.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/snowy.mcfunction
new file mode 100644
index 0000000000..f8bc45e553
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/creeper/snowy.mcfunction
@@ -0,0 +1,15 @@
+# replace creeper with a snowy trap or zombie/stray
+# @s = creeper
+# at @s
+# run from mob/init/mob_type/creeper/base
+
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $removed_mob gm4_sr_data 1
+
+execute if block ~ ~ ~ snow run return run summon marker ~ ~ ~ {Tags:["gm4_mu_trap","gm4_mu_snowy_trap"],CustomName:'{"text":"GM4 Monsters Unbound - Snow Trap"}'}
+
+execute store result score $pick_entity gm4_mu_data run random value 1..2
+scoreboard players set $mob_extras gm4_sr_data 1
+execute if score $pick_entity gm4_mu_data matches 1 run summon zombie ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if score $pick_entity gm4_mu_data matches 2 run summon stray ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/base.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/base.mcfunction
new file mode 100644
index 0000000000..ab0bb045ed
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/base.mcfunction
@@ -0,0 +1,27 @@
+# calculate modifiers for newly spawned enderman
+# @s = enderman
+# at @s
+# run from mob/init/mob_type
+
+# | Biome Modifiers
+# flowering
+execute if predicate gm4_monsters_unbound:biome/flowering if predicate {condition:"minecraft:random_chance",chance:0.50} run function gm4_monsters_unbound:mob/init/mob_type/enderman/flowering
+# toxic
+execute if predicate gm4_monsters_unbound:biome/toxic if predicate {condition:"minecraft:random_chance",chance:0.50} run function gm4_monsters_unbound:mob/init/mob_type/enderman/toxic
+# burned
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/burned] store success score $mob_extras gm4_sr_data run summon enderman ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/burned] store success score $mob_extras gm4_sr_data run summon enderman ~-.05 ~ ~.05 {Tags:["gm4_sr_extra_mob"]}
+# growth
+execute if predicate gm4_monsters_unbound:biome/growth run function gm4_monsters_unbound:mob/init/mob_type/enderman/growth
+# underground
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_survival_refightalized:mob/underground] if predicate {condition:"minecraft:random_chance",chance:0.15} run function gm4_monsters_unbound:mob/init/mob_type/enderman/underground
+# dripstone caves
+execute if biome ~ ~ ~ dripstone_caves if block ~.875 ~ ~.875 #gm4:no_collision if block ~.875 ~ ~-.875 #gm4:no_collision if block ~-.875 ~ ~.875 #gm4:no_collision if block ~-.875 ~ ~-.875 #gm4:no_collision run function gm4_monsters_unbound:mob/init/mob_type/enderman/dripstone_caves
+
+# the end
+execute if dimension the_end run attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:stat_change.the_end 0.2 add_multiplied_base
+execute if dimension the_end run attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.the_end 0.15 add_multiplied_base
+# nether wastes
+execute if biome ~ ~ ~ nether_wastes if predicate {condition:"minecraft:random_chance",chance:0.95} run function gm4_monsters_unbound:mob/init/mob_type/enderman/nether_wastes
+# soul sand valley
+execute if biome ~ ~ ~ soul_sand_valley if predicate {condition:"minecraft:random_chance",chance:0.95} run function gm4_monsters_unbound:mob/init/mob_type/enderman/soul_sand_valley
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/dripstone_caves.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/dripstone_caves.mcfunction
new file mode 100644
index 0000000000..0ff69189cf
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/dripstone_caves.mcfunction
@@ -0,0 +1,10 @@
+# replace with spider
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/flowering.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/flowering.mcfunction
new file mode 100644
index 0000000000..ca42ad871e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/flowering.mcfunction
@@ -0,0 +1,10 @@
+# replace enderman with a slime
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon slime ~ ~ ~ {Tags:["gm4_sr_extra_mob"],Size:2}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/growth.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/growth.mcfunction
new file mode 100644
index 0000000000..2fe8f8ae38
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/growth.mcfunction
@@ -0,0 +1,11 @@
+# replace enderman with a 3 skeletons
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+execute if biome ~ ~ ~ mangrove_swamp run summon bogged ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if biome ~ ~ ~ snowy_taiga run summon stray ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute unless biome ~ ~ ~ mangrove_swamp unless biome ~ ~ ~ snowy_taiga run summon skeleton ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+summon skeleton ~0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"]}
+summon skeleton ~-0.15 ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+scoreboard players set $mob_extras gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/nether_wastes.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/nether_wastes.mcfunction
new file mode 100644
index 0000000000..e986d98263
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/nether_wastes.mcfunction
@@ -0,0 +1,10 @@
+# replace enderman with blaze
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon blaze ~ ~0.3 ~ {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/soul_sand_valley.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/soul_sand_valley.mcfunction
new file mode 100644
index 0000000000..649ef8378e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/soul_sand_valley.mcfunction
@@ -0,0 +1,10 @@
+# replace enderman with wither skeleton
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon wither_skeleton ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/toxic.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/toxic.mcfunction
new file mode 100644
index 0000000000..928781af95
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/toxic.mcfunction
@@ -0,0 +1,10 @@
+# replace enderman with a witch
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon witch ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/underground.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/underground.mcfunction
new file mode 100644
index 0000000000..7973d0bbe8
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/enderman/underground.mcfunction
@@ -0,0 +1,11 @@
+# spawn 5 more enderman
+# @s = enderman
+# at @s
+# run from mob/init/mob_type/enderman/base
+
+summon enderman ~0.15 ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+summon enderman ~0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"]}
+summon enderman ~-0.15 ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+summon enderman ~0.15 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+summon enderman ~ ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+scoreboard players set $mob_extras gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/base.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/base.mcfunction
new file mode 100644
index 0000000000..df9a1c6f2a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/base.mcfunction
@@ -0,0 +1,33 @@
+# calculate modifiers for newly spawned skeleton / stray
+# @s = skeleton types
+# at @s
+# run from mob/init/mob_type
+
+# elites - don't get other modifiers - 5% of spawns
+execute store result score $nearby_elites gm4_mu_data if entity @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_elite,distance=..64]
+execute if score $nearby_elites gm4_mu_data matches ..3 if predicate {condition:"minecraft:random_chance",chance:0.05} run tag @s[tag=!gm4_sr_extra_mob] add gm4_mu_elite
+execute if entity @s[tag=gm4_mu_elite] run return run function gm4_monsters_unbound:mob/init/elite/pick
+
+# | Biome Modifiers
+# snowy
+execute if entity @s[type=stray,predicate=gm4_monsters_unbound:biome/snowy,predicate=!gm4_monsters_unbound:biome/growth] run loot replace entity @s weapon.offhand loot gm4_monsters_unbound:mob/equip_arrow/stray_snowy
+# mountainous
+execute if predicate gm4_monsters_unbound:biome/mountainous positioned ~ ~35 ~ store result score $phantom_count gm4_mu_data if entity @e[type=phantom,distance=..32]
+execute if score $spawn_phantoms gm4_sr_config matches 1 if score $phantom_count gm4_mu_data < $mob_limit.phantom gm4_sr_config if predicate gm4_monsters_unbound:chance/spawn_phantom run function gm4_monsters_unbound:mob/init/mob_type/zombie/spawn_phantoms
+# flowering
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.85},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/flowering"}]} run function gm4_monsters_unbound:mob/init/mob_type/skeleton/flowering
+# toxic
+tag @s add gm4_mu_self
+execute if entity @s[type=bogged,predicate=gm4_monsters_unbound:biome/toxic] if predicate {condition:"minecraft:random_chance",chance:0.15} summon spider run function gm4_monsters_unbound:mob/init/mob_type/skeleton/toxic
+tag @s remove gm4_mu_self
+# burning
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.15},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/burned"}]} run enchant @s flame 1
+# growth
+execute if entity @s[type=!bogged,predicate=gm4_monsters_unbound:biome/growth] run function gm4_monsters_unbound:mob/init/mob_type/skeleton/growth
+# dripstone caves
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"location_check",predicate:{biomes:"dripstone_caves"}},{condition:"random_chance",chance:0.6}]} run item replace entity @s weapon.mainhand with stone_pickaxe
+# underground
+execute if predicate gm4_survival_refightalized:mob/underground if predicate {condition:"minecraft:random_chance",chance:0.4} run function gm4_monsters_unbound:mob/init/mob_type/skeleton/underground
+
+# soul sand valley
+execute if biome ~ ~ ~ soul_sand_valley run effect give @s fire_resistance infinite 0 true
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/flowering.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/flowering.mcfunction
new file mode 100644
index 0000000000..0f3d349c39
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/flowering.mcfunction
@@ -0,0 +1,10 @@
+# replace skeleton with zombie
+# @s = skeleton
+# at @s
+# run from mob/init/mob_type/skeleton/base
+
+summon zombie ~.1 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+scoreboard players set $mob_extras gm4_sr_data 1
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/growth.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/growth.mcfunction
new file mode 100644
index 0000000000..b6881d2514
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/growth.mcfunction
@@ -0,0 +1,8 @@
+# apply growth effects to skeleton
+# @s = skeleton
+# at @s
+# run from mob/init/mob_type/skeleton/base
+
+item replace entity @s weapon.mainhand with air
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.growth 4 add_value
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.growth 0.25 add_multiplied_base
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/toxic.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/toxic.mcfunction
new file mode 100644
index 0000000000..1b26ae6a87
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/toxic.mcfunction
@@ -0,0 +1,7 @@
+# make the bogged ride a spider
+# @s = bogged
+# at @s
+# run from mob/init/mob_type/skeleton/base
+
+tag @s add gm4_sr_extra_mob
+ride @e[tag=gm4_mu_self,distance=..0.1,limit=1] mount @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/underground.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/underground.mcfunction
new file mode 100644
index 0000000000..efeed6cb16
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/skeleton/underground.mcfunction
@@ -0,0 +1,11 @@
+# apply an underground buff
+# @s = skeleton
+# at @s
+# run from mob/init/mob_type/skeleton/base
+
+execute store result score $buff_picked gm4_mu_data run random value 1..4
+
+execute if score $buff_picked gm4_mu_data matches 1 run effect give @s regeneration infinite 0
+execute if score $buff_picked gm4_mu_data matches 2 run scoreboard players add @s[tag=!gm4_mu_elite.split_entity] gm4_sr_arrow.damage_change 4
+execute if score $buff_picked gm4_mu_data matches 3 run scoreboard players remove @s gm4_sr_arrow.fire_delay 1
+execute if score $buff_picked gm4_mu_data matches 4 run item replace entity @s weapon.mainhand with stone_sword
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/cave_spider.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/cave_spider.mcfunction
new file mode 100644
index 0000000000..81d9766f34
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/cave_spider.mcfunction
@@ -0,0 +1,17 @@
+# calculate modifiers for newly spawned cave spider
+# @s = cave spider
+# at @s
+# run from mob/init/mob_type
+
+# | Biome Modifiers
+# mountainous
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.40},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/mountainous"}]} run effect give @s speed infinite 0
+# burned
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.50},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/burned"}]} run effect give @s fire_resistance infinite 0
+# toxic
+tag @s[predicate=gm4_monsters_unbound:biome/toxic] add gm4_mu_toxic_attack
+# growth
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/growth] store success score $mob_extras gm4_sr_data run summon cave_spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/growth] if predicate {condition:"minecraft:random_chance",chance:0.60} store success score $mob_extras gm4_sr_data run summon cave_spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+# dripstone caves
+execute if biome ~ ~ ~ dripstone_caves run attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.dripstone_caves 1 add_multiplied_total
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/gargantuan.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/gargantuan.mcfunction
new file mode 100644
index 0000000000..a32dd705f5
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/gargantuan.mcfunction
@@ -0,0 +1,13 @@
+# make spider gargantuan
+# @s = spider
+# at @s
+# run from mob/init/mob_type/spider/spider
+# run from mob/init/mob_type/spider/underground/pick
+
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.gargantuan 0.25 add_multiplied_total
+attribute @s minecraft:scale modifier add gm4_monsters_unbound:stat_change.gargantuan 0.25 add_multiplied_total
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.gargantuan 0.75 add_multiplied_total
+effect give @s weaving infinite 0
+team join gm4_mu_elite.gargantuan
+tag @s add gm4_mu_elite
+tag @s add gm4_mu_elite.gargantuan
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/lush_caves.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/lush_caves.mcfunction
new file mode 100644
index 0000000000..6d7d20fad6
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/lush_caves.mcfunction
@@ -0,0 +1,13 @@
+# replace spider with 4 silverfish
+# @s = spider
+# at @s
+# run from mob/init/mob_type/spider/spider
+
+summon silverfish ~0.15 ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+summon silverfish ~0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"]}
+summon silverfish ~-0.15 ~ ~0.15 {Tags:["gm4_sr_extra_mob"]}
+summon silverfish ~-0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/spider.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/spider.mcfunction
new file mode 100644
index 0000000000..f70f7f3520
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/spider.mcfunction
@@ -0,0 +1,23 @@
+# calculate modifiers for newly spawned spider
+# @s = spider
+# at @s
+# run from mob/init/mob_type
+
+# | Biome Modifiers
+# snowy
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.15},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/snowy"}]} run function gm4_monsters_unbound:mob/init/mob_type/spider/gargantuan
+# mountainous
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.40},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/mountainous"}]} run effect give @s speed infinite 0
+# burned
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.50},{condition:"minecraft:reference",name:"gm4_monsters_unbound:biome/burned"}]} run effect give @s fire_resistance infinite 0
+# flowering
+execute if biome ~ ~ ~ lush_caves if predicate {condition:"minecraft:random_chance",chance:0.50} run function gm4_monsters_unbound:mob/init/mob_type/spider/lush_caves
+# toxic
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/toxic] run function gm4_monsters_unbound:mob/init/mob_type/spider/toxic
+# growth
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/growth] store success score $mob_extras gm4_sr_data run summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if entity @s[tag=!gm4_sr_extra_mob,predicate=gm4_monsters_unbound:biome/growth] if predicate {condition:"minecraft:random_chance",chance:0.60} store success score $mob_extras gm4_sr_data run summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+# dripstone caves
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.1},{condition:"minecraft:location_check",predicate:{biomes:"dripstone_caves"}}]} run function gm4_monsters_unbound:mob/init/mob_type/spider/gargantuan
+# underground
+execute if predicate {condition:"minecraft:all_of",terms:[{condition:"minecraft:random_chance",chance:0.25},{condition:"minecraft:reference",name:"gm4_survival_refightalized:mob/underground"}]} run function gm4_monsters_unbound:mob/init/mob_type/spider/underground/pick
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/toxic.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/toxic.mcfunction
new file mode 100644
index 0000000000..645f368dc5
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/toxic.mcfunction
@@ -0,0 +1,9 @@
+# summon 3 cave spiders
+# @s = spider
+# at @s
+# run from mob/init/mob_type/spider/spider
+
+summon cave_spider ~ ~ ~0.15 {Tags:["gm4_sr_extra_mob"],attributes:[{id:"minecraft:max_health",base:9}]}
+summon cave_spider ~0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"],attributes:[{id:"minecraft:max_health",base:9}]}
+summon cave_spider ~-0.15 ~ ~-0.15 {Tags:["gm4_sr_extra_mob"],attributes:[{id:"minecraft:max_health",base:9}]}
+scoreboard players set $mob_extras gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/pick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/pick.mcfunction
new file mode 100644
index 0000000000..b5c06764ac
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/pick.mcfunction
@@ -0,0 +1,10 @@
+# pick underground buff
+# @s = spider
+# at @s
+# run from mob/init/mob_type/spider/spider
+
+execute store result score $buff_picked gm4_mu_data run random value 1..3
+
+execute if score $buff_picked gm4_mu_data matches 1 run effect give @s invisibility infinite 0
+execute if score $buff_picked gm4_mu_data matches 2 run function gm4_monsters_unbound:mob/init/mob_type/spider/gargantuan
+execute if score $buff_picked gm4_mu_data matches 3 run function gm4_monsters_unbound:mob/init/mob_type/spider/underground/replace_with_cave_spider
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/replace_with_cave_spider.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/replace_with_cave_spider.mcfunction
new file mode 100644
index 0000000000..8a1195aaff
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/spider/underground/replace_with_cave_spider.mcfunction
@@ -0,0 +1,10 @@
+# replace with cave spider
+# @s = spider
+# at @s
+# run from mob/init/mob_type/spider/underground/pick
+
+summon cave_spider ~.1 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+scoreboard players set $mob_extras gm4_sr_data 1
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/base.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/base.mcfunction
new file mode 100644
index 0000000000..6be391bc36
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/base.mcfunction
@@ -0,0 +1,31 @@
+# calculate modifiers for newly spawned zombie / zombie villager
+# @s = zombie types
+# at @s
+# run from mob/init/mob_type
+
+# elites - don't get other modifiers - 5% of spawns (replaces baby zombies)
+execute if entity @s[tag=gm4_sr_was_baby] store result score $nearby_elites gm4_mu_data if entity @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_elite,distance=..64]
+execute if entity @s[tag=gm4_sr_was_baby] if score $nearby_elites gm4_mu_data matches ..3 run return run function gm4_monsters_unbound:mob/init/elite/pick
+
+# | Biome Modifiers
+# snowy
+execute if predicate gm4_monsters_unbound:biome/snowy run function gm4_monsters_unbound:mob/init/mob_type/zombie/snowy
+tag @s[predicate=gm4_monsters_unbound:biome/snowy] add gm4_mu_slowing_attack
+# mountainous
+execute if predicate gm4_monsters_unbound:biome/mountainous run function gm4_monsters_unbound:mob/init/mob_type/zombie/mountainous
+# burned
+execute if entity @s[type=husk,predicate=gm4_monsters_unbound:biome/burned] run function gm4_monsters_unbound:mob/init/mob_type/zombie/burned_husk
+# flowering
+execute if predicate gm4_monsters_unbound:biome/flowering run tag @s add gm4_mu_spore_zombie
+execute if entity @s[tag=gm4_mu_spore_zombie] run function gm4_monsters_unbound:mob/init/mob_type/zombie/flowering
+# toxic
+tag @s[predicate=gm4_monsters_unbound:biome/toxic] add gm4_mu_weakness_attack
+effect give @s[predicate=gm4_monsters_unbound:biome/toxic] infested infinite 0
+# reef
+execute if entity @s[type=drowned,predicate=gm4_monsters_unbound:biome/reef] run function gm4_monsters_unbound:mob/init/mob_type/zombie/reef_drowned
+# growth
+execute if entity @s[type=!zombie_villager,tag=!gm4_mu_spore_zombie,predicate=gm4_monsters_unbound:biome/growth] run function gm4_monsters_unbound:mob/init/mob_type/zombie/growth
+# dripstone caves
+execute if entity @s[tag=!gm4_sr_extra_mob] if biome ~ ~ ~ dripstone_caves run function gm4_monsters_unbound:mob/init/mob_type/zombie/dripstone_caves/try
+# underground (not dripstone caves)
+execute if predicate {condition:"all_of",terms:[{condition:"reference",name:"gm4_survival_refightalized:mob/underground"},{condition:"inverted",term:{condition:"location_check",predicate:{"biomes":"dripstone_caves"}}},{condition:"random_chance",chance:0.5}]} run function gm4_monsters_unbound:mob/init/mob_type/zombie/underground/pick
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk.mcfunction
new file mode 100644
index 0000000000..2b82605d37
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk.mcfunction
@@ -0,0 +1,9 @@
+# apply burned husk effects
+# @s = husk
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.burned_husk -0.65 add_multiplied_total
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:stat_change.burned_husk -0.25 add_multiplied_total
+execute at @p[gamemode=!spectator] store result score $husk_count gm4_mu_data if entity @e[type=husk,distance=..128]
+execute if entity @s[tag=!gm4_sr_extra_mob] unless score $husk_count gm4_mu_data > $mob_limit.husk_army gm4_sr_config run function gm4_monsters_unbound:mob/init/mob_type/zombie/burned_husk_army
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk_army.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk_army.mcfunction
new file mode 100644
index 0000000000..df79b1b483
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/burned_husk_army.mcfunction
@@ -0,0 +1,18 @@
+# spawn up to 11 extra husks
+# @s = husk
+# at @s
+# run from mob/init/mob_type/zombie/burned_husk
+
+execute if block ~1 ~ ~ #gm4:no_collision if block ~1 ~1 ~ #gm4:no_collision run summon husk ~1 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if block ~-1 ~ ~ #gm4:no_collision if block ~-1 ~1 ~ #gm4:no_collision run summon husk ~-1 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if block ~ ~ ~1 #gm4:no_collision if block ~ ~1 ~1 #gm4:no_collision run summon husk ~ ~ ~1 {Tags:["gm4_sr_extra_mob"]}
+execute if block ~ ~ ~-1 #gm4:no_collision if block ~ ~1 ~-1 #gm4:no_collision run summon husk ~ ~ ~-1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.5} if block ~1 ~ ~1 #gm4:no_collision if block ~1 ~1 ~1 #gm4:no_collision run summon husk ~1 ~ ~1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.5} if block ~-1 ~ ~-1 #gm4:no_collision if block ~-1 ~1 ~-1 #gm4:no_collision run summon husk ~-1 ~ ~-1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.5} if block ~1 ~ ~-1 #gm4:no_collision if block ~1 ~1 ~-1 #gm4:no_collision run summon husk ~1 ~ ~-1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.25} if block ~-1 ~ ~1 #gm4:no_collision if block ~-1 ~1 ~1 #gm4:no_collision run summon husk ~-1 ~ ~1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.25} if block ~2 ~ ~-1 #gm4:no_collision if block ~2 ~1 ~-1 #gm4:no_collision run summon husk ~2 ~ ~-1 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.25} if block ~-1 ~ ~2 #gm4:no_collision if block ~-1 ~1 ~2 #gm4:no_collision run summon husk ~-1 ~ ~2 {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.25} if block ~2 ~ ~2 #gm4:no_collision if block ~2 ~1 ~2 #gm4:no_collision run summon husk ~2 ~ ~2 {Tags:["gm4_sr_extra_mob"]}
+
+scoreboard players set $mob_extras gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/place.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/place.mcfunction
new file mode 100644
index 0000000000..a8aadfec3d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/place.mcfunction
@@ -0,0 +1,12 @@
+# place dripstone trap
+# @s = zombie
+# at @s positioned ~ ~x ~
+# run from mob/init/mob_type/zombie/dripstone_caves/raycast
+
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $removed_mob gm4_sr_data 1
+
+scoreboard players set $raycast_limit gm4_mu_data -1
+
+execute align y run summon marker ~ ~ ~ {Tags:["gm4_mu_trap","gm4_mu_dripstone_trap"],CustomName:'{"text":"GM4 Monsters Unbound - Dripstone Trap"}'}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/raycast.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/raycast.mcfunction
new file mode 100644
index 0000000000..467bacb085
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/raycast.mcfunction
@@ -0,0 +1,10 @@
+# zombie dripstone try to find place for a trap
+# @s = zombie
+# at @s positioned ~ ~x ~
+# run from mob/init/mob_type/zombie/dripstone_caves/try
+# run from here
+
+execute if block ~ ~1 ~ #gm4_monsters_unbound:dripstone run return run function gm4_monsters_unbound:mob/init/mob_type/zombie/dripstone_caves/place
+
+scoreboard players remove $raycast_limit gm4_mu_data 1
+execute if score $raycast_limit gm4_mu_data matches 1.. positioned ~ ~1 ~ if block ~ ~ ~ #gm4:no_collision run function gm4_monsters_unbound:mob/init/mob_type/zombie/dripstone_caves/raycast
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/try.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/try.mcfunction
new file mode 100644
index 0000000000..43fd6de9d2
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/dripstone_caves/try.mcfunction
@@ -0,0 +1,19 @@
+# zombie dripstone try to place a trap
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $removed_mob gm4_sr_data 1
+
+scoreboard players set $raycast_limit gm4_mu_data 32
+execute positioned ~ ~1 ~ run function gm4_monsters_unbound:mob/init/mob_type/zombie/dripstone_caves/raycast
+
+# stop if the raycast was succesful
+execute if score $raycast_limit gm4_mu_data matches -1 run return 0
+
+scoreboard players set $spawned_mob gm4_mu_data 0
+execute if block ~.875 ~ ~.875 #gm4:no_collision if block ~.875 ~ ~-.875 #gm4:no_collision if block ~-.875 ~ ~.875 #gm4:no_collision if block ~-.875 ~ ~-.875 #gm4:no_collision store success score $spawned_mob gm4_mu_data run summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if score $spawned_mob gm4_mu_data matches 0 run summon skeleton ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+scoreboard players set $mob_extras gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/equip_shield.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/equip_shield.mcfunction
new file mode 100644
index 0000000000..54b14b49cb
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/equip_shield.mcfunction
@@ -0,0 +1,12 @@
+# give the zombie a shield and bonus stats
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/underground/pick
+# run from mob/init/mob_type/zombie/mountainous
+# run from mob/init/mob_type/zombie/snowy
+
+tag @s add gm4_mu_shielded_zombie
+item replace entity @s weapon.offhand with shield
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:stat_change.shield 0.9 add_value
+attribute @s minecraft:armor modifier add gm4_monsters_unbound:stat_change.shield 20 add_value
+attribute @s minecraft:armor_toughness modifier add gm4_monsters_unbound:stat_change.shield 10 add_value
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/flowering.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/flowering.mcfunction
new file mode 100644
index 0000000000..31ec2f1fc3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/flowering.mcfunction
@@ -0,0 +1,23 @@
+# set flowering zombie stats
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+# in cherry grove use cherry leaves
+execute if biome ~ ~ ~ cherry_grove run tag @s add gm4_mu_spore_zombie.cherry
+
+# lower max health
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.spore_zombie -0.2 add_multiplied_total
+
+# put spore on head and store generation
+loot replace entity @s armor.head loot gm4_monsters_unbound:mob/equip_armor/spore
+execute store result entity @s equipment.head.components."minecraft:custom_data".gm4_mu_spore.generation int 1 run scoreboard players add @s gm4_mu_generation 1
+
+# let generation determine dropchance of spore
+scoreboard players set $spore_dropchange gm4_mu_data 11
+execute store result entity @s drop_chances.head float 0.1 run scoreboard players operation $spore_dropchange gm4_mu_data -= @s gm4_mu_generation
+
+# remove any possible elite triggers
+data remove entity @s attributes[{id:"minecraft:max_health"}].modifiers[{id:"minecraft:leader_zombie_bonus"}]
+data modify entity @s IsBaby set value 0b
+tag @s remove gm4_sr_was_baby
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/growth.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/growth.mcfunction
new file mode 100644
index 0000000000..a3271fa7a3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/growth.mcfunction
@@ -0,0 +1,15 @@
+# apply growth effects to zombie
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+
+execute if biome ~ ~ ~ mangrove_swamp run summon bogged ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if biome ~ ~ ~ snowy_taiga run summon stray ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute unless biome ~ ~ ~ mangrove_swamp unless biome ~ ~ ~ snowy_taiga run summon skeleton ~.05 ~ ~ {Tags:["gm4_sr_extra_mob"]}
+summon skeleton ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+summon skeleton ~-.05 ~ ~.05 {Tags:["gm4_sr_extra_mob"]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/mountainous.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/mountainous.mcfunction
new file mode 100644
index 0000000000..0e12585127
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/mountainous.mcfunction
@@ -0,0 +1,11 @@
+# set mountain zombie stats
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+execute positioned ~ ~35 ~ store result score $phantom_count gm4_mu_data if entity @e[type=phantom,distance=..32]
+execute if score $spawn_phantoms gm4_sr_config matches 1 if score $phantom_count gm4_mu_data < $mob_limit.phantom gm4_sr_config if predicate gm4_monsters_unbound:chance/spawn_phantom run function gm4_monsters_unbound:mob/init/mob_type/zombie/spawn_phantoms
+attribute @s minecraft:attack_knockback modifier add gm4_monsters_unbound:stat_change.mountainous 1 add_value
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:stat_change.mountainous 1 add_value
+
+execute if predicate {condition:"minecraft:random_chance",chance:0.15} run function gm4_monsters_unbound:mob/init/mob_type/zombie/equip_shield
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/reef_drowned.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/reef_drowned.mcfunction
new file mode 100644
index 0000000000..0ccc159b6b
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/reef_drowned.mcfunction
@@ -0,0 +1,17 @@
+# apply reef effects to drowned
+# @s = drowned
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.reef 1 add_multiplied_base
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:stat_change.reef 2 add_value
+
+execute if predicate {condition:"minecraft:random_chance",chance:0.6} if entity @s[tag=!gm4_sr_extra_mob] store success score $mob_extras gm4_sr_data run summon drowned ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.6} if entity @s[tag=!gm4_sr_extra_mob] store success score $mob_extras gm4_sr_data run summon drowned ~ ~ ~ {Tags:["gm4_sr_extra_mob"]}
+execute if predicate {condition:"minecraft:random_chance",chance:0.45} if entity @s[tag=!gm4_sr_extra_mob] store success score $mob_extras gm4_sr_data run summon guardian ~ ~ ~
+execute if predicate {condition:"minecraft:random_chance",chance:0.45} if entity @s[tag=!gm4_sr_extra_mob] store success score $mob_extras gm4_sr_data run summon guardian ~ ~ ~
+execute if predicate {condition:"minecraft:random_chance",chance:0.45} if entity @s[tag=!gm4_sr_extra_mob] store success score $mob_extras gm4_sr_data run summon guardian ~ ~ ~
+
+execute if predicate {condition:"minecraft:random_chance",chance:0.33} run item replace entity @s[tag=!gm4_sr_extra_mob] weapon.mainhand with trident
+
+scoreboard players set @s gm4_sr_arrow.fire_delay 0
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/snowy.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/snowy.mcfunction
new file mode 100644
index 0000000000..8263ab1961
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/snowy.mcfunction
@@ -0,0 +1,9 @@
+# set snowy zombie stats
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:stat_change.snowy -0.15 add_multiplied_total
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:stat_change.snowy 0.2 add_multiplied_total
+
+execute if predicate {condition:"minecraft:random_chance",chance:0.05} run function gm4_monsters_unbound:mob/init/mob_type/zombie/equip_shield
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/spawn_phantoms.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/spawn_phantoms.mcfunction
new file mode 100644
index 0000000000..7c158f1665
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/spawn_phantoms.mcfunction
@@ -0,0 +1,12 @@
+# spawn phantoms
+# @s = zombie / skeleton
+# at @s
+# run from mob/init/mob_type/zombie/base
+# run from mob/init/mob_type/skeleton/base
+
+execute if block ~ ~35 ~ #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~ ~35 ~ {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
+execute if block ~2 ~35 ~ #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~2 ~35 ~ {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
+execute if block ~-1 ~35 ~2 #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~-1 ~35 ~2 {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
+execute if predicate {condition:"random_chance",chance:0.5} if block ~-2 ~35 ~-1 #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~-2 ~35 ~-1 {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
+execute if predicate {condition:"random_chance",chance:0.5} if block ~2 ~35 ~-2 #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~2 ~35 ~-2 {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
+execute if predicate {condition:"random_chance",chance:0.5} if block ~-2 ~35 ~2 #gm4:no_collision store success score $mob_extras gm4_sr_data run summon phantom ~-2 ~35 ~2 {Tags:["gm4_sr_extra_mob","gm4_mu_phantom"]}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/offhand_weapon.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/offhand_weapon.mcfunction
new file mode 100644
index 0000000000..1cf2ab899a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/offhand_weapon.mcfunction
@@ -0,0 +1,8 @@
+# give the zombie an offhand weapon and bonus stats
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/underground/pick
+
+tag @s add gm4_mu_offhanding_zombie
+item replace entity @s weapon.offhand with stone_sword
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:stat_change.offhand_weapon 1.5 add_value
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/pick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/pick.mcfunction
new file mode 100644
index 0000000000..8ef7a0d93a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/pick.mcfunction
@@ -0,0 +1,13 @@
+# pick underground buff
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/base
+
+execute store result score $buff_picked gm4_mu_data run random value 1..6
+
+execute if score $buff_picked gm4_mu_data matches 1 run effect give @s resistance infinite 0
+execute if score $buff_picked gm4_mu_data matches 2 run effect give @s speed infinite 0
+execute if score $buff_picked gm4_mu_data matches 3 run effect give @s regeneration infinite 0
+execute if score $buff_picked gm4_mu_data matches 4 run function gm4_monsters_unbound:mob/init/mob_type/zombie/underground/offhand_weapon
+execute if score $buff_picked gm4_mu_data matches 5 run function gm4_monsters_unbound:mob/init/mob_type/zombie/equip_shield
+execute if score $buff_picked gm4_mu_data matches 6 run function gm4_monsters_unbound:mob/init/mob_type/zombie/underground/replace_with_skeleton
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/replace_with_skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/replace_with_skeleton.mcfunction
new file mode 100644
index 0000000000..54d1390260
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/init/mob_type/zombie/underground/replace_with_skeleton.mcfunction
@@ -0,0 +1,11 @@
+# replace with 2 melee skeletons
+# @s = zombie
+# at @s
+# run from mob/init/mob_type/zombie/underground/pick
+
+summon skeleton ~.05 ~ ~ {Tags:["gm4_sr_extra_mob","gm4_sr_melee_skeleton"],HandItems:[{},{}]}
+summon skeleton ~ ~ ~ {Tags:["gm4_sr_extra_mob","gm4_sr_melee_skeleton"],HandItems:[{},{}]}
+tp @s ~ ~-2050 ~
+kill @s
+scoreboard players set $mob_extras gm4_sr_data 1
+scoreboard players set $removed_mob gm4_sr_data 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/charging_attack.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/charging_attack.mcfunction
new file mode 100644
index 0000000000..55cc04cf58
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/charging_attack.mcfunction
@@ -0,0 +1,10 @@
+# damage players hit by charging attacks
+# @s = player that was hit
+# at unspecified
+advancement revoke @s only gm4_monsters_unbound:damaged/attack_effect/charging
+
+execute as @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_charging_attack,limit=1,sort=nearest] run function gm4_monsters_unbound:mob/process/elite/zephyr/charge_complete
+
+effect give @s slowness 1 3 true
+effect give @s nausea 4 0 false
+summon breeze_wind_charge ~ ~ ~ {Motion:[0.0d,-1.0d,0.0d]}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/slowing_attack.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/slowing_attack.mcfunction
new file mode 100644
index 0000000000..28fdb9afde
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/slowing_attack.mcfunction
@@ -0,0 +1,7 @@
+# slow players hit with slowing attack
+# @s = player that was hit
+# at unspecified
+advancement revoke @s only gm4_monsters_unbound:damaged/attack_effect/slowing
+
+scoreboard players set $freeze_seconds gm4_mu_data 3
+function gm4_monsters_unbound:effect/freeze/apply_chill
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/toxic_attack.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/toxic_attack.mcfunction
new file mode 100644
index 0000000000..6a125ce058
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/toxic_attack.mcfunction
@@ -0,0 +1,13 @@
+# weakness and hunger players hit with a toxic attack
+# @s = player that was hit
+# at unspecified
+advancement revoke @s only gm4_monsters_unbound:damaged/attack_effect/toxic
+
+# scale effect with world difficulty (on easy no effect is applied)
+execute store result score $worlddiff gm4_mu_data run difficulty
+
+execute if score $worlddiff gm4_mu_data matches 2 run effect give @s[tag=!gm4_mu_immune_weakness] weakness 2 0
+execute if score $worlddiff gm4_mu_data matches 3 run effect give @s[tag=!gm4_mu_immune_weakness] weakness 4 0
+
+execute if score $worlddiff gm4_mu_data matches 2 run effect give @s[tag=!gm4_mu_immune_hunger] hunger 2 2
+execute if score $worlddiff gm4_mu_data matches 3 run effect give @s[tag=!gm4_mu_immune_hunger] hunger 4 2
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/weakness_attack.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/weakness_attack.mcfunction
new file mode 100644
index 0000000000..127daa5132
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/attack_effect/weakness_attack.mcfunction
@@ -0,0 +1,7 @@
+# weaken players hit with weakness attack
+# @s = player that was hit
+# at unspecified
+advancement revoke @s only gm4_monsters_unbound:damaged/attack_effect/weakness
+
+effect give @s[tag=!gm4_mu_immune_weakness] weakness 15 0
+effect give @s[tag=!gm4_mu_immune_hunger] hunger 15 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/cloaked_creeper.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/cloaked_creeper.mcfunction
new file mode 100644
index 0000000000..be16326c19
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/cloaked_creeper.mcfunction
@@ -0,0 +1,7 @@
+# uncloak creeper if a player is nearby
+# @s = cloaked creeper
+# at @s
+# run from main
+
+effect clear @s invisibility
+tag @s remove gm4_mu_cloaked_creeper
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_damage.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_damage.mcfunction
new file mode 100644
index 0000000000..9ecce0cf5f
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_damage.mcfunction
@@ -0,0 +1,12 @@
+# damage player hit by flare
+# @s = player
+# at near @s
+# run from mob/process/elite/blazing/flare_explode
+
+execute store result score $showDeathMessages gm4_mu_data run gamerule showDeathMessages
+gamerule showDeathMessages false
+damage @s 5 explosion
+tag @s add gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 at @s unless entity @e[type=player,tag=gm4_mu_self,distance=..0.1,limit=1] run tellraw @a ["",{"translate":"text.gm4.monsters_unbound.death.blazing_elite_flare","fallback":"%s was blown up by a Blazing Flare",with:[{"selector":"@s"}]}]
+tag @s remove gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 run gamerule showDeathMessages true
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_explode.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_explode.mcfunction
new file mode 100644
index 0000000000..db0aaa7001
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/flare_explode.mcfunction
@@ -0,0 +1,17 @@
+# explode the flare
+# @s = flare block_display
+# at @s
+# run from mob/process/elite/blazing/process_flare
+
+particle flame ~ ~ ~ 0.01 0.01 0.01 0.1 32
+particle explosion ~ ~ ~ 0 0 0 40 0
+
+playsound entity.generic.explode hostile @a ~ ~ ~ 1 1.4
+playsound item.firecharge.use hostile @a ~ ~ ~ 1 0.7
+
+# hit players
+tag @s add gm4_mu_self
+execute positioned ~-.22 ~-.22 ~-.22 as @a[dx=0,dy=0,dz=0] positioned ~-0.34 ~-0.34 ~-0.34 as @s[dx=0,dy=0,dz=0] run function gm4_monsters_unbound:mob/process/elite/blazing/flare_damage
+tag @s remove gm4_mu_self
+
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/init_flare.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/init_flare.mcfunction
new file mode 100644
index 0000000000..67824c990a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/init_flare.mcfunction
@@ -0,0 +1,13 @@
+# init flare block_display
+# @s = flare block_display
+# at @s
+# run from mob/process/elite/blazing/process
+
+data merge entity @s {Tags:["gm4_mu_elite_flare"],teleport_duration:1,brightness:{sky:15,block:15},transformation:{left_rotation:[0f,0f,0f,1f],right_rotation:[0f,0f,0f,1f],translation:[-0.125f,-0.125f,-0.125f],scale:[0.25f,0.25f,0.25f]},block_state:{Name:"minecraft:magma_block"}}
+
+playsound minecraft:entity.blaze.shoot hostile @a ~ ~ ~ 1 1.2
+
+tp @s ~ ~ ~ ~ ~
+scoreboard players set @s gm4_mu_data 0
+
+execute unless score $keep_tick.elite_process_flare gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/blazing_flare 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process.mcfunction
new file mode 100644
index 0000000000..6915844a73
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process.mcfunction
@@ -0,0 +1,14 @@
+# process blazing elite
+# @s = blazing elite
+# at @s
+# run from mob/process/elite/check_type
+
+scoreboard players set $has_target gm4_mu_data 0
+execute on target if entity @s[type=player] run scoreboard players set $has_target gm4_mu_data 1
+execute if score $has_target gm4_mu_data matches 1 run scoreboard players add @s gm4_mu_timer 1
+execute if score $has_target gm4_mu_data matches 0 run scoreboard players set @s[scores={gm4_mu_timer=3..5}] gm4_mu_timer 6
+scoreboard players set @s[scores={gm4_mu_timer=10..}] gm4_mu_timer 0
+
+execute if score @s gm4_mu_timer matches 3 anchored eyes positioned ^ ^-0.25 ^ on target facing entity @s eyes rotated ~ -75 summon block_display run function gm4_monsters_unbound:mob/process/elite/blazing/init_flare
+execute if score @s[type=#gm4_survival_refightalized:zombie_types] gm4_mu_timer matches 4 anchored eyes positioned ^ ^-0.25 ^ on target facing entity @s eyes rotated ~90 -75 summon block_display run function gm4_monsters_unbound:mob/process/elite/blazing/init_flare
+execute if score @s[type=#gm4_survival_refightalized:zombie_types] gm4_mu_timer matches 5 anchored eyes positioned ^ ^-0.25 ^ on target facing entity @s eyes rotated ~-90 -75 summon block_display run function gm4_monsters_unbound:mob/process/elite/blazing/init_flare
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process_flare.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process_flare.mcfunction
new file mode 100644
index 0000000000..61fcad268e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/blazing/process_flare.mcfunction
@@ -0,0 +1,29 @@
+# process the flare
+# @s = flare block_display
+# at @s
+# run from clocks/elite/blazing_flare
+
+# particles
+particle flame ^ ^ ^0.0125 0.12 0.12 0.12 0.015 2
+
+# track towards closest player until nearby, then fly off
+execute if score @s gm4_mu_data matches 0 positioned ^ ^ ^0.7 if entity @p[gamemode=!spectator,gamemode=!creative,distance=..2] run scoreboard players set @s gm4_mu_data 1
+execute if score @s[scores={gm4_mu_data=0}] gm4_mu_timer matches ..60 facing entity @p[gamemode=!spectator,gamemode=!creative] eyes positioned ^ ^ ^50 rotated as @s positioned ^ ^ ^500 facing entity @s eyes facing ^ ^ ^-1 positioned as @s run tp @s ~ ~ ~ ~ ~
+tp @s[scores={gm4_mu_timer=..10}] ^ ^ ^0.35
+tp @s[scores={gm4_mu_timer=11..60}] ^ ^ ^0.25
+tp @s[scores={gm4_mu_timer=61..70}] ^ ^ ^0.15
+tp @s[scores={gm4_mu_timer=71..}] ^ ^ ^0.05
+
+scoreboard players set $flare_hit gm4_mu_data 0
+# hit players
+execute positioned ~-.15 ~-.15 ~-.15 as @a[dx=0,dy=0,dz=0] positioned ~-0.55 ~-0.55 ~-0.55 if entity @s[dx=0,dy=0,dz=0] run scoreboard players set $flare_hit gm4_mu_data 1
+# hit terrain
+execute unless block ~ ~ ~ #gm4:no_collision run scoreboard players set $flare_hit gm4_mu_data 1
+# timer ran out
+scoreboard players add @s gm4_mu_timer 1
+execute if score @s gm4_mu_timer matches 80.. run scoreboard players set $flare_hit gm4_mu_data 1
+# explode when something is hit
+execute if score $flare_hit gm4_mu_data matches 1 run return run function gm4_monsters_unbound:mob/process/elite/blazing/flare_explode
+
+# keep running
+scoreboard players set $keep_tick.elite_process_flare gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/check_type.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/check_type.mcfunction
new file mode 100644
index 0000000000..d269062297
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/check_type.mcfunction
@@ -0,0 +1,12 @@
+# process elites
+# @s = elite mob
+# at @s
+# run from main
+
+execute if entity @s[tag=gm4_mu_elite.mending] run function gm4_monsters_unbound:mob/process/elite/mending/process
+execute if entity @s[tag=gm4_mu_elite.blazing] run function gm4_monsters_unbound:mob/process/elite/blazing/process
+execute if entity @s[tag=gm4_mu_elite.zephyr] run function gm4_monsters_unbound:mob/process/elite/zephyr/process
+execute if entity @s[tag=gm4_mu_elite.gargantuan] run function gm4_monsters_unbound:mob/process/elite/gargantuan/process
+execute if entity @s[tag=gm4_mu_elite.pearlescent] run function gm4_monsters_unbound:mob/process/elite/pearlescent/process
+execute if entity @s[tag=gm4_mu_elite.splitting] run function gm4_monsters_unbound:mob/process/elite/splitting/process
+execute if entity @s[tag=gm4_mu_elite.volatile] run function gm4_monsters_unbound:mob/process/elite/volatile/process
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/activate.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/activate.mcfunction
new file mode 100644
index 0000000000..9c771df3e5
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/activate.mcfunction
@@ -0,0 +1,21 @@
+# activate gargantuan elite ground slam
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/check_type
+
+attribute @s minecraft:follow_range modifier remove gm4_monsters_unbound:elite_buff.giant.charging
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.giant.charging
+playsound minecraft:entity.zombie.attack_wooden_door hostile @a ~ ~ ~ 1.25 0
+
+execute store result storage gm4_monsters_unbound:temp deal.damage float 1.75 run attribute @s minecraft:attack_damage get
+
+tag @s add gm4_mu_self
+execute as @a[distance=..7,gamemode=!spectator] run function gm4_monsters_unbound:mob/process/elite/gargantuan/player_hit with storage gm4_monsters_unbound:temp deal
+tag @s remove gm4_mu_self
+
+data remove storage gm4_monsters_unbound:temp deal
+
+scoreboard players set $particle_ring gm4_mu_data 72
+execute rotated 0 0 run function gm4_monsters_unbound:mob/process/elite/gargantuan/particle_ring_big
+
+scoreboard players set @s gm4_mu_timer -6
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/eval_stats.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/eval_stats.mcfunction
new file mode 100644
index 0000000000..cd0cf370e5
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/eval_stats.mcfunction
@@ -0,0 +1,8 @@
+# set gargantuan elite stats
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/gargantuan/update_stats
+
+$attribute @s movement_speed modifier add gm4_monsters_unbound:elite_buff.giant.health_reduction_stats $(speed) add_multiplied_total
+$attribute @s attack_damage modifier add gm4_monsters_unbound:elite_buff.giant.health_reduction_stats $(damage) add_multiplied_total
+$attribute @s knockback_resistance modifier add gm4_monsters_unbound:elite_buff.giant.health_reduction_stats $(knockback_resistance) add_value
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring.mcfunction
new file mode 100644
index 0000000000..33db3ab60b
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring.mcfunction
@@ -0,0 +1,12 @@
+# show a particle ring for gargantuan elite ground slam
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/gargantuan/process
+# run from here
+
+particle block{block_state:"chest"} ^ ^0.2 ^7 0.15 0.15 0.15 0.5 2
+particle block{block_state:"chest"} ^ ^0.4 ^7 0.15 0.15 0.15 0.5 2
+particle block{block_state:"chest"} ^ ^0.6 ^7 0.15 0.15 0.15 0.5 2
+
+scoreboard players remove $particle_ring gm4_mu_data 1
+execute if score $particle_ring gm4_mu_data matches 1.. rotated ~5 ~ run function gm4_monsters_unbound:mob/process/elite/gargantuan/particle_ring
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring_big.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring_big.mcfunction
new file mode 100644
index 0000000000..d56ceab7c0
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/particle_ring_big.mcfunction
@@ -0,0 +1,14 @@
+# show a particle ring for gargantuan elite ground slam
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/activate
+# run from run
+
+particle block{block_state:"chest"} ^ ^ ^7 0.225 0.225 0.225 1 5
+particle block{block_state:"chest"} ^ ^0.2 ^7 0.225 0.225 0.225 1 5
+particle block{block_state:"chest"} ^ ^0.4 ^7 0.225 0.225 0.225 1 5
+particle block{block_state:"chest"} ^ ^0.6 ^7 0.225 0.225 0.225 1 5
+particle block{block_state:"chest"} ^ ^0.8 ^7 0.225 0.225 0.225 1 5
+
+scoreboard players remove $particle_ring gm4_mu_data 1
+execute if score $particle_ring gm4_mu_data matches 1.. rotated ~5 ~ run function gm4_monsters_unbound:mob/process/elite/gargantuan/particle_ring_big
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/player_hit.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/player_hit.mcfunction
new file mode 100644
index 0000000000..0b4c773fdb
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/player_hit.mcfunction
@@ -0,0 +1,10 @@
+# damage player from gargantuan ground slam
+# @s = player that got hit
+# at @s
+# run from mob/process/elite/gargantuan/activate
+
+particle block{block_state:"chest"} ~ ~1.2 ~ 0.325 0.925 0.325 1 12
+
+$damage @s $(damage) mob_attack by @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_self,limit=1,distance=..7]
+effect give @s slowness 3 3
+effect give @s nausea 5 0
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/process.mcfunction
new file mode 100644
index 0000000000..437b130084
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/process.mcfunction
@@ -0,0 +1,30 @@
+# process gargantuan elite
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/check_type
+
+# check health
+execute store result score $curr_health gm4_mu_data run data get entity @s Health 1000
+execute unless score $curr_health gm4_mu_data = @s gm4_mu_data run function gm4_monsters_unbound:mob/process/elite/gargantuan/update_stats
+
+# no nearby players
+execute unless score @s gm4_mu_timer matches 1.. unless entity @a[gamemode=!spectator,distance=..7] run return 0
+# otherwise 40% chance to start attack (60% to return and not use it)
+execute unless score @s gm4_mu_timer matches 1.. if entity @a[gamemode=!spectator,distance=..7] if predicate {condition:"minecraft:random_chance",chance:0.6} run return 0
+
+scoreboard players add @s gm4_mu_timer 1
+scoreboard players set @s[scores={gm4_mu_timer=20..}] gm4_mu_timer 0
+
+scoreboard players set $particle_ring gm4_mu_data 72
+execute if score @s gm4_mu_timer matches 2..4 rotated 0 0 run function gm4_monsters_unbound:mob/process/elite/gargantuan/particle_ring
+
+attribute @s[scores={gm4_mu_timer=1}] minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.giant.charging -1 add_multiplied_total
+attribute @s[scores={gm4_mu_timer=1}] minecraft:follow_range modifier add gm4_monsters_unbound:elite_buff.giant.charging -1 add_multiplied_total
+
+execute if score @s gm4_mu_timer matches 2 run playsound minecraft:entity.zombie.attack_wooden_door hostile @a ~ ~ ~ 1 1.2
+execute if score @s gm4_mu_timer matches 3 run playsound minecraft:entity.zombie.attack_wooden_door hostile @a ~ ~ ~ 1 1.4
+execute if score @s gm4_mu_timer matches 4 run playsound minecraft:entity.zombie.attack_wooden_door hostile @a ~ ~ ~ 1 1.7
+
+data modify entity @s[scores={gm4_mu_timer=4}] Motion set value [0d,0.5d,0d]
+
+execute if score @s gm4_mu_timer matches 5 run function gm4_monsters_unbound:mob/process/elite/gargantuan/activate
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/update_stats.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/update_stats.mcfunction
new file mode 100644
index 0000000000..6a343dffd3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/gargantuan/update_stats.mcfunction
@@ -0,0 +1,26 @@
+# update gargantuan elite stats
+# @s = gargantuan elite
+# at @s
+# run from mob/process/elite/gargantuan/process
+
+scoreboard players operation @s gm4_mu_data = $curr_health gm4_mu_data
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.giant.health_reduction_stats
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:elite_buff.giant.health_reduction_stats
+attribute @s minecraft:knockback_resistance modifier remove gm4_monsters_unbound:elite_buff.giant.health_reduction_stats
+
+execute store result score $max_health gm4_mu_data run attribute @s minecraft:max_health get 10
+scoreboard players operation $curr_health gm4_mu_data /= $max_health gm4_mu_data
+scoreboard players set $curr_health_percent_lost gm4_mu_data 100
+scoreboard players operation $curr_health_percent_lost gm4_mu_data -= $curr_health gm4_mu_data
+
+execute if score $curr_health_percent_lost gm4_mu_data matches 50.. run effect give @s[type=!#gm4_survival_refightalized:skeleton_types] minecraft:resistance infinite 0 true
+execute if score $curr_health_percent_lost gm4_mu_data matches 75.. run effect give @s[type=!#gm4_survival_refightalized:skeleton_types] minecraft:resistance infinite 1 true
+
+execute if score $curr_health_percent_lost gm4_mu_data matches 50.. run scoreboard players set @s[type=#gm4_survival_refightalized:skeleton_types] gm4_sr_arrow.fire_delay 4
+execute if score $curr_health_percent_lost gm4_mu_data matches 75.. run scoreboard players set @s[type=#gm4_survival_refightalized:skeleton_types] gm4_sr_arrow.fire_delay 6
+
+execute store result storage gm4_monsters_unbound:temp set.speed float 0.015 run scoreboard players get $curr_health_percent_lost gm4_mu_data
+execute store result storage gm4_monsters_unbound:temp set.damage float 0.005 run scoreboard players get $curr_health_percent_lost gm4_mu_data
+execute store result storage gm4_monsters_unbound:temp set.knockback_resistance float 0.0015 run scoreboard players add $curr_health_percent_lost gm4_mu_data 567
+function gm4_monsters_unbound:mob/process/elite/gargantuan/eval_stats with storage gm4_monsters_unbound:temp set
+data remove storage gm4_monsters_unbound:temp set
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/death.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/death.mcfunction
new file mode 100644
index 0000000000..05cbd81089
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/death.mcfunction
@@ -0,0 +1,7 @@
+# run on glacial elite death
+# @s = glacial elite
+# at @s
+# run from mob/process/elite/on_death/run
+
+summon marker ~ ~-1 ~ {Tags:["gm4_mu_elite_death_marker","gm4_mu_elite.glacial_processing"]}
+execute unless score $keep_tick.elite_glacial_death gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/glacial_death 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/explode.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/explode.mcfunction
new file mode 100644
index 0000000000..9aff6f8845
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/explode.mcfunction
@@ -0,0 +1,11 @@
+# explode the glacial bomb
+# @s = glacial elite death marker
+# at @s
+# run from mob/process/elite/glacial/process_explosion
+
+scoreboard players set $freeze_seconds gm4_mu_data 3
+execute as @e[distance=..4.81,type=!#gm4:non_living,tag=!smithed.entity,tag=!smithed.strict] run function gm4_monsters_unbound:effect/freeze/apply
+execute as @a[gamemode=!spectator,distance=..12] facing entity @s eyes positioned ^ ^ ^4.5 positioned ~-.05 ~-.05 ~-.05 if entity @s[dx=0,dy=0,dz=0] positioned ~-0.9 ~-0.9 ~-0.9 if entity @s[dx=0,dy=0,dz=0] run function gm4_monsters_unbound:effect/freeze/apply
+playsound block.glass.break hostile @a[distance=..4.81] ~ ~ ~ 1 0.8
+
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/process_explosion.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/process_explosion.mcfunction
new file mode 100644
index 0000000000..39692cb8d3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/process_explosion.mcfunction
@@ -0,0 +1,20 @@
+# process the glacial bomb
+# @s = glacial elite death marker
+# at @s
+# run from clocks/elite/glacial_death
+
+# before show warning
+particle dust{color:[0.725,0.910,0.918],scale:3} ~ ~ ~ 0.04 0.04 0.04 0 4 normal
+particle snowflake ~ ~ ~ 1.75 1.75 1.75 0 7 normal
+scoreboard players set $frost_ring_yaw gm4_mu_data 0
+execute if score @s gm4_mu_data matches ..360 rotated 0 80 run function gm4_monsters_unbound:mob/process/elite/glacial/warning_yaw_loop
+
+# explode after 2 seconds
+scoreboard players add @s gm4_mu_data 20
+
+playsound minecraft:block.snow.break hostile @a[distance=..4.81] ~ ~ ~ 1.55 1.2
+playsound minecraft:block.snow.fall hostile @a[distance=..4.81] ~ ~ ~ 2 0.75
+playsound minecraft:block.snow.fall hostile @a[distance=4.81..16] ~ ~ ~ 1 0.6
+
+execute if score @s gm4_mu_data matches 400.. run return run function gm4_monsters_unbound:mob/process/elite/glacial/explode
+scoreboard players set $keep_tick.elite_glacial_death gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_big.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_big.mcfunction
new file mode 100644
index 0000000000..8c2994eda7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_big.mcfunction
@@ -0,0 +1,9 @@
+# show warning particles
+# @s = glacial elite death marker
+# at @s
+# run from mob/process/elite/glacial/warning_yaw_loop
+# run from here
+
+particle dust{color:[0.725,0.910,0.918],scale:2} ^ ^ ^4.8 0.02 0.02 0.02 0 1 normal
+scoreboard players remove $frost_ring_pitch gm4_mu_data 5
+execute if score $frost_ring_pitch gm4_mu_data matches -85.. rotated ~5 ~-5 run function gm4_monsters_unbound:mob/process/elite/glacial/warning_pitch_loop_big
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_small.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_small.mcfunction
new file mode 100644
index 0000000000..db59de0c89
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_pitch_loop_small.mcfunction
@@ -0,0 +1,9 @@
+# show warning particles
+# @s = glacial elite death marker
+# at @s
+# run from mob/process/elite/glacial/warning_yaw_loop
+# run from here
+
+execute if predicate {condition:"minecraft:random_chance",chance:0.15} run particle snowflake ^ ^ ^4.8 0.005 0.005 0.005 0 1 normal
+scoreboard players remove $frost_ring_pitch gm4_mu_data 5
+execute if score $frost_ring_pitch gm4_mu_data matches -85.. rotated ~5 ~-5 run function gm4_monsters_unbound:mob/process/elite/glacial/warning_pitch_loop_small
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_yaw_loop.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_yaw_loop.mcfunction
new file mode 100644
index 0000000000..14d30955d7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/glacial/warning_yaw_loop.mcfunction
@@ -0,0 +1,12 @@
+# show warning particles
+# @s = glacial elite death marker
+# at @s
+# run from mob/process/elite/glacial/process_explosion
+# run from here
+
+scoreboard players set $frost_ring_pitch gm4_mu_data 80
+execute if score $frost_ring_yaw gm4_mu_data < @s gm4_mu_data run function gm4_monsters_unbound:mob/process/elite/glacial/warning_pitch_loop_big
+execute unless score $frost_ring_yaw gm4_mu_data < @s gm4_mu_data run function gm4_monsters_unbound:mob/process/elite/glacial/warning_pitch_loop_small
+
+scoreboard players add $frost_ring_yaw gm4_mu_data 10
+execute if score $frost_ring_yaw gm4_mu_data matches ..360 rotated ~10 ~ run function gm4_monsters_unbound:mob/process/elite/glacial/warning_yaw_loop
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_los_raycast.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_los_raycast.mcfunction
new file mode 100644
index 0000000000..55e49c314d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_los_raycast.mcfunction
@@ -0,0 +1,17 @@
+# check LOS to this undead
+# @s = undead near mending elite
+# at @s
+# run from mob/process/elite/mending/process
+# run from here
+
+execute if score $target_healed gm4_mu_data matches 1.. run return 0
+
+tag @s remove gm4_mu_target
+
+scoreboard players add $raycast_travel_distance gm4_mu_data 3
+
+execute positioned ~-.05 ~-.05 ~-.05 if entity @s[dx=0,dy=0,dz=0] positioned ~-0.9 ~-0.9 ~-0.9 if entity @s[dx=0,dy=0,dz=0] at @s anchored eyes positioned ^ ^ ^ run function gm4_monsters_unbound:mob/process/elite/mending/trigger
+execute if score $target_healed gm4_mu_data matches 1.. run return run function gm4_monsters_unbound:mob/process/elite/mending/particle_raycast
+
+execute unless score $raycast_travel_distance gm4_mu_data matches ..300 run return run scoreboard players reset $raycast_travel_distance gm4_mu_data
+execute positioned ^ ^ ^.3 if block ~ ~ ~ #gm4:no_collision run function gm4_monsters_unbound:mob/process/elite/mending/check_los_raycast
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_target.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_target.mcfunction
new file mode 100644
index 0000000000..54dab0688e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/check_target.mcfunction
@@ -0,0 +1,10 @@
+# check if this entity is a valid target to be healed
+# @s = undead near mending elite
+# at @s
+# run from mob/process/elite/mending/process
+
+execute store result score $curr_health gm4_mu_data run data get entity @s Health 10
+execute store result score $max_health gm4_mu_data run attribute @s minecraft:max_health get 10
+# remove a slight amount from max_health to fix floating point errors
+scoreboard players remove $max_health gm4_mu_data 2
+execute if score $curr_health gm4_mu_data < $max_health gm4_mu_data run tag @s add gm4_mu_target
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/particle_raycast.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/particle_raycast.mcfunction
new file mode 100644
index 0000000000..2a3b5f3a81
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/particle_raycast.mcfunction
@@ -0,0 +1,13 @@
+# check LOS to this undead
+# @s = undead near mending elite
+# at @s
+# run from mob/process/elite/mending/process
+# run from here
+
+scoreboard players remove $raycast_travel_distance gm4_mu_data 1
+
+particle dust_color_transition{from_color:[0.000,1.000,0.000],scale:0.65,to_color:[0.000,0.000,0.000]} ~ ~ ~ 0.1 0.1 0.1 0 0
+
+execute unless score $raycast_travel_distance gm4_mu_data matches 1.. run particle dust_color_transition{from_color:[0.000,1.000,0.000],scale:0.85,to_color:[0.000,0.000,0.000]} ~ ~ ~ 0.22 0.22 0.22 0.5 12
+
+execute if score $raycast_travel_distance gm4_mu_data matches 1.. positioned ^ ^ ^-.1 run function gm4_monsters_unbound:mob/process/elite/mending/particle_raycast
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/process.mcfunction
new file mode 100644
index 0000000000..b97ec47608
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/process.mcfunction
@@ -0,0 +1,11 @@
+# process mending elite
+# @s = mending elite
+# at @s
+# run from mob/process/elite/check_type
+
+execute as @e[type=#minecraft:undead,tag=!gm4_mu_elite.mending,distance=..30,limit=12,sort=random] run function gm4_monsters_unbound:mob/process/elite/mending/check_target
+
+tag @s add gm4_mu_self
+scoreboard players set $target_healed gm4_mu_data 0
+execute at @s anchored eyes positioned ^ ^0.4375 ^ as @e[type=#minecraft:undead,tag=gm4_mu_target,distance=..30,sort=random] facing entity @s eyes run function gm4_monsters_unbound:mob/process/elite/mending/check_los_raycast
+tag @s remove gm4_mu_self
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/trigger.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/trigger.mcfunction
new file mode 100644
index 0000000000..81d1675053
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/mending/trigger.mcfunction
@@ -0,0 +1,12 @@
+# heal this undead
+# @s = undead near mending elite
+# at @s
+# run from mob/process/elite/mending/check_los_raycast
+
+scoreboard players set $target_healed gm4_mu_data 1
+
+effect give @s instant_damage 1 2 false
+effect give @s resistance 1 1 false
+particle heart ^ ^ ^ 0.2 0.2 0.2 0.05 1
+
+playsound minecraft:item.bottle.fill hostile @a ~ ~ ~ 0.7 2
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_death/run.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_death/run.mcfunction
new file mode 100644
index 0000000000..ad481af2d2
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_death/run.mcfunction
@@ -0,0 +1,13 @@
+# check which elite has died
+# @s = item dropped from killed elite
+# at @s
+# run from check_item
+
+execute store result score $elite_type gm4_mu_data run data get entity @s Item.components."minecraft:custom_data".gm4_mu_elite_on_death.id
+execute if score $elite_type gm4_mu_data matches 1 run function gm4_monsters_unbound:mob/process/elite/glacial/death
+execute if score $elite_type gm4_mu_data matches 2 positioned ~ ~1.75 ~ summon item_display run function gm4_monsters_unbound:mob/process/elite/vorpal/init_fear_cloud
+execute if score $elite_type gm4_mu_data matches 3 positioned ~ ~0.25 ~ run function gm4_monsters_unbound:mob/process/elite/splitting/zombie
+execute if score $elite_type gm4_mu_data matches 4 positioned ~ ~0.25 ~ run function gm4_monsters_unbound:mob/process/elite/splitting/skeleton
+execute if score $elite_type gm4_mu_data matches 5 run function gm4_monsters_unbound:mob/process/elite/volatile/death
+
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/check_mob.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/check_mob.mcfunction
new file mode 100644
index 0000000000..301b173396
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/check_mob.mcfunction
@@ -0,0 +1,7 @@
+# process elite that got hit
+# @s = elite that got hit
+# at @s
+# run from mob/process/elite/on_hit/run
+
+execute if entity @s[tag=gm4_mu_elite.vorpal] if predicate {condition:"minecraft:random_chance",chance:0.65} run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/run
+execute if entity @s[tag=gm4_mu_elite.zephyr] run function gm4_monsters_unbound:mob/process/elite/zephyr/hit_when_charging
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/run.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/run.mcfunction
new file mode 100644
index 0000000000..a349877f35
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/on_hit/run.mcfunction
@@ -0,0 +1,6 @@
+# process elites being hit
+# @s = player that hit an elite
+# at @s
+advancement revoke @s only gm4_monsters_unbound:elite/on_hit
+
+execute as @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_elite.on_hit,nbt={HurtTime:10s},limit=1,sort=nearest] at @s run function gm4_monsters_unbound:mob/process/elite/on_hit/check_mob
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/get_facing.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/get_facing.mcfunction
new file mode 100644
index 0000000000..7e96ce2612
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/get_facing.mcfunction
@@ -0,0 +1,8 @@
+# get facing direction towards target
+# @s = marker
+# at elite anchored eyes positioned ^ ^ ^0.2
+# run from mob/process/elite/pearlescent/laser
+
+tp @s ~ ~ ~ facing entity @p[tag=gm4_mu_target] eyes
+data modify storage gm4_monsters_unbound:temp Rotation set from entity @s Rotation
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser.mcfunction
new file mode 100644
index 0000000000..93eccd1741
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser.mcfunction
@@ -0,0 +1,21 @@
+# shoot laser
+# @s = pearlescent elite
+# at @s
+# run from mob/process/elite/pearlescent/process
+
+playsound block.campfire.crackle hostile @a ~ ~ ~ 0.5 0.8
+particle flash ~ ~1.8 ~
+
+execute on target run tag @s[type=player] add gm4_mu_target
+execute unless entity @p[tag=gm4_mu_target] run return 0
+tag @s add gm4_mu_self
+
+scoreboard players set $laser_limit gm4_mu_data 150
+
+execute anchored eyes positioned ^ ^ ^0.2 summon marker run function gm4_monsters_unbound:mob/process/elite/pearlescent/get_facing
+data modify entity @s Rotation set from storage gm4_monsters_unbound:temp Rotation
+data remove storage gm4_monsters_unbound:temp Rotation
+execute at @s anchored eyes positioned ^ ^ ^0.2 run function gm4_monsters_unbound:mob/process/elite/pearlescent/laser_raycast
+
+execute on target run tag @s remove gm4_mu_target
+tag @s remove gm4_mu_self
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_damage.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_damage.mcfunction
new file mode 100644
index 0000000000..6c12498e2c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_damage.mcfunction
@@ -0,0 +1,15 @@
+# deal damage to hit player
+# @s = player hit by laser
+# at near @s
+# run from mob/process/elite/pearlescent/laser_raycast
+
+scoreboard players set $attack_hit gm4_mu_data 1
+scoreboard players set $laser_limit gm4_mu_data 0
+
+execute store result score $showDeathMessages gm4_mu_data run gamerule showDeathMessages
+gamerule showDeathMessages false
+damage @s 1.0 in_fire
+tag @s add gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 at @s unless entity @e[type=player,tag=gm4_mu_self,distance=..0.1,limit=1] run tellraw @a ["",{"translate":"text.gm4.monsters_unbound.death.pearlescent_elite_laser","fallback":"%s was seen by %s",with:[{"selector":"@s"},{"selector":"@e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_elite.pearlescent,distance=..32,limit=1]"}]}]
+tag @s remove gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 run gamerule showDeathMessages true
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_raycast.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_raycast.mcfunction
new file mode 100644
index 0000000000..8829a06a04
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/laser_raycast.mcfunction
@@ -0,0 +1,16 @@
+# raycast to target player
+# @s = pearlescent elite
+# at @s
+# run from mob/process/elite/pearlescent/laser
+# run from here
+
+particle dust_color_transition{from_color:[0.400,0.325,0.450],to_color:[0.800,0.650,0.900],scale:1.25} ^0.125 ^ ^ 0.01 0.01 0.01 0 1
+particle dust_color_transition{from_color:[0.400,0.325,0.450],to_color:[0.800,0.650,0.900],scale:1.25} ^-0.125 ^ ^ 0.01 0.01 0.01 0 1
+
+particle dust_color_transition{from_color:[0.400,0.325,0.450],to_color:[0.800,0.650,0.900],scale:1.25} ^0.125 ^ ^0.1 0.01 0.01 0.01 0 1
+particle dust_color_transition{from_color:[0.400,0.325,0.450],to_color:[0.800,0.650,0.900],scale:1.25} ^-0.125 ^ ^0.1 0.01 0.01 0.01 0 1
+
+execute positioned ~-0.1 ~-0.1 ~-0.1 as @a[gamemode=!spectator,dx=0,dy=0,dz=0] positioned ~-0.8 ~-0.8 ~-0.8 if entity @s[dx=0,dy=0,dz=0] run function gm4_monsters_unbound:mob/process/elite/pearlescent/laser_damage
+
+scoreboard players remove $laser_limit gm4_mu_data 1
+execute if score $laser_limit gm4_mu_data matches 1.. positioned ^ ^ ^0.2 if block ~ ~ ~ #gm4:no_collision run function gm4_monsters_unbound:mob/process/elite/pearlescent/laser_raycast
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/process.mcfunction
new file mode 100644
index 0000000000..cc84f96af7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/pearlescent/process.mcfunction
@@ -0,0 +1,27 @@
+# process pearlescent elite
+# @s = pearlescent elite
+# at @s
+# run from mob/process/elite/check_type
+
+# 33% chance to start attack if mob has a target
+scoreboard players set $attack gm4_mu_data 0
+execute if score @s gm4_mu_timer matches 1.. run scoreboard players set $attack gm4_mu_data 1
+execute unless score $attack gm4_mu_data matches 1 on target if entity @s[type=player] if predicate {condition:"minecraft:random_chance",chance:0.33} run scoreboard players set $attack gm4_mu_data 1
+execute if score $attack gm4_mu_data matches 0 run return 0
+
+scoreboard players add @s gm4_mu_timer 1
+scoreboard players set @s[scores={gm4_mu_timer=300..}] gm4_mu_timer 0
+
+execute if score @s gm4_mu_timer matches 1 run playsound block.beacon.activate hostile @a ~ ~ ~ 1 0.7
+execute if score @s gm4_mu_timer matches 101..110 run playsound block.beacon.deactivate hostile @a ~ ~ ~ 1 0.7
+
+attribute @s[scores={gm4_mu_timer=1}] minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.pearlescent.charging -0.75 add_multiplied_total
+attribute @s[scores={gm4_mu_timer=5}] minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.pearlescent.charging
+attribute @s[scores={gm4_mu_timer=5}] minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.pearlescent.firing -0.33 add_multiplied_total
+attribute @s[scores={gm4_mu_timer=101..110}] minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.pearlescent.firing
+
+execute if score @s gm4_mu_timer matches ..100 run particle block{block_state:"pearlescent_froglight"} ~ ~2 ~ 0.3 0.3 0.3 0.5 8
+
+scoreboard players set $attack_hit gm4_mu_data 0
+execute if score @s gm4_mu_timer matches 5..100 run function gm4_monsters_unbound:mob/process/elite/pearlescent/laser
+execute if score @s gm4_mu_timer matches 10.. if score $attack_hit gm4_mu_data matches 0 run scoreboard players add @s gm4_mu_timer 10
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/init_entity.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/init_entity.mcfunction
new file mode 100644
index 0000000000..85c291eb60
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/init_entity.mcfunction
@@ -0,0 +1,35 @@
+# init split entity
+# @s = split entity
+# at @s
+# run from mob/process/elite/splitting/skeleton
+# run from mob/process/elite/splitting/zombie
+
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:gravity modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:jump_strength modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:knockback_resistance modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:max_health modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:scale modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:step_height modifier add gm4_monsters_unbound:split_entity -0.5 add_multiplied_total
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:split_entity 0.33 add_multiplied_total
+attribute @s[type=#gm4_survival_refightalized:skeleton_types] minecraft:follow_range modifier add gm4_monsters_unbound:split_entity -0.66 add_multiplied_total
+
+scoreboard players set @s gm4_sr_arrow.fire_delay 6
+scoreboard players set @s gm4_sr_arrow.damage_change -14
+
+data modify entity @s CustomName set from storage gm4_monsters_unbound:temp CustomName
+
+execute store result entity @s Motion[0] double 0.01 run random value -30..30
+execute store result entity @s Motion[1] double 0.01 run random value 20..60
+execute store result entity @s Motion[2] double 0.01 run random value -30..30
+
+tag @s add gm4_mu_elite.split_entity
+tag @s add gm4_mu_split_entity
+execute if dimension minecraft:overworld run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
+execute unless dimension minecraft:overworld run function gm4_survival_refightalized:mob/init/calc_difficulty_else
+
+item replace entity @s armor.head with spawner
+data modify entity @s drop_chances.head set value 0
+
+team join gm4_mu_elite.split
+execute if score $has_bow gm4_mu_data matches 0 run item replace entity @s[type=#gm4_survival_refightalized:skeleton_types] weapon.mainhand with wooden_sword
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/process.mcfunction
new file mode 100644
index 0000000000..519fcbae7e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/process.mcfunction
@@ -0,0 +1,6 @@
+# process splitting elite
+# @s = splitting elite
+# at @s
+# run from mob/process/elite/check_type
+
+data modify entity @s equipment.head.components."minecraft:custom_name" set from entity @s CustomName
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/skeleton.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/skeleton.mcfunction
new file mode 100644
index 0000000000..8ba096aa66
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/skeleton.mcfunction
@@ -0,0 +1,20 @@
+# split splitting elite on death
+# @s = item
+# at @s
+# run from mob/process/elite/on_death/run
+
+data modify storage gm4_monsters_unbound:temp CustomName set from entity @s Item.components."minecraft:custom_name"
+
+# only 2-3 of the spawned skeletons will have bows, the rest will be melee with wooden swords
+scoreboard players set $has_bow gm4_mu_data 1
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute store result score $has_bow gm4_mu_data run random value 0..1
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+scoreboard players set $has_bow gm4_mu_data 0
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon skeleton run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+
+data remove storage gm4_monsters_unbound:temp CustomName
+
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/zombie.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/zombie.mcfunction
new file mode 100644
index 0000000000..e14037d294
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/splitting/zombie.mcfunction
@@ -0,0 +1,15 @@
+# split splitting elite on death
+# @s = item
+# at @s
+# run from mob/process/elite/on_death/run
+
+data modify storage gm4_monsters_unbound:temp CustomName set from entity @s Item.components."minecraft:custom_name"
+
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+execute summon zombie run function gm4_monsters_unbound:mob/process/elite/splitting/init_entity
+
+data remove storage gm4_monsters_unbound:temp CustomName
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/death.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/death.mcfunction
new file mode 100644
index 0000000000..24e877ffe4
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/death.mcfunction
@@ -0,0 +1,9 @@
+# spawn many volatile pillars on death
+# @s = item
+# at @s
+# run from mob/process/elite/on_death/run
+
+execute positioned ~ ~ ~3 summon marker run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location
+execute positioned ~ ~ ~-3 summon marker run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location
+execute positioned ~3 ~ ~ summon marker run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location
+execute positioned ~-3 ~ ~ summon marker run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_damage.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_damage.mcfunction
new file mode 100644
index 0000000000..15f3e5a29d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_damage.mcfunction
@@ -0,0 +1,15 @@
+# damage from volatile pillar
+# @s = player that was hit
+# at near @s
+# run from mob/process/elite/volatile/pillar_explode
+
+effect give @s slowness 2 2
+effect give @s nausea 4 0
+
+execute store result score $showDeathMessages gm4_mu_data run gamerule showDeathMessages
+gamerule showDeathMessages false
+damage @s 9.0 explosion
+tag @s add gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 at @s unless entity @e[type=player,tag=gm4_mu_self,distance=..0.1,limit=1] run tellraw @a ["",{"translate":"text.gm4.monsters_unbound.death.volatile_elite_meteorite","fallback":"%s was struck by a meteorite",with:[{"selector":"@s"}]}]
+tag @s remove gm4_mu_self
+execute if score $showDeathMessages gm4_mu_data matches 1 run gamerule showDeathMessages true
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_explode.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_explode.mcfunction
new file mode 100644
index 0000000000..c5772e381a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_explode.mcfunction
@@ -0,0 +1,14 @@
+# explode volatile pillar
+# @s = pillar marker
+# at @s
+# run from mob/process/elite/volatile/pillar_process
+
+execute if score @s gm4_mu_data matches 2 as @a[gamemode=!spectator,distance=..2.25] run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_damage
+execute if score @s gm4_mu_data matches 3 as @a[gamemode=!spectator,distance=..2.5] run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_damage
+execute if score @s gm4_mu_data matches 4 as @a[gamemode=!spectator,distance=..2.75] run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_damage
+execute if score @s gm4_mu_data matches 5 as @a[gamemode=!spectator,distance=..3] run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_damage
+kill @s
+particle minecraft:dragon_breath ~ ~ ~ 0.2 0.2 0.2 0.33 64
+particle minecraft:dragon_breath ~ ~0.25 ~ 0.5 0.5 0.5 0 32
+particle minecraft:dragon_breath ~ ~5 ~ 0.2 8 0.2 1 32
+playsound entity.dragon_fireball.explode hostile @a[distance=..32] ~ ~ ~ 1 0.9 0.5
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location.mcfunction
new file mode 100644
index 0000000000..6d63ebe22c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location.mcfunction
@@ -0,0 +1,39 @@
+# get a location for volatile pillar
+# @s = pillar marker
+# at @s
+# run from mob/process/elite/volatile/process
+
+tag @s add gm4_mu_elite.volatile_pillar
+execute store result score @s gm4_mu_timer run random value 0..14
+execute store result score @s gm4_mu_data run random value 2..5
+scoreboard players operation @s gm4_mu_timer -= @s gm4_mu_data
+scoreboard players operation @s gm4_mu_timer -= @s gm4_mu_data
+
+execute store result score $randomX gm4_mu_data run random value 0..12
+execute store result score $randomZ gm4_mu_data run random value 0..12
+tp @s ~-6 ~ ~-6
+
+execute at @s if score $randomX gm4_mu_data matches 8.. run tp @s ~8 ~ ~
+execute if score $randomX gm4_mu_data matches 8.. run scoreboard players remove $randomX gm4_mu_data 8
+execute at @s if score $randomX gm4_mu_data matches 4.. run tp @s ~4 ~ ~
+execute if score $randomX gm4_mu_data matches 4.. run scoreboard players remove $randomX gm4_mu_data 4
+execute at @s if score $randomX gm4_mu_data matches 2.. run tp @s ~2 ~ ~
+execute if score $randomX gm4_mu_data matches 2.. run scoreboard players remove $randomX gm4_mu_data 2
+execute at @s if score $randomX gm4_mu_data matches 1.. run tp @s ~1 ~ ~
+execute if score $randomX gm4_mu_data matches 1.. run scoreboard players remove $randomX gm4_mu_data 1
+
+execute at @s if score $randomZ gm4_mu_data matches 8.. run tp @s ~ ~ ~8
+execute if score $randomZ gm4_mu_data matches 8.. run scoreboard players remove $randomZ gm4_mu_data 8
+execute at @s if score $randomZ gm4_mu_data matches 4.. run tp @s ~ ~ ~4
+execute if score $randomZ gm4_mu_data matches 4.. run scoreboard players remove $randomZ gm4_mu_data 4
+execute at @s if score $randomZ gm4_mu_data matches 2.. run tp @s ~ ~ ~2
+execute if score $randomZ gm4_mu_data matches 2.. run scoreboard players remove $randomZ gm4_mu_data 2
+execute at @s if score $randomZ gm4_mu_data matches 1.. run tp @s ~ ~ ~1
+execute if score $randomZ gm4_mu_data matches 1.. run scoreboard players remove $randomZ gm4_mu_data 1
+
+scoreboard players set $move_y_limit gm4_mu_data 12
+execute at @s store result score $location_found gm4_mu_data run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location_y
+execute if score $location_found gm4_mu_data matches 0 run return run kill @s
+
+execute unless score $keep_tick.elite_pillar_volatile gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/volatile_pillar 1t
+execute at @s run playsound minecraft:entity.ender_dragon.shoot hostile @a ~ ~ ~ 1 0.5
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location_y.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location_y.mcfunction
new file mode 100644
index 0000000000..81d674ffd3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_location_y.mcfunction
@@ -0,0 +1,12 @@
+# get a location for volatile pillar
+# @s = pillar marker
+# at @s
+# run from mob/process/elite/volatile/pillar_location
+# run from here
+
+execute if block ~ ~ ~ #gm4:no_collision unless block ~ ~-1 ~ #gm4:no_collision align y run return run tp @s ~ ~ ~
+
+scoreboard players remove $move_y_limit gm4_mu_data 1
+execute if score $move_y_limit gm4_mu_data matches 0 run return 0
+execute if block ~ ~ ~ #gm4:no_collision positioned ~ ~-1 ~ run return run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location_y
+execute positioned ~ ~1 ~ run return run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location_y
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_particle_ring.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_particle_ring.mcfunction
new file mode 100644
index 0000000000..733fc3ba48
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_particle_ring.mcfunction
@@ -0,0 +1,13 @@
+# volatile pillar particles
+# @s = pillar marker
+# at @s rotated ~x ~
+# run from clocks/elite/pillaer_process
+# run from here
+
+execute if score @s gm4_mu_data matches 2 run particle dust_color_transition{from_color:[0.667,0.000,0.667],scale:1,to_color:[0.000,0.000,0.000]} ^ ^ ^2.25 0 0 0 1 0 normal
+execute if score @s gm4_mu_data matches 3 run particle dust_color_transition{from_color:[0.667,0.000,0.667],scale:1,to_color:[0.000,0.000,0.000]} ^ ^ ^2.5 0 0 0 1 0 normal
+execute if score @s gm4_mu_data matches 4 run particle dust_color_transition{from_color:[0.667,0.000,0.667],scale:1,to_color:[0.000,0.000,0.000]} ^ ^ ^2.75 0 0 0 1 0 normal
+execute if score @s gm4_mu_data matches 5 run particle dust_color_transition{from_color:[0.667,0.000,0.667],scale:1,to_color:[0.000,0.000,0.000]} ^ ^ ^3 0 0 0 1 0 normal
+
+scoreboard players remove $particle_ring gm4_mu_data 6
+execute if score $particle_ring gm4_mu_data matches 1.. rotated ~6 ~ run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_particle_ring
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_process.mcfunction
new file mode 100644
index 0000000000..671d66ebec
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/pillar_process.mcfunction
@@ -0,0 +1,16 @@
+# process volatile pillar
+# @s = pillar marker
+# at @s
+# run from clocks/elite/volatile_pillar
+
+particle block{block_state:"purple_glazed_terracotta"} ~ ~5 ~ 0.2 8 0.2 1 32
+
+scoreboard players set $particle_ring gm4_mu_data 360
+function gm4_monsters_unbound:mob/process/elite/volatile/pillar_particle_ring
+
+scoreboard players add @s gm4_mu_timer 1
+
+execute if score @s gm4_mu_timer matches 60 run playsound minecraft:entity.breeze.inhale hostile @a ~ ~ ~ 2 2
+execute if score @s gm4_mu_timer matches 70.. run return run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_explode
+
+scoreboard players set $keep_tick.elite_pillar_volatile gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/process.mcfunction
new file mode 100644
index 0000000000..e2a66d0853
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/volatile/process.mcfunction
@@ -0,0 +1,15 @@
+# process volatile elite
+# @s = volatile elite
+# at @s
+# run from mob/process/elite/check_type
+
+scoreboard players set $has_target gm4_mu_data 0
+execute on target if entity @s[type=player] run scoreboard players set $has_target gm4_mu_data 1
+execute if score $has_target gm4_mu_data matches 0 run return 0
+
+scoreboard players add @s gm4_mu_timer 1
+execute if predicate {condition:"random_chance","chance":0.45} run scoreboard players add @s gm4_mu_timer 1
+
+execute if score @s gm4_mu_timer matches 8..12 run particle block{block_state:"purple_glazed_terracotta"} ~ ~2 ~ 0 4 0 0.25 32
+execute if score @s gm4_mu_timer matches 8..12 on target at @s summon marker run function gm4_monsters_unbound:mob/process/elite/volatile/pillar_location
+scoreboard players set @s[scores={gm4_mu_timer=12..}] gm4_mu_timer 0
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/fear_hit.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/fear_hit.mcfunction
new file mode 100644
index 0000000000..c24c77b31d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/fear_hit.mcfunction
@@ -0,0 +1,9 @@
+# apply fear to hit player
+# @s = player that was hit
+# at @s
+# run from mob/process/elite/vorpal/process_fear_cloud
+
+scoreboard players set $player_hit gm4_mu_data 1
+
+execute store result score $fear_seconds gm4_mu_data run random value 10..16
+function gm4_monsters_unbound:effect/fear/apply
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/init_fear_cloud.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/init_fear_cloud.mcfunction
new file mode 100644
index 0000000000..ebb66678c7
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/init_fear_cloud.mcfunction
@@ -0,0 +1,12 @@
+# spawn fear cloud skull
+# @s = block_display
+# at @s
+# run from mob/process/elite/on_death/run
+
+data merge entity @s {Tags:["gm4_mu_elite.fear_cloud"],teleport_duration:1,brightness:{sky:15,block:15},transformation:{left_rotation:[0f,1f,0f,0f],right_rotation:[0f,0f,0f,1f],translation:[0f,0.25f,0f],scale:[1f,1f,1f]},item:{id:"minecraft:wither_skeleton_skull",count:1}}
+
+playsound minecraft:entity.blaze.shoot hostile @a ~ ~ ~ 1 1.2
+
+tp @s ~ ~ ~ facing entity @p[gamemode=!spectator]
+
+execute unless score $keep_tick.elite_death_vorpal gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/vorpal_death 1t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/process_fear_cloud.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/process_fear_cloud.mcfunction
new file mode 100644
index 0000000000..eee2743012
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/process_fear_cloud.mcfunction
@@ -0,0 +1,30 @@
+# process fear cloud skull
+# @s = block_display
+# at @s
+# run from clocks/elite/vorpal_death
+
+# particles
+particle dust{color:[0.000,0.000,0.000],scale:1} ^ ^ ^0.0125 0.2666 0.2666 0.2666 0.666 4 normal
+
+scoreboard players add @s gm4_mu_timer 1
+
+# track towards closest player
+execute facing entity @p[gamemode=!spectator,gamemode=!creative] eyes positioned ^ ^ ^25 rotated as @s positioned ^ ^ ^25 facing entity @s eyes facing ^ ^ ^-1 positioned as @s run tp @s ~ ~ ~ ~ ~
+tp @s[scores={gm4_mu_timer=..29}] ^ ^ ^0.025
+tp @s[scores={gm4_mu_timer=30..60}] ^ ^ ^0.075
+tp @s[scores={gm4_mu_timer=61..90}] ^ ^ ^0.125
+tp @s[scores={gm4_mu_timer=91..120}] ^ ^ ^0.200
+tp @s[scores={gm4_mu_timer=121..140}] ^ ^ ^0.300
+tp @s[scores={gm4_mu_timer=141..160}] ^ ^ ^0.450
+tp @s[scores={gm4_mu_timer=161..}] ^ ^ ^0.650
+
+# hit players
+scoreboard players set $player_hit gm4_mu_data 0
+execute positioned ~-.15 ~-.15 ~-.15 as @a[dx=0,dy=0,dz=0,gamemode=!spectator,gamemode=!creative] positioned ~-0.55 ~-0.55 ~-0.55 if entity @s[dx=0,dy=0,dz=0] run function gm4_monsters_unbound:mob/process/elite/vorpal/fear_hit
+execute if score $player_hit gm4_mu_data matches 1 run return run kill @s
+
+# timer ran out
+execute if score @s gm4_mu_timer matches 240.. run return run kill @s
+
+# keep running if entity is still around
+scoreboard players set $keep_tick.elite_death_vorpal gm4_mu_keep_tick 1
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/randomize.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/randomize.mcfunction
new file mode 100644
index 0000000000..77a11c8546
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/randomize.mcfunction
@@ -0,0 +1,9 @@
+# get random teleport location
+# @s = marker
+# at @s
+# run from clocks/elite/vorpal/warp/spawn_marker
+
+execute store result score $randomX gm4_mu_data run random value 0..12
+execute store result score $randomZ gm4_mu_data run random value 0..12
+
+execute at @s run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/tp_marker
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/run.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/run.mcfunction
new file mode 100644
index 0000000000..fd2e7686aa
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/run.mcfunction
@@ -0,0 +1,14 @@
+# teleport the elite randomly
+# @s = vorpal elite
+# at @s
+# run from clocks/elite/on_hit/check_mob
+
+# teleport up to 12 blocks away
+tag @s add gm4_mu_target
+execute positioned ~-6 ~ ~-6 summon marker run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/spawn_marker
+tag @s remove gm4_mu_target
+
+playsound minecraft:entity.enderman.teleport hostile @a ~ ~ ~ 1 0.75
+
+execute at @s run particle minecraft:portal ~ ~1.75 ~ 0 0 0 0.75 32
+execute at @s run playsound minecraft:entity.enderman.teleport hostile @a ~ ~ ~ 1 0.75
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/set_ypos.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/set_ypos.mcfunction
new file mode 100644
index 0000000000..f3d3c7bcf8
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/set_ypos.mcfunction
@@ -0,0 +1,11 @@
+# get random teleport location
+# @s = marker
+# at @s
+# run from clocks/elite/vorpal/warp/tp_marker
+
+execute at @s run tp @s ~ ~-1 ~
+scoreboard players add $set_y gm4_mu_data 1
+scoreboard players set $warp_safe gm4_mu_data 0
+execute at @s if predicate gm4_monsters_unbound:technical/valid_tp unless entity @a[gamemode=!creative,gamemode=!spectator,distance=..3] run scoreboard players set $warp_safe gm4_mu_data 1
+execute if score $warp_safe gm4_mu_data matches 1 run scoreboard players set $warp_attempt gm4_mu_data 33
+execute unless score $set_y gm4_mu_data matches 8.. at @s unless score $warp_safe gm4_mu_data matches 1 run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/set_ypos
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/spawn_marker.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/spawn_marker.mcfunction
new file mode 100644
index 0000000000..8cc3471e7c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/spawn_marker.mcfunction
@@ -0,0 +1,12 @@
+# get random teleport location
+# @s = marker
+# at @s
+# run from clocks/elite/vorpal/warp/run
+
+execute store result score $y_pos gm4_mu_data run data get entity @s Pos[1]
+scoreboard players set $warp_attempt gm4_mu_data 0
+
+function gm4_monsters_unbound:mob/process/elite/vorpal/warp/randomize
+
+execute if score $warp_safe gm4_mu_data matches 1 at @s align xyz run tp @e[type=#gm4_monsters_unbound:elite_types,tag=gm4_mu_target] ~.5 ~ ~.5
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/tp_marker.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/tp_marker.mcfunction
new file mode 100644
index 0000000000..f17fdbacac
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/vorpal/warp/tp_marker.mcfunction
@@ -0,0 +1,31 @@
+# get random teleport location
+# @s = marker
+# at @s
+# run from clocks/elite/vorpal/warp/randomize
+# run from here
+
+execute at @s if score $randomX gm4_mu_data matches 8.. run tp @s ~8 ~ ~
+execute if score $randomX gm4_mu_data matches 8.. run scoreboard players remove $randomX gm4_mu_data 8
+execute at @s if score $randomX gm4_mu_data matches 4.. run tp @s ~4 ~ ~
+execute if score $randomX gm4_mu_data matches 4.. run scoreboard players remove $randomX gm4_mu_data 4
+execute at @s if score $randomX gm4_mu_data matches 2.. run tp @s ~2 ~ ~
+execute if score $randomX gm4_mu_data matches 2.. run scoreboard players remove $randomX gm4_mu_data 2
+execute at @s if score $randomX gm4_mu_data matches 1.. run tp @s ~1 ~ ~
+execute if score $randomX gm4_mu_data matches 1.. run scoreboard players remove $randomX gm4_mu_data 1
+
+execute at @s if score $randomZ gm4_mu_data matches 8.. run tp @s ~ ~ ~8
+execute if score $randomZ gm4_mu_data matches 8.. run scoreboard players remove $randomZ gm4_mu_data 8
+execute at @s if score $randomZ gm4_mu_data matches 4.. run tp @s ~ ~ ~4
+execute if score $randomZ gm4_mu_data matches 4.. run scoreboard players remove $randomZ gm4_mu_data 4
+execute at @s if score $randomZ gm4_mu_data matches 2.. run tp @s ~ ~ ~2
+execute if score $randomZ gm4_mu_data matches 2.. run scoreboard players remove $randomZ gm4_mu_data 2
+execute at @s if score $randomZ gm4_mu_data matches 1.. run tp @s ~ ~ ~1
+execute if score $randomZ gm4_mu_data matches 1.. run scoreboard players remove $randomZ gm4_mu_data 1
+
+execute store result entity @s Pos[1] double 1 run scoreboard players get $y_pos gm4_mu_data
+execute at @s run tp @s ~ ~4 ~
+scoreboard players set $set_y gm4_mu_data 0
+execute at @s run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/set_ypos
+
+scoreboard players add $warp_attempt gm4_mu_data 1
+execute unless score $warp_attempt gm4_mu_data matches 33.. run function gm4_monsters_unbound:mob/process/elite/vorpal/warp/randomize
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/activate.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/activate.mcfunction
new file mode 100644
index 0000000000..d4bfb53877
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/activate.mcfunction
@@ -0,0 +1,18 @@
+# activate charged attack
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/zephyr/process
+
+execute anchored eyes positioned ^ ^-1.15 ^ run particle gust_emitter_small ~ ~ ~ 0 0 0 1 1 normal
+playsound minecraft:entity.breeze.wind_burst hostile @a ~ ~ ~ 1 0
+
+# skeletons shoot arrows instead of speed burst
+execute if entity @s[type=#gm4_survival_refightalized:skeleton_types] run return run function gm4_monsters_unbound:mob/process/elite/zephyr/skeleton/start
+
+summon breeze_wind_charge ~ ~ ~ {Motion:[0.0,-5.0,0.0]}
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charging
+attribute @s minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.speed.charged 1.5 add_multiplied_total
+attribute @s minecraft:attack_damage modifier add gm4_monsters_unbound:elite_buff.speed.charged 0.75 add_multiplied_total
+attribute @s minecraft:attack_knockback modifier add gm4_monsters_unbound:elite_buff.speed.charged 2 add_value
+
+tag @s add gm4_mu_charging_attack
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/charge_complete.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/charge_complete.mcfunction
new file mode 100644
index 0000000000..d6915a57ab
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/charge_complete.mcfunction
@@ -0,0 +1,13 @@
+# charge is complete
+# @s = zephyr elite
+# at @s
+# run from mob/process/attack_effect/charging_attack
+
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_knockback modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+
+# don't charge again until player target is lost
+tag @s remove gm4_mu_charging_attack
+tag @s remove gm4_mu_elite.on_hit
+scoreboard players set @s gm4_mu_timer -12
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/hit_when_charging.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/hit_when_charging.mcfunction
new file mode 100644
index 0000000000..13e4a16f10
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/hit_when_charging.mcfunction
@@ -0,0 +1,21 @@
+# remove charge if mob is hit
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/on_hit/check_mob
+
+execute anchored eyes positioned ^ ^-0.15 ^ run particle small_gust ~ ~ ~ 0.45 0.45 0.45 1 16 normal
+playsound minecraft:entity.breeze.hurt hostile @a ~ ~ ~ 1 0
+effect give @s slowness 1 9 true
+
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charging
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_knockback modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+
+execute if score @s gm4_mu_timer matches 2.. run summon breeze_wind_charge ~ ~ ~ {Motion:[0.0,-5.0,0.0]}
+
+# disable charge for a little time
+tag @s remove gm4_mu_elite.zephyr_skeleton_burst
+tag @s remove gm4_mu_charging_attack
+tag @s remove gm4_mu_elite.on_hit
+scoreboard players set @s gm4_mu_timer -4
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/lose_charge.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/lose_charge.mcfunction
new file mode 100644
index 0000000000..00707776f0
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/lose_charge.mcfunction
@@ -0,0 +1,14 @@
+# remove charge if target is lost
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/zephyr/process
+
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charging
+attribute @s minecraft:movement_speed modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_damage modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+attribute @s minecraft:attack_knockback modifier remove gm4_monsters_unbound:elite_buff.speed.charged
+scoreboard players reset @s gm4_mu_timer
+
+effect give @s[tag=gm4_mu_elite.zephyr_skeleton_burst] speed 3 3
+tag @s remove gm4_mu_elite.zephyr_skeleton_burst
+tag @s remove gm4_mu_elite.on_hit
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/process.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/process.mcfunction
new file mode 100644
index 0000000000..b1d8f88b4a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/process.mcfunction
@@ -0,0 +1,28 @@
+# process zephyr elite
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/check_type
+
+scoreboard players set $has_target gm4_mu_data 0
+execute on target run scoreboard players set $has_target gm4_mu_data 1
+execute if entity @s[type=#gm4_survival_refightalized:skeleton_types,scores={gm4_mu_timer=1..}] run scoreboard players set $has_target gm4_mu_data 1
+
+# no target
+execute if score $has_target gm4_mu_data matches 0 if score @s gm4_mu_timer matches -2147483648..2147483647 run function gm4_monsters_unbound:mob/process/elite/zephyr/lose_charge
+execute if score $has_target gm4_mu_data matches 0 run return run scoreboard players reset @s gm4_mu_timer
+
+scoreboard players add @s gm4_mu_timer 1
+
+execute if score @s gm4_mu_timer matches 1..4 anchored eyes positioned ^ ^-0.15 ^ run particle small_gust ~ ~ ~ 0.35 0.35 0.35 1 6 normal
+
+tag @s[scores={gm4_mu_timer=1}] add gm4_mu_elite.on_hit
+attribute @s[scores={gm4_mu_timer=1}] minecraft:movement_speed modifier add gm4_monsters_unbound:elite_buff.speed.charging -1 add_multiplied_total
+
+execute if score @s gm4_mu_timer matches 2 run playsound minecraft:entity.breeze.inhale hostile @a ~ ~ ~ 1 0.5
+execute if score @s gm4_mu_timer matches 3 run playsound minecraft:entity.breeze.charge hostile @a ~ ~ ~ 1 0.5
+execute if score @s gm4_mu_timer matches 4 run playsound minecraft:entity.breeze.idle_air hostile @a ~ ~ ~ 1 0.65
+
+execute if score @s gm4_mu_timer matches 5 run function gm4_monsters_unbound:mob/process/elite/zephyr/activate
+execute if score @s[type=#gm4_survival_refightalized:skeleton_types] gm4_mu_timer matches 6..10 run function gm4_monsters_unbound:mob/process/elite/zephyr/skeleton/arrow_burst
+
+scoreboard players reset @s[scores={gm4_mu_timer=14..},tag=!gm4_mu_charging_attack] gm4_mu_timer
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/arrow_burst.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/arrow_burst.mcfunction
new file mode 100644
index 0000000000..42e6e1fe78
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/arrow_burst.mcfunction
@@ -0,0 +1,13 @@
+# shoot many arrows
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/zephyr/process
+# run from clocks/elite/zephyr_process
+
+scoreboard players add @s gm4_mu_data 1
+
+execute if score @s gm4_mu_data matches 16.. run return run function gm4_monsters_unbound:mob/process/elite/zephyr/lose_charge
+
+scoreboard players set $keep_tick.elite_process_zephyr gm4_mu_keep_tick 1
+
+execute anchored eyes positioned ^ ^ ^0.05 on target facing entity @s eyes summon arrow run function gm4_monsters_unbound:mob/process/elite/zephyr/skeleton/init_arrow
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/get_target_pos.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/get_target_pos.mcfunction
new file mode 100644
index 0000000000..0a21431496
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/get_target_pos.mcfunction
@@ -0,0 +1,10 @@
+# get pos of target
+# @s = marker
+# at @s
+# run from mob/process/elite/zephyr/skeleton/init_arrow
+
+data modify storage gm4_monsters_unbound:temp Pos set from entity @s Pos
+execute store result score $target_x gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[0] 100
+execute store result score $target_y gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[1] 100
+execute store result score $target_z gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[2] 100
+kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/init_arrow.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/init_arrow.mcfunction
new file mode 100644
index 0000000000..4980b3fa3a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/init_arrow.mcfunction
@@ -0,0 +1,38 @@
+# init arrow burst arrow
+# @s = arrow
+# at @s
+# run from mob/process/elite/zephyr/skeleton/arrow_burst
+
+# don't process this arrow
+tag @s add gm4_sr_arrow_checked
+
+# arrow deals half damage
+data modify entity @s damage set value 0.5
+
+# get player pos
+execute positioned ^ ^ ^10 summon marker run function gm4_monsters_unbound:mob/process/elite/zephyr/skeleton/get_target_pos
+
+# get vector
+data modify storage gm4_monsters_unbound:temp Pos set from entity @s Pos
+execute store result score $motion_x gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[0] 100
+execute store result score $motion_y gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[1] 100
+execute store result score $motion_z gm4_mu_data run data get storage gm4_monsters_unbound:temp Pos[2] 100
+
+execute store result score $motion_x_offset gm4_mu_data run random value -128..128
+execute store result score $motion_y_offset gm4_mu_data run random value -32..32
+execute store result score $motion_z_offset gm4_mu_data run random value -128..128
+
+scoreboard players operation $target_x gm4_mu_data += $motion_x_offset gm4_mu_data
+scoreboard players operation $target_y gm4_mu_data += $motion_y_offset gm4_mu_data
+scoreboard players operation $target_z gm4_mu_data += $motion_z_offset gm4_mu_data
+
+scoreboard players operation $motion_x gm4_mu_data -= $target_x gm4_mu_data
+scoreboard players operation $motion_y gm4_mu_data -= $target_y gm4_mu_data
+scoreboard players operation $motion_z gm4_mu_data -= $target_z gm4_mu_data
+
+# set motion
+execute store result entity @s Motion[0] double -0.0016517 run scoreboard players get $motion_x gm4_mu_data
+execute store result entity @s Motion[1] double -0.0016517 run scoreboard players get $motion_y gm4_mu_data
+execute store result entity @s Motion[2] double -0.0016517 run scoreboard players get $motion_z gm4_mu_data
+
+data remove storage gm4_monsters_unbound:temp Pos
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/start.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/start.mcfunction
new file mode 100644
index 0000000000..372bcb456c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/elite/zephyr/skeleton/start.mcfunction
@@ -0,0 +1,8 @@
+# start arrow burst for skeleton zephyr elite
+# @s = zephyr elite
+# at @s
+# run from mob/process/elite/zephyr/process
+
+tag @s add gm4_mu_elite.zephyr_skeleton_burst
+scoreboard players set @s gm4_mu_data 0
+execute unless score $keep_tick.elite_process_zephyr gm4_mu_keep_tick matches 1 run schedule function gm4_monsters_unbound:clocks/elite/zephyr_process 2t
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_dripstone_trap.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_dripstone_trap.mcfunction
new file mode 100644
index 0000000000..fe8147f8fe
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_dripstone_trap.mcfunction
@@ -0,0 +1,21 @@
+# reveal dripstone trap when a player gets below
+# @s = hidden dripstone trap
+# at @s
+# run from main
+
+kill @s
+
+execute unless block ~ ~1 ~ #gm4_monsters_unbound:dripstone run return 0
+
+# spring the trap
+particle block{block_state:"dripstone_block"} ~ ~ ~ 0.2 0.6 0.2 1 24
+particle block{block_state:"dripstone_block"} ~ ~-16 ~ 0.2 10 0.2 1 64
+playsound minecraft:block.dripstone_block.break block @a[distance=..42] ~ ~ ~ 1.5 0.8 1
+
+execute store result score $pick_entity gm4_mu_data run random value 1..3
+scoreboard players set $mob_extras gm4_sr_data 1
+execute if score $pick_entity gm4_mu_data matches 1 run summon skeleton ~ ~-0.8 ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,-0.275d,0.0d],attributes:[{id:"fall_damage_multiplier",base:1,modifiers:[{id:"gm4_monsters_unbound:stat_change.dripstone_trap",amount:-0.95,operation:"add_multiplied_total"}]}]}
+execute if score $pick_entity gm4_mu_data matches 2 run summon zombie ~ ~-0.8 ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,-0.275d,0.0d],attributes:[{id:"fall_damage_multiplier",base:1,modifiers:[{id:"gm4_monsters_unbound:stat_change.dripstone_trap",amount:-0.95,operation:"add_multiplied_total"}]}]}
+execute if score $pick_entity gm4_mu_data matches 3 run summon spider ~ ~ ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,-0.275d,0.0d],attributes:[{id:"fall_damage_multiplier",base:1,modifiers:[{id:"gm4_monsters_unbound:stat_change.dripstone_trap",amount:-0.95,operation:"add_multiplied_total"}]}]}
+
+execute as @e[type=#gm4_survival_refightalized:modify,tag=gm4_sr_extra_mob,distance=..1,limit=1] at @s run function gm4_survival_refightalized:mob/init/initiate
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_snowy_trap.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_snowy_trap.mcfunction
new file mode 100644
index 0000000000..41f348202c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/reveal_snowy_trap.mcfunction
@@ -0,0 +1,20 @@
+# reveal snowy trap when a player gets nearby
+# @s = hidden snowy trap
+# at @s
+# run from main
+
+kill @s
+
+execute unless block ~ ~ ~ snow run return 0
+
+# spring the trap
+particle block{block_state:"snow"} ~ ~1 ~ 0.2 0.6 0.2 1 12
+playsound minecraft:block.snow.place block @a ~ ~ ~ 1.5 0.8
+
+execute store result score $pick_entity gm4_mu_data run random value 1..3
+scoreboard players set $mob_extras gm4_sr_data 1
+execute if score $pick_entity gm4_mu_data matches 1 run summon zombie ~ ~-0.75 ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,0.5d,0.0d]}
+execute if score $pick_entity gm4_mu_data matches 2 run summon stray ~ ~-0.75 ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,0.5d,0.0d]}
+execute if score $pick_entity gm4_mu_data matches 3 run summon creeper ~ ~-0.75 ~ {Tags:["gm4_sr_extra_mob"],Motion:[0.0d,0.5d,0.0d]}
+
+execute as @e[type=#gm4_survival_refightalized:modify,tag=gm4_sr_extra_mob,distance=..1,limit=1] at @s run function gm4_survival_refightalized:mob/init/initiate
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/activate.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/activate.mcfunction
new file mode 100644
index 0000000000..fc43aafca4
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/activate.mcfunction
@@ -0,0 +1,31 @@
+# summon new zombie/husk/drowned when spore is grown
+# @s = spore item
+# at @s
+# run from mob/process/spore/advance
+
+# check for mob cap
+execute at @p[gamemode=!spectator] store result score $spore_zombie_count gm4_mu_data if entity @e[type=#gm4_survival_refightalized:zombie_types,tag=gm4_mu_spore_mob,distance=..32]
+execute if score $spore_zombie_count gm4_mu_data > $mob_limit.spore_zombie gm4_sr_config run kill @s
+execute if score $spore_zombie_count gm4_mu_data > $mob_limit.spore_zombie gm4_sr_config run return 0
+
+# get spores in stack and their generation
+execute store result score $spore_count gm4_mu_data run data get entity @s Item.count
+execute store result score $generation gm4_mu_data run data get entity @s Item.components."minecraft:custom_data".gm4_mu_spore.generation
+
+# spawn up to 4 spore zombies
+execute align xz run summon zombie ~.5 ~ ~.5 {Tags:["gm4_sr_extra_mob","gm4_mu_spore_mob"]}
+execute if score $spore_count gm4_mu_data matches 2.. align xz run summon zombie ~.51 ~ ~.47 {Tags:["gm4_sr_extra_mob","gm4_mu_spore_mob"]}
+execute if score $spore_count gm4_mu_data matches 3.. align xz run summon zombie ~.54 ~ ~.52 {Tags:["gm4_sr_extra_mob","gm4_mu_spore_mob"]}
+execute if score $spore_count gm4_mu_data matches 4.. align xz run summon zombie ~0.47 ~ ~.54 {Tags:["gm4_sr_extra_mob","gm4_mu_spore_mob"]}
+execute if entity @s[tag=gm4_mu_spore.cherry] run tag @e[type=zombie,tag=gm4_mu_spore_mob,distance=..1] add gm4_mu_spore_zombie.cherry
+
+# vfx
+particle minecraft:block{block_state:"minecraft:flowering_azalea_leaves"} ~ ~1 ~ 0.35 1 0.35 0.1 32
+playsound block.grass.break hostile @a ~ ~ ~ 0.6 0.6
+
+# remove spores
+execute if score $spore_count gm4_mu_data matches ..4 run kill @s
+execute if score $spore_count gm4_mu_data matches 5.. store result entity @s Item.count byte 1 run scoreboard players remove $spore_count gm4_mu_data 4
+
+# set spore zombie generation
+execute as @e[tag=gm4_mu_spore_mob,distance=..1] at @s run function gm4_monsters_unbound:mob/process/spore/set_generation
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/advance.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/advance.mcfunction
new file mode 100644
index 0000000000..d7ddc6d5f2
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/advance.mcfunction
@@ -0,0 +1,15 @@
+# advance spore growth
+# @s = spore item
+# at @s
+# run from main
+
+execute if score @s gm4_mu_data matches 10.. run return run function gm4_monsters_unbound:mob/process/spore/activate
+
+scoreboard players add @s gm4_mu_data 1
+execute if score @s[tag=!gm4_mu_spore.cherry] gm4_mu_data matches 1..4 run particle minecraft:block{block_state:"minecraft:flowering_azalea_leaves"} ~ ~ ~ 0.04 0.15 0.04 0.05 5
+execute if score @s[tag=!gm4_mu_spore.cherry] gm4_mu_data matches 5..7 run particle minecraft:block{block_state:"minecraft:flowering_azalea_leaves"} ~ ~ ~ 0.045 0.175 0.045 0.1 8
+execute if score @s[tag=!gm4_mu_spore.cherry] gm4_mu_data matches 8.. run particle minecraft:block{block_state:"minecraft:flowering_azalea_leaves"} ~ ~ ~ 0.05 0.2 0.05 0.15 16
+execute if score @s[tag=gm4_mu_spore.cherry] gm4_mu_data matches 1..4 run particle minecraft:block{block_state:"minecraft:cherry_leaves"} ~ ~ ~ 0.04 0.15 0.04 0.05 5
+execute if score @s[tag=gm4_mu_spore.cherry] gm4_mu_data matches 5..7 run particle minecraft:block{block_state:"minecraft:cherry_leaves"} ~ ~ ~ 0.045 0.175 0.045 0.1 8
+execute if score @s[tag=gm4_mu_spore.cherry] gm4_mu_data matches 8.. run particle minecraft:block{block_state:"minecraft:cherry_leaves"} ~ ~ ~ 0.05 0.2 0.05 0.15 16
+playsound block.grass.step hostile @a ~ ~ ~ 2 0.5
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/burn_on_head.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/burn_on_head.mcfunction
new file mode 100644
index 0000000000..fef77ad5a0
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/burn_on_head.mcfunction
@@ -0,0 +1,10 @@
+# burn the spore if a spore zombie is on fire
+# @s = spore zombie
+# at unspecified
+# run from main
+
+item replace entity @s armor.head with air
+tag @s remove gm4_mu_spore_zombie
+tag @s remove gm4_mu_spore_zombie.cherry
+
+execute anchored eyes run particle flame ^ ^0.1 ^-0.1 0.1 0.1 0.1 0.15 8
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/initialise.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/initialise.mcfunction
new file mode 100644
index 0000000000..03e1f3a7b0
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/initialise.mcfunction
@@ -0,0 +1,8 @@
+# tag spore item as spore
+# @s = spore item
+# at unspecified
+# run from check_item
+
+tag @s add gm4_mu_spore
+data merge entity @s {Age:-32768,PickupDelay:32767,Health:4}
+execute if items entity @s contents minecraft:cherry_leaves run tag @s add gm4_mu_spore.cherry
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/set_generation.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/set_generation.mcfunction
new file mode 100644
index 0000000000..bf2c1dfca0
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/spore/set_generation.mcfunction
@@ -0,0 +1,9 @@
+# set generation of new zombie/husk/drowned
+# @s = zombie/husk/drowned
+# at @s
+# run from mob/process/spore/activate
+
+scoreboard players operation @s gm4_mu_generation = $generation gm4_mu_data
+tag @s remove gm4_mu_spore_mob
+tag @s add gm4_mu_spore_zombie
+function gm4_monsters_unbound:mob/init/initiate
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/toxic_creeper.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/toxic_creeper.mcfunction
new file mode 100644
index 0000000000..c3c3da772f
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/mob/process/toxic_creeper.mcfunction
@@ -0,0 +1,10 @@
+# refresh effects on creeper
+# @s = toxic creeper
+# at unspecified
+# run from slow_clock
+# run from mob/init/mob_type/creeper
+
+effect give @s weakness 33 1
+effect give @s blindness 33 0 true
+effect give @s nausea 33 0 true
+effect give @s hunger 33 1 true
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/slow_clock.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/slow_clock.mcfunction
new file mode 100644
index 0000000000..3a7c598719
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/slow_clock.mcfunction
@@ -0,0 +1,10 @@
+schedule function gm4_monsters_unbound:slow_clock 30s
+
+# toxic creepers
+execute as @e[type=creeper,tag=gm4_mu_toxic_creeper] run function gm4_monsters_unbound:mob/process/toxic_creeper
+
+# cloaked crepers
+effect give @e[type=creeper,tag=gm4_mu_cloaked_creeper] invisibility 33 0
+
+# remove traps that have not been triggered
+execute as @e[type=marker,tag=gm4_mu_trap] at @s unless entity @a[gamemode=!spectator,distance=..128] run kill @s
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/function/tick.mcfunction b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/tick.mcfunction
new file mode 100644
index 0000000000..e13dc0c417
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/function/tick.mcfunction
@@ -0,0 +1,4 @@
+schedule function gm4_monsters_unbound:tick 1t
+
+# check for items on the ground
+execute as @e[type=item,tag=!gm4_mu_item_checked,tag=!smithed.strict,tag=!smithed.entity] run function gm4_monsters_unbound:check_item
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/guidebook/monsters_unbound.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/guidebook/monsters_unbound.json
new file mode 100644
index 0000000000..7eba959453
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/guidebook/monsters_unbound.json
@@ -0,0 +1,828 @@
+{
+ "id": "monsters_unbound",
+ "name": "Monsters Unbound",
+ "module_type": "module",
+ "icon": {
+ "id": "minecraft:chainmail_chestplate"
+ },
+ "criteria": {
+ "enter_underground": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ ]
+ }
+ },
+ "enter_dripstone_caves": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "minecraft:dripstone_caves"
+ }
+ }
+ ]
+ }
+ },
+ "enter_burned": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/burned"
+ }
+ ]
+ }
+ },
+ "enter_flowering": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/flowering"
+ }
+ ]
+ }
+ },
+ "enter_growth": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/growth"
+ }
+ ]
+ }
+ },
+ "enter_mountainous": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/mountainous"
+ }
+ ]
+ }
+ },
+ "enter_warm_ocean": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "minecraft:warm_ocean"
+ }
+ }
+ ]
+ }
+ },
+ "enter_snowy": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/snowy"
+ }
+ ]
+ }
+ },
+ "enter_toxic": {
+ "trigger": "minecraft:location",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/toxic"
+ }
+ ]
+ }
+ },
+ "kill_elite_blazing": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.blazing\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_gargantuan": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.gargantuan\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_glacial": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.glacial\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_mending": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.mending\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_pearlescent": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.pearlescent\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_splitting": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.splitting\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_volatile": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.volatile\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_vorpal": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.vorpal\"]}"
+ }
+ }
+ ]
+ }
+ },
+ "kill_elite_zephyr": {
+ "trigger": "minecraft:player_killed_entity",
+ "conditions": {
+ "entity": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_elite.zephyr\"]}"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "sections": [
+ {
+ "name": "biomes",
+ "enable": [],
+ "requirements": [],
+ "pages": [
+ [
+ {
+ "insert": "title"
+ },
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.biomes",
+ "fallback": "Mobs spawned in different biomes have special modifiers.\n\nSome areas and biomes spawn different mobs than usual."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "underground",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_underground"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.underground",
+ "fallback": "Mobs spawned underground are generally stronger and can have varying buffs and potion effects."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "burned",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_burned"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.burned",
+ "fallback": "Mobs spawned in a %s biome are weaker but faster.\n\nHusks spawn in large groups.",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.burned",
+ "fallback": "burned",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.desert"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.savanna"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.savanna_plateau"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.windswept_savanna"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.badlands"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.wooded_badlands"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.eroded_badlands"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "dripstone_caves",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_dripstone_caves"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.dripstone_caves",
+ "fallback": "More Spiders are found in Dripstone Caves, and Skeletons may wield pickaxes.\n\nSome Dripstone may be trapped and drop a mob when walked below."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "flowering",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_flowering"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.flowering",
+ "fallback": "In %s biomes Spore Zombies can be found, these drop a respawning Spore on death. Spores are susceptible to fire.\n\nCreepers are weaker but invisible.",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.flowering",
+ "fallback": "flowering",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.sunflower_plains"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.flower_forest"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.cherry_grove"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.lush_caves"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "growth",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_growth"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.growth",
+ "fallback": "Mobs spawned in a %s biome are faster.\n\nSkeletons usually use melee weapons.\n\nMore Spiders are found here",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.growth",
+ "fallback": "growth",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.snowy_taiga"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.grove"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.taiga"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.old_growth_pine_taiga"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.old_growth_spruce_taiga"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.dark_forest"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.mangrove_swamp"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "mountainous",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_mountainous"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.mountainous",
+ "fallback": "Phantoms can spawn in %s biomes.\n\nCreepers have more health.\n\nSpiders are faster",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.mountainous",
+ "fallback": "mountainous",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.snowy_slopes"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.jagged_peaks"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.frozen_peaks"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.windswept_hills"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.windswept_gravelly_hills"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.windswept_forest"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.stony_shore"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.cherry_grove"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.meadow"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.stony_peaks"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.windswept_savanna"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.eroded_badlands"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "snowy",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_snowy"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.snowy",
+ "fallback": "Mobs can ambush the player from snow in %s biomes.\n\nMobs can apply slowness.\n\nSpiders can be Gargantuan Elites.",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.snowy",
+ "fallback": "snowy",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.snowy_plains"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.ice_spikes"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.snowy_taiga"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.snowy_beach"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.grove"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.snowy_slopes"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.jagged_peaks"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.frozen_peaks"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.frozen_river"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.frozen_ocean"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.deep_frozen_ocean"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "toxic",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_toxic"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.toxic",
+ "fallback": "Mobs spawned in a %s biome can apply various negative effects.\n\nMore Witches are found here.",
+ "with": [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.toxic",
+ "fallback": "toxic",
+ "color": "blue",
+ "hoverEvent": {
+ "action": "show_text",
+ "contents": [
+ "- ",
+ {
+ "translate": "biome.minecraft.swamp"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.mangrove_swamp"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.jungle"
+ },
+ "\n- ",
+ {
+ "translate": "biome.minecraft.bamboo_jungle"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ },
+ {
+ "name": "warm_ocean",
+ "enable": [],
+ "requirements": [
+ [
+ "enter_warm_ocean"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.warm_ocean",
+ "fallback": "Drowned spawned in a Warm Ocean are much more powerful and have a larger chance to spawn wielding a Trident."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elites",
+ "enable": [],
+ "requirements": [],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elites",
+ "fallback": "Zombies that spawn as babies or as leaders are replaced with a random Elite variant.\n\nSkeletons have a static 5% chance to be an Elite."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_blazing",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_blazing"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_blazing",
+ "fallback": "Blazing Elites are slow and immune to burning. Their attacks deal little damage but have Fire Aspect II or Flame. Occasionally will spawn slow moving homing projectiles that explode on contact."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_gargantuan",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_gargantuan"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_gargantuan",
+ "fallback": "Gargantuan Elites are much bigger and gain stats based on their missing health. Will occasionally perform an AoE stomp attack."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_glacial",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_glacial"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_glacial",
+ "fallback": "Glacial Elites leave a sphere of frozen energy on death. This sphere explodes after 2 seconds freezing any entity inside for 3 seconds."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_mending",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_mending"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_mending",
+ "fallback": "Mending Elites will heal other undead mobs in their line of sight, this will never target other Mending Elites."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_pearlescent",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_pearlescent"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_pearlescent",
+ "fallback": "Pearescent Elites can shoot damaging lasers from their eyes, the laser is blocked by terrain."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_splitting",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_splitting"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_splitting",
+ "fallback": "Splitting Elites split into 6 smaller and weaker versions of itself on death."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_volatile",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_volatile"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_volatile",
+ "fallback": "Volatile Elites create randomly targeted purple beams of energy around them that explode after a delay, dealing heavy magic damage."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_vorpal",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_vorpal"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_vorpal",
+ "fallback": "Vorpal Elites teleport randomly on getting hit. On death a homing skull will track the nearest player and apply Fear, which blinds and slows interactions."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "elite_zephyr",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_elite_zephyr"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.monsters_unbound.description.elite_zephyr",
+ "fallback": "Zephyr Elites can charge a powerful wind-charged attack. Damaging them during the charge time dissipates the charge. Zephyr Zombies will rush the player, Zephyr Skeletons fire a burst of arrows."
+ }
+ ]
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/glacial.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/glacial.json
new file mode 100644
index 0000000000..e38a0530fc
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/glacial.json
@@ -0,0 +1,29 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:packed_ice",
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_elite_on_death:{name:glacial,id:1}}"
+ },
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/elite_headwear/glacial",
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/mending.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/mending.json
new file mode 100644
index 0000000000..dd31bbd99d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/mending.json
@@ -0,0 +1,25 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:lime_glazed_terracotta",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/elite_headwear/mending",
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/pearlescent.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/pearlescent.json
new file mode 100644
index 0000000000..72e33b3220
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/pearlescent.json
@@ -0,0 +1,25 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:pearlescent_froglight",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/elite_headwear/pearlescent",
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_skeleton.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_skeleton.json
new file mode 100644
index 0000000000..621d71bd8e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_skeleton.json
@@ -0,0 +1,28 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:spawner",
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_elite_on_death:{name:splitting_skeleton,id:4}}"
+ },
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_zombie.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_zombie.json
new file mode 100644
index 0000000000..b6644a6150
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/splitting_zombie.json
@@ -0,0 +1,28 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:spawner",
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_elite_on_death:{name:splitting_zombie,id:3}}"
+ },
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/volatile.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/volatile.json
new file mode 100644
index 0000000000..29f3f52f1e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/volatile.json
@@ -0,0 +1,29 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:purple_glazed_terracotta",
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_elite_on_death:{name:volatile,id:5}}"
+ },
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "blast_protection": 10,
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/vorpal.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/vorpal.json
new file mode 100644
index 0000000000..be74248fa3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/elite/vorpal.json
@@ -0,0 +1,28 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:black_wool",
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_elite_on_death:{name:vorpal,id:2}}"
+ },
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "enchantment_glint_override": false,
+ "enchantments": {
+ "binding_curse": 1
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_armor/spore.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_armor/spore.json
new file mode 100644
index 0000000000..682023d45d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_armor/spore.json
@@ -0,0 +1,97 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:cherry_leaves",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/spore/cherry"
+ }
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_spore_zombie.cherry\"]}"
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:azalea_leaves",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/spore/default"
+ }
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.66
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_spore_zombie.cherry\"]}"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:flowering_azalea_leaves",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:custom_model_data": "item/spore/flowering"
+ }
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "nbt": "{Tags:[\"gm4_mu_spore_zombie.cherry\"]}"
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "functions": [
+ {
+ "function": "minecraft:set_custom_data",
+ "tag": "{gm4_mu_spore:{generation:0}}"
+ },
+ {
+ "function": "minecraft:set_name",
+ "target": "item_name",
+ "name": {
+ "translate": "item.gm4.monsters_unbound.zombie_spore",
+ "fallback": "Zombie Spore",
+ "italic": false
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/skeleton_toxic.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/skeleton_toxic.json
new file mode 100644
index 0000000000..68cf89a259
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/skeleton_toxic.json
@@ -0,0 +1,64 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:tipped_arrow",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:potion_contents": {
+ "custom_color": 8889187,
+ "custom_effects": [
+ {
+ "id": "minecraft:weakness",
+ "amplifier": 0,
+ "duration": 800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ },
+ {
+ "id": "minecraft:hunger",
+ "amplifier": 1,
+ "duration": 800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ },
+ {
+ "id": "minecraft:poison",
+ "amplifier": 0,
+ "duration": 800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ }
+ ]
+ }
+ }
+ },
+ {
+ "function": "minecraft:set_name",
+ "target": "custom_name",
+ "name": {
+ "translate": "item.minecraft.tipped_arrow.effect.poison",
+ "italic": false
+ }
+ },
+ {
+ "function": "minecraft:set_count",
+ "count": {
+ "min": 2,
+ "max": 4
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_snowy.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_snowy.json
new file mode 100644
index 0000000000..edc4f070b3
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_snowy.json
@@ -0,0 +1,48 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:tipped_arrow",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:potion_contents": {
+ "custom_color": 9154528,
+ "custom_effects": [
+ {
+ "id": "minecraft:slowness",
+ "amplifier": 2,
+ "duration": 4800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ }
+ ]
+ }
+ }
+ },
+ {
+ "function": "minecraft:set_name",
+ "target": "custom_name",
+ "name": {
+ "translate": "item.minecraft.tipped_arrow.effect.slowness",
+ "italic": false
+ }
+ },
+ {
+ "function": "minecraft:set_count",
+ "count": {
+ "min": 1,
+ "max": 2
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_toxic.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_toxic.json
new file mode 100644
index 0000000000..ca205e49db
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/loot_table/mob/equip_arrow/stray_toxic.json
@@ -0,0 +1,64 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:tipped_arrow",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:potion_contents": {
+ "custom_color": 8889187,
+ "custom_effects": [
+ {
+ "id": "minecraft:weakness",
+ "amplifier": 0,
+ "duration": 800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ },
+ {
+ "id": "minecraft:poison",
+ "amplifier": 1,
+ "duration": 800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ },
+ {
+ "id": "minecraft:slowness",
+ "amplifier": 0,
+ "duration": 4800,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ }
+ ]
+ }
+ }
+ },
+ {
+ "function": "minecraft:set_name",
+ "target": "custom_name",
+ "name": {
+ "translate": "item.minecraft.tipped_arrow.effect.poison",
+ "italic": false
+ }
+ },
+ {
+ "function": "minecraft:set_count",
+ "count": {
+ "min": 2,
+ "max": 4
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/burned.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/burned.json
new file mode 100644
index 0000000000..6dbf35d141
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/burned.json
@@ -0,0 +1,23 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:desert",
+ "minecraft:savanna",
+ "minecraft:savanna_plateau",
+ "minecraft:windswept_savanna",
+ "minecraft:badlands",
+ "minecraft:wooded_badlands",
+ "minecraft:eroded_badlands"
+ ]
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/flowering.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/flowering.json
new file mode 100644
index 0000000000..0076ffbb3f
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/flowering.json
@@ -0,0 +1,35 @@
+[
+ {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "minecraft:lush_caves"
+ }
+ },
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:sunflower_plains",
+ "minecraft:flower_forest",
+ "minecraft:cherry_grove"
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/growth.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/growth.json
new file mode 100644
index 0000000000..36dc9adb2e
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/growth.json
@@ -0,0 +1,23 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:snowy_taiga",
+ "minecraft:grove",
+ "minecraft:taiga",
+ "minecraft:old_growth_pine_taiga",
+ "minecraft:old_growth_spruce_taiga",
+ "minecraft:dark_forest",
+ "minecraft:mangrove_swamp"
+ ]
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/mountainous.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/mountainous.json
new file mode 100644
index 0000000000..802689bbf8
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/mountainous.json
@@ -0,0 +1,28 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:snowy_slopes",
+ "minecraft:jagged_peaks",
+ "minecraft:frozen_peaks",
+ "minecraft:windswept_hills",
+ "minecraft:windswept_gravelly_hills",
+ "minecraft:windswept_forest",
+ "minecraft:stony_shore",
+ "minecraft:meadow",
+ "minecraft:stony_peaks",
+ "minecraft:windswept_savanna",
+ "minecraft:eroded_badlands",
+ "minecraft:cherry_grove"
+ ]
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/reef.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/reef.json
new file mode 100644
index 0000000000..5f0551827a
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/reef.json
@@ -0,0 +1,28 @@
+[
+ {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "block": {
+ "blocks": "#gm4:water"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "minecraft:warm_ocean"
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/snowy.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/snowy.json
new file mode 100644
index 0000000000..6b9fa961eb
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/snowy.json
@@ -0,0 +1,27 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:snowy_plains",
+ "minecraft:ice_spikes",
+ "minecraft:snowy_taiga",
+ "minecraft:snowy_beach",
+ "minecraft:grove",
+ "minecraft:snowy_slopes",
+ "minecraft:jagged_peaks",
+ "minecraft:frozen_peaks",
+ "minecraft:frozen_river",
+ "minecraft:frozen_ocean",
+ "minecraft:deep_frozen_ocean"
+ ]
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/toxic.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/toxic.json
new file mode 100644
index 0000000000..fd294dbc53
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/biome/toxic.json
@@ -0,0 +1,20 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": [
+ "minecraft:swamp",
+ "minecraft:mangrove_swamp",
+ "minecraft:jungle",
+ "minecraft:bamboo_jungle"
+ ]
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/chance/spawn_phantom.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/chance/spawn_phantom.json
new file mode 100644
index 0000000000..3723be3e3d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/chance/spawn_phantom.json
@@ -0,0 +1,18 @@
+[
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.075
+ },
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_monsters_unbound:biome/mountainous"
+ },
+ {
+ "condition": "minecraft:time_check",
+ "value": {
+ "min": 13188,
+ "max": 22812
+ },
+ "period": 24000
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/on_fire.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/on_fire.json
new file mode 100644
index 0000000000..81903de6b6
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/on_fire.json
@@ -0,0 +1,9 @@
+{
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "flags": {
+ "is_on_fire": true
+ }
+ }
+ }
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/valid_tp.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/valid_tp.json
new file mode 100644
index 0000000000..11032fe31d
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/predicate/technical/valid_tp.json
@@ -0,0 +1,73 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:location_check",
+ "offsetY": -1,
+ "predicate": {
+ "block": {
+ "blocks": "#gm4:no_collision"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:location_check",
+ "offsetY": 1,
+ "predicate": {
+ "fluid": {
+ "fluids": "#minecraft:lava"
+ }
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "fluid": {
+ "fluids": "#minecraft:lava"
+ }
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "offsetY": 1,
+ "predicate": {
+ "fluid": {
+ "fluids": "#minecraft:water"
+ }
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "fluid": {
+ "fluids": "#minecraft:water"
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "offsetY": 1,
+ "predicate": {
+ "block": {
+ "blocks": "#gm4:no_collision"
+ }
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "block": {
+ "blocks": "#gm4:no_collision"
+ }
+ }
+ }
+]
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/block/dripstone.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/block/dripstone.json
new file mode 100644
index 0000000000..66925de919
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/block/dripstone.json
@@ -0,0 +1,6 @@
+{
+ "values": [
+ "minecraft:dripstone_block",
+ "minecraft:pointed_dripstone"
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/entity_type/elite_types.json b/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/entity_type/elite_types.json
new file mode 100644
index 0000000000..98d6cd9b42
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_monsters_unbound/tags/entity_type/elite_types.json
@@ -0,0 +1,10 @@
+{
+ "values": [
+ "minecraft:bogged",
+ "minecraft:drowned",
+ "minecraft:husk",
+ "minecraft:skeleton",
+ "minecraft:stray",
+ "minecraft:zombie"
+ ]
+}
diff --git a/gm4_monsters_unbound/data/gm4_survival_refightalized/tags/function/init_mob.json b/gm4_monsters_unbound/data/gm4_survival_refightalized/tags/function/init_mob.json
new file mode 100644
index 0000000000..4ce5a5586c
--- /dev/null
+++ b/gm4_monsters_unbound/data/gm4_survival_refightalized/tags/function/init_mob.json
@@ -0,0 +1,5 @@
+{
+ "values": [
+ "gm4_monsters_unbound:mob/init/mob_type"
+ ]
+}
diff --git a/gm4_monsters_unbound/images/monsters_unbound.png b/gm4_monsters_unbound/images/monsters_unbound.png
new file mode 100644
index 0000000000..113458931d
Binary files /dev/null and b/gm4_monsters_unbound/images/monsters_unbound.png differ
diff --git a/gm4_monsters_unbound/pack.svg b/gm4_monsters_unbound/pack.svg
new file mode 100644
index 0000000000..31dc1698ff
--- /dev/null
+++ b/gm4_monsters_unbound/pack.svg
@@ -0,0 +1,118 @@
+
+
+
diff --git a/gm4_monsters_unbound/translations.csv b/gm4_monsters_unbound/translations.csv
new file mode 100644
index 0000000000..d8e3efce94
--- /dev/null
+++ b/gm4_monsters_unbound/translations.csv
@@ -0,0 +1,46 @@
+key,en_us
+advancement.gm4.monsters_unbound.elite_kill.title,Elite Hunter
+advancement.gm4.monsters_unbound.elite_kill.description,Kill any Elite monster
+advancement.gm4.monsters_unbound.elite_kill_all.title,Elites Hunted
+advancement.gm4.monsters_unbound.elite_kill_all.description,Kill one of every Elite monster
+item.gm4.monsters_unbound.zombie_spore,Zombie Spore
+text.gm4.monsters_unbound.elite_name.glacial,Glacial
+text.gm4.monsters_unbound.elite_name.slate,Slate
+text.gm4.monsters_unbound.elite_name.blazing,Blazing
+text.gm4.monsters_unbound.elite_name.zephyr,Zephyr
+text.gm4.monsters_unbound.elite_name.gargantuan,Gargantuan
+text.gm4.monsters_unbound.elite_name.vorpal,Vorpal
+text.gm4.monsters_unbound.elite_name.splitting,Splitting
+text.gm4.monsters_unbound.elite_name.split,Split
+text.gm4.monsters_unbound.elite_name.volatile,Volatile
+text.gm4.monsters_unbound.elite_name.pearlescent,Pearlescent
+text.gm4.guidebook.module_desc.monsters_unbound,Mobs gain special effects based on their biome.
+text.gm4.guidebook.monsters_unbound.description.biomes,Mobs spawned in different biomes have special modifiers.\n\nSome areas and biomes spawn different mobs than usual.
+text.gm4.guidebook.monsters_unbound.description.underground,Mobs spawned underground are generally stronger and can have varying buffs and potion effects.
+text.gm4.guidebook.monsters_unbound.burned,burned
+text.gm4.guidebook.monsters_unbound.description.burned,Mobs spawned in a %s biome are weaker but faster.\n\nHusks spawn in large groups.
+text.gm4.guidebook.monsters_unbound.description.dripstone_caves,"More Spiders are found in Dripstone Caves, and Skeletons may wield pickaxes.\n\nSome Dripstone may be trapped and drop a mob when walked below."
+text.gm4.guidebook.monsters_unbound.flowering,flowering
+text.gm4.guidebook.monsters_unbound.description.flowering,"In %s biomes Spore Zombies can be found, these drop a respawning Spore on death. Spores are susceptible to fire.\n\nCreepers are weaker but invisible."
+text.gm4.guidebook.monsters_unbound.growth,growth
+text.gm4.guidebook.monsters_unbound.description.growth,Mobs spawned in a %s biome are faster.\n\nSkeletons usually use melee weapons.\n\nMore Spiders are found here
+text.gm4.guidebook.monsters_unbound.mountainous,mountainous
+text.gm4.guidebook.monsters_unbound.description.mountainous,Phantoms can spawn in %s biomes.\n\nCreepers have more health.\n\nSpiders are faster
+text.gm4.guidebook.monsters_unbound.snowy,snowy
+text.gm4.guidebook.monsters_unbound.description.snowy,Mobs can ambush the player from snow in %s biomes.\n\nMobs can apply slowness.\n\nSpiders can be Gargantuan Elites.
+text.gm4.guidebook.monsters_unbound.toxic,toxic
+text.gm4.guidebook.monsters_unbound.description.toxic,Mobs spawned in a %s biome can apply various negative effects.\n\nMore Witches are found here.
+text.gm4.guidebook.monsters_unbound.description.warm_ocean,Drowned spawned in a Warm Ocean are much more powerful and have a larger chance to spawn wielding a Trident.
+text.gm4.guidebook.monsters_unbound.description.elites,Zombies that spawn as babies or as leaders are replaced with a random Elite variant.\n\nSkeletons have a static 5% chance to be an Elite.
+text.gm4.guidebook.monsters_unbound.description.elite_zephyr,"Zephyr Elites can charge a powerful wind-charged attack. Damaging them during the charge time dissipates the charge. Zephyr Zombies will rush the player, Zephyr Skeletons fire a burst of arrows."
+text.gm4.guidebook.monsters_unbound.description.elite_blazing,Blazing Elites are slow and immune to burning. Their attacks deal little damage but have Fire Aspect II or Flame. Occasionally will spawn slow moving homing projectiles that explode on contact.
+text.gm4.guidebook.monsters_unbound.description.elite_gargantuan,Gargantuan Elites are much bigger and gain stats based on their missing health. Will occasionally perform an AoE stomp attack.
+text.gm4.guidebook.monsters_unbound.description.elite_glacial,Glacial Elites leave a sphere of frozen energy on death. This sphere explodes after 2 seconds freezing any entity inside for 3 seconds.
+text.gm4.guidebook.monsters_unbound.description.elite_mending,"Mending Elites will heal other undead mobs in their line of sight, this will never target other Mending Elites."
+text.gm4.guidebook.monsters_unbound.description.elite_pearlescent,"Pearescent Elites can shoot damaging lasers from their eyes, the laser is blocked by terrain."
+text.gm4.guidebook.monsters_unbound.description.elite_splitting,Splitting Elites split into 6 smaller and weaker versions of itself on death.
+text.gm4.guidebook.monsters_unbound.description.elite_volatile,"Volatile Elites create randomly targeted purple beams of energy around them that explode after a delay, dealing heavy magic damage."
+text.gm4.guidebook.monsters_unbound.description.elite_vorpal,"Vorpal Elites teleport randomly on getting hit. On death a homing skull will track the nearest player and apply Fear, which blinds and slows interactions."
+text.gm4.monsters_unbound.death.pearlescent_elite_laser,"%s was seen by %s"
+text.gm4.monsters_unbound.death.volatile_elite_meteorite,"%s was struck by a meteorite"
+text.gm4.monsters_unbound.death.blazing_elite_flare,"%s was blown up by a Blazing Flare"
diff --git a/gm4_survival_refightalized/README.md b/gm4_survival_refightalized/README.md
new file mode 100644
index 0000000000..56bf84febc
--- /dev/null
+++ b/gm4_survival_refightalized/README.md
@@ -0,0 +1,13 @@
+# Survival Refightalized
+
+A reworked survival experience with more varied mobs and new armor and shield mechanics.
+
+
+
+### Features:
+- Armor acts like a second health bar instead of reducing incoming damage.
+- Shields are disabled after being hit, adds the possibility to "parry" an attack.
+- Mobs scale with spawn location, being stronger lower down in the world.
+- Phantoms take damage if they try to fly into water, as they deserve.
+
+A full detailed list of all mechanics can be found at the [Wiki](https://wiki.gm4.co/Survival_Refightalized).
diff --git a/gm4_survival_refightalized/beet.yaml b/gm4_survival_refightalized/beet.yaml
new file mode 100644
index 0000000000..3959138376
--- /dev/null
+++ b/gm4_survival_refightalized/beet.yaml
@@ -0,0 +1,36 @@
+id: gm4_survival_refightalized
+name: Survival Refightalized
+version: 1.0.X
+
+data_pack:
+ load: .
+
+resource_pack:
+ load: .
+
+pipeline:
+ - gm4.plugins.extend.module
+ - gm4.plugins.include.lib_forceload
+ - gm4.plugins.include.lib_lore
+
+meta:
+ gm4:
+ versioning:
+ required:
+ lib_forceload: 1.3.0
+ lib_lore: 1.1.0
+ schedule_loops:
+ - tick
+ - main
+ - slow_clock
+ website:
+ description: A reworked survival experience with more varied mobs and new armor and shield mechanics.
+ recommended:
+ - gm4_monsters_unbound
+ video: null
+ wiki: https://wiki.gm4.co/wiki/Survival_Refightalized
+ credits:
+ Creator:
+ - Thanathor
+ Icon Design:
+ - Hozz
diff --git a/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_armor_damage.json b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_armor_damage.json
new file mode 100644
index 0000000000..9a30594664
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_armor_damage.json
@@ -0,0 +1,23 @@
+{
+ "display": {
+ "icon": {
+ "id": "minecraft:leather_chestplate"
+ },
+ "title": {
+ "translate": "advancement.gm4.survival_refightalized.armor_damage.title",
+ "fallback": "Armor Up!"
+ },
+ "description": {
+ "translate": "advancement.gm4.survival_refightalized.armor_damage.description",
+ "fallback": "Discover that Armor works a bit differently now",
+ "color": "gray"
+ },
+ "frame": "task"
+ },
+ "parent": "gm4:root",
+ "criteria": {
+ "full_set": {
+ "trigger": "minecraft:impossible"
+ }
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry.json b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry.json
new file mode 100644
index 0000000000..1d3a48a513
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry.json
@@ -0,0 +1,23 @@
+{
+ "display": {
+ "icon": {
+ "id": "minecraft:shield"
+ },
+ "title": {
+ "translate": "advancement.gm4.survival_refightalized.parry.title",
+ "fallback": "Not Today"
+ },
+ "description": {
+ "translate": "advancement.gm4.survival_refightalized.parry.description",
+ "fallback": "Parry with a Shield by blocking just before an attack",
+ "color": "gray"
+ },
+ "frame": "task"
+ },
+ "parent": "gm4:survival_refightalized_armor_damage",
+ "criteria": {
+ "full_set": {
+ "trigger": "minecraft:impossible"
+ }
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry_lethal_damage.json b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry_lethal_damage.json
new file mode 100644
index 0000000000..b5b1e77ff7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4/advancement/survival_refightalized_parry_lethal_damage.json
@@ -0,0 +1,27 @@
+{
+ "display": {
+ "icon": {
+ "id": "minecraft:shield",
+ "components": {
+ "minecraft:enchantment_glint_override": true
+ }
+ },
+ "title": {
+ "translate": "advancement.gm4.survival_refightalized.parry_lethal_damage.title",
+ "fallback": "Not Today, Either"
+ },
+ "description": {
+ "translate": "advancement.gm4.survival_refightalized.parry_lethal_damage.description",
+ "fallback": "Block lethal damage with a Shield Parry",
+ "color": "gray"
+ },
+ "frame": "challenge",
+ "hidden": true
+ },
+ "parent": "gm4:survival_refightalized_parry",
+ "criteria": {
+ "full_set": {
+ "trigger": "minecraft:impossible"
+ }
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/damaged.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/damaged.json
new file mode 100644
index 0000000000..06cdde48d6
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/damaged.json
@@ -0,0 +1,208 @@
+{
+ "criteria": {
+ "combat_damage": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "gm4_survival_refightalized:combat",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "armor_piercing": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "gm4_survival_refightalized:armor_piercing",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "armor_piercing_mob": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "source_entity": {
+ "nbt": "{Tags:[\"gm4_sr_stat.armor_pierce_attack\"]}"
+ }
+ }
+ }
+ }
+ },
+ "bypasses_enchantments": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "minecraft:bypasses_enchantments",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "is_fire": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "minecraft:is_fire",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "is_explosion": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "minecraft:is_explosion",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "is_fall": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "minecraft:is_fall",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "is_projectile": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "minecraft:is_projectile",
+ "expected": true
+ },
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "witch": {
+ "trigger": "minecraft:effects_changed",
+ "conditions": {
+ "effects": {
+ "minecraft:poison": {}
+ },
+ "source": {
+ "type": "minecraft:witch"
+ }
+ }
+ },
+ "cave_spider": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "source_entity": {
+ "type": "minecraft:cave_spider"
+ },
+ "type": {
+ "tags": [
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ },
+ "catch_other": {
+ "trigger": "minecraft:entity_hurt_player",
+ "conditions": {
+ "damage": {
+ "type": {
+ "tags": [
+ {
+ "id": "gm4_survival_refightalized:ignore",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "requirements": [
+ [
+ "combat_damage",
+ "armor_piercing",
+ "armor_piercing_mob",
+ "bypasses_enchantments",
+ "is_fire",
+ "is_fall",
+ "is_explosion",
+ "is_projectile",
+ "witch",
+ "cave_spider",
+ "catch_other"
+ ]
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/diamond_netherite.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/diamond_netherite.json
new file mode 100644
index 0000000000..21cac2dfc9
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/diamond_netherite.json
@@ -0,0 +1,99 @@
+{
+ "criteria": {
+ "diamond_helmet": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:diamond_helmet"
+ }
+ ]
+ }
+ },
+ "diamond_chestplate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:diamond_chestplate"
+ }
+ ]
+ }
+ },
+ "diamond_leggings": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:diamond_leggings"
+ }
+ ]
+ }
+ },
+ "diamond_boots": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:diamond_boots"
+ }
+ ]
+ }
+ },
+ "netherite_helmet": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:netherite_helmet"
+ }
+ ]
+ }
+ },
+ "netherite_chestplate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:netherite_chestplate"
+ }
+ ]
+ }
+ },
+ "netherite_leggings": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:netherite_leggings"
+ }
+ ]
+ }
+ },
+ "netherite_boots": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:netherite_boots"
+ }
+ ]
+ }
+ }
+ },
+ "requirements": [
+ [
+ "diamond_helmet",
+ "diamond_chestplate",
+ "diamond_leggings",
+ "diamond_boots",
+ "netherite_helmet",
+ "netherite_chestplate",
+ "netherite_leggings",
+ "netherite_boots"
+ ]
+ ],
+ "rewards": {
+ "function": "gm4_survival_refightalized:player/reach_tier/diamond_netherite"
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/iron_golden.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/iron_golden.json
new file mode 100644
index 0000000000..10d70096d3
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/reach_tier/iron_golden.json
@@ -0,0 +1,99 @@
+{
+ "criteria": {
+ "iron_helmet": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:iron_helmet"
+ }
+ ]
+ }
+ },
+ "iron_chestplate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:iron_chestplate"
+ }
+ ]
+ }
+ },
+ "iron_leggings": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:iron_leggings"
+ }
+ ]
+ }
+ },
+ "iron_boots": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:iron_boots"
+ }
+ ]
+ }
+ },
+ "golden_helmet": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:golden_helmet"
+ }
+ ]
+ }
+ },
+ "golden_chestplate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:golden_chestplate"
+ }
+ ]
+ }
+ },
+ "golden_leggings": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:golden_leggings"
+ }
+ ]
+ }
+ },
+ "golden_boots": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "items": "minecraft:golden_boots"
+ }
+ ]
+ }
+ }
+ },
+ "requirements": [
+ [
+ "iron_helmet",
+ "iron_chestplate",
+ "iron_leggings",
+ "iron_boots",
+ "golden_helmet",
+ "golden_chestplate",
+ "golden_leggings",
+ "golden_boots"
+ ]
+ ],
+ "rewards": {
+ "function": "gm4_survival_refightalized:player/reach_tier/iron_golden"
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_custom_shield.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_custom_shield.json
new file mode 100644
index 0000000000..e73956be7a
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_custom_shield.json
@@ -0,0 +1,21 @@
+{
+ "criteria": {
+ "custom_shield": {
+ "trigger": "minecraft:using_item",
+ "conditions": {
+ "item": {
+ "predicates": {
+ "minecraft:custom_data": {
+ "gm4_survival_refightalized": {
+ "shield": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "rewards": {
+ "function": "gm4_survival_refightalized:player/damage/shield/using"
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_vanilla_shield.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_vanilla_shield.json
new file mode 100644
index 0000000000..5b9d26724b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/advancement/using_vanilla_shield.json
@@ -0,0 +1,101 @@
+{
+ "criteria": {
+ "mainhand": {
+ "trigger": "minecraft:using_item",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "mainhand": {
+ "items": "shield"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "mainhand": {
+ "predicates": {
+ "minecraft:custom_data": {
+ "gm4_survival_refightalized": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "item": {
+ "items": "shield"
+ }
+ }
+ },
+ "offhand": {
+ "trigger": "minecraft:using_item",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "offhand": {
+ "items": "shield"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "offhand": {
+ "predicates": {
+ "minecraft:custom_data": {
+ "gm4_survival_refightalized": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "item": {
+ "items": "shield"
+ }
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mainhand",
+ "offhand"
+ ]
+ ],
+ "rewards": {
+ "function": "gm4_survival_refightalized:player/damage/shield/update_vanilla_shield"
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/check_arrow.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/check_arrow.mcfunction
new file mode 100644
index 0000000000..db369a2ced
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/check_arrow.mcfunction
@@ -0,0 +1,13 @@
+# check shot arrows
+# @s = arrow
+# at unspecified
+# run from tick
+
+# tag item as checked and try to process
+tag @s add gm4_sr_arrow_checked
+
+execute store result score $arrow_damage gm4_sr_data run data get entity @s damage 10
+tag @s add gm4_sr_current_arrow
+execute on origin if entity @s[type=#gm4_survival_refightalized:can_fire_arrows] run function gm4_survival_refightalized:mob/process/arrow/run
+tag @s remove gm4_sr_current_arrow
+execute unless score $arrow_damage gm4_sr_data matches 20 store result entity @s damage double 0.1 run scoreboard players get $arrow_damage gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/debug/dont_run/dev.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/debug/dont_run/dev.mcfunction
new file mode 100644
index 0000000000..31e015e4f1
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/debug/dont_run/dev.mcfunction
@@ -0,0 +1,19 @@
+# show stats of the closest modified mob
+# @s = modified mob
+# at player with gm4_sr_dev.mob_stats tag
+# run from player/player_submain
+
+execute store result score $dev.difficulty gm4_sr_data run scoreboard players get @s gm4_sr_mob.difficulty
+execute store result score $dev.health_max gm4_sr_data run attribute @s minecraft:max_health get 1
+execute store result score $dev.health_curr gm4_sr_data run data get entity @s Health
+execute store result score $worlddiff gm4_sr_data run difficulty
+execute if score $worlddiff gm4_sr_data matches 1 store result score $dev.damage gm4_sr_data run attribute @s minecraft:attack_damage get 77
+execute if score $worlddiff gm4_sr_data matches 2 store result score $dev.damage gm4_sr_data run attribute @s minecraft:attack_damage get 100
+execute if score $worlddiff gm4_sr_data matches 3 store result score $dev.damage gm4_sr_data run attribute @s minecraft:attack_damage get 150
+scoreboard players operation $dev.damage_10 gm4_sr_data = $dev.damage gm4_sr_data
+scoreboard players operation $dev.damage_10 gm4_sr_data /= #100 gm4_sr_data
+scoreboard players operation $dev.damage_1 gm4_sr_data = $dev.damage gm4_sr_data
+scoreboard players operation $dev.damage_1 gm4_sr_data %= #100 gm4_sr_data
+execute store result score $dev.speed gm4_sr_data run attribute @s minecraft:movement_speed get 100
+execute at @s run particle firework ~ ~1 ~ 0.2 0.5 0.2 0 3 force @p[tag=gm4_sr_dev.mob_stats]
+title @p[tag=gm4_sr_dev.mob_stats] actionbar [{"text":"Diff: ","color":"gray"},{"score":{"name":"$dev.difficulty","objective":"gm4_sr_data"},"color":"white"},{"text":" Health: ","color":"gray"},{"score":{"name":"$dev.health_curr","objective":"gm4_sr_data"},"color":"white"},{"text":"/","color":"white"},{"score":{"name":"$dev.health_max","objective":"gm4_sr_data"},"color":"white"},{"text":" Damage: "},{"score":{"name":"$dev.damage_10","objective":"gm4_sr_data"},"color":"white"},{"text":".","color":"white"},{"score":{"name":"$dev.damage_1","objective":"gm4_sr_data"},"color":"white"},{"text":" Speed: "},{"score":{"name":"$dev.speed","objective":"gm4_sr_data"},"color":"white"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/init.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/init.mcfunction
new file mode 100644
index 0000000000..20c1ac9ff5
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/init.mcfunction
@@ -0,0 +1,80 @@
+execute unless score survival_refightalized gm4_modules matches 1 run data modify storage gm4:log queue append value {type:"install",module:"Survival Refightalized"}
+execute unless score survival_refightalized gm4_earliest_version < survival_refightalized gm4_modules run scoreboard players operation survival_refightalized gm4_earliest_version = survival_refightalized gm4_modules
+scoreboard players set survival_refightalized gm4_modules 1
+
+# scoreboards
+scoreboard objectives add gm4_sr_data dummy
+scoreboard objectives add gm4_sr_config dummy
+
+scoreboard objectives add gm4_sr_mob.difficulty dummy
+scoreboard objectives add gm4_sr_mob.damage_cap dummy
+
+scoreboard objectives add gm4_sr_health.restoration dummy
+scoreboard objectives add gm4_sr_health.regeneration_timer dummy
+scoreboard objectives add gm4_sr_health.absorption_reduction_timer dummy
+
+scoreboard objectives add gm4_sr_stat.current_health dummy
+scoreboard objectives add gm4_sr_stat.max_health dummy
+scoreboard objectives add gm4_sr_stat.health_percentage dummy
+scoreboard objectives add gm4_sr_stat.current_absorption dummy
+scoreboard objectives add gm4_sr_stat.max_absorption dummy
+
+scoreboard objectives add gm4_sr_stat.armor_recharge_change dummy
+scoreboard objectives add gm4_sr_stat.regeneration_rate_change dummy
+
+scoreboard objectives add gm4_sr_stat.hunger food
+scoreboard objectives add gm4_sr_stat.damage_taken custom:damage_taken
+scoreboard objectives add gm4_sr_stat.damage_absorbed custom:damage_absorbed
+scoreboard objectives add gm4_sr_stat.damage_resisted custom:damage_resisted
+scoreboard objectives add gm4_sr_stat.damage_blocked custom:damage_blocked_by_shield
+scoreboard objectives add gm4_sr_stat.armor armor
+scoreboard objectives add gm4_sr_stat.deaths deathCount
+
+scoreboard objectives add gm4_sr_armor.tier dummy
+scoreboard objectives add gm4_sr_armor.reduction dummy
+scoreboard objectives add gm4_sr_armor.reduction_timer dummy
+
+scoreboard objectives add gm4_sr_arrow.fire_delay dummy
+scoreboard objectives add gm4_sr_arrow.fire_delay_left dummy
+scoreboard objectives add gm4_sr_arrow.damage_change dummy
+
+scoreboard objectives add gm4_sr_shield.spam_detection dummy
+scoreboard objectives add gm4_sr_shield.use_ticks dummy
+scoreboard objectives add gm4_sr_shield.timer dummy
+
+# configs
+execute unless score $natural_regen gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $natural_regen gm4_sr_config 1
+execute unless score $combat_regen_timer gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $combat_regen_timer gm4_sr_config 1250
+execute unless score $armor_recharge_timer gm4_sr_config matches -2147483648..2147483647 run scoreboard players set $armor_recharge_timer gm4_sr_config 625
+
+# swap natural regeneration to module's system
+execute unless score $natural_regen_disabled gm4_sr_data matches 1 run gamerule naturalRegeneration false
+execute unless score $natural_regen_disabled gm4_sr_data matches 1 run data modify storage gm4:log queue append value {type:"text",message:{"text":"[INFO] Survival Refightalized changed gamerule naturalRegeneration to false"}}
+scoreboard players set $natural_regen_disabled gm4_sr_data 1
+execute store result score $naturalregeneration gm4_sr_data run gamerule naturalRegeneration
+execute if score $natural_regen gm4_sr_config matches 1 if score $naturalregeneration gm4_sr_data matches 1 run data modify storage gm4:log queue append value {type:"text",message:[{"text":"[WARN]","color":"red"},{"text":" Survival Refightalized requires naturalRegeneration to be false, but it is true. ","color":"white"},{"text":"click here to fix","color":"red","clickEvent":{"action":"suggest_command","value":"/gamerule naturalRegeneration false"}}]}
+
+# constants
+scoreboard players set #-128 gm4_sr_data -128
+scoreboard players set #-50 gm4_sr_data -50
+scoreboard players set #0 gm4_sr_data 0
+scoreboard players set #1 gm4_sr_data 1
+scoreboard players set #2 gm4_sr_data 2
+scoreboard players set #4 gm4_sr_data 4
+scoreboard players set #5 gm4_sr_data 5
+scoreboard players set #8 gm4_sr_data 8
+scoreboard players set #10 gm4_sr_data 10
+scoreboard players set #20 gm4_sr_data 20
+scoreboard players set #25 gm4_sr_data 25
+scoreboard players set #50 gm4_sr_data 50
+scoreboard players set #60 gm4_sr_data 60
+scoreboard players set #80 gm4_sr_data 80
+scoreboard players set #100 gm4_sr_data 100
+scoreboard players set #300 gm4_sr_data 300
+scoreboard players set #1000 gm4_sr_data 1000
+scoreboard players set #1024 gm4_sr_data 1024
+
+# start clocks
+schedule function gm4_survival_refightalized:tick 1t
+schedule function gm4_survival_refightalized:main 2t
+schedule function gm4_survival_refightalized:slow_clock 3t
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/main.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/main.mcfunction
new file mode 100644
index 0000000000..dac509d09f
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/main.mcfunction
@@ -0,0 +1,17 @@
+schedule function gm4_survival_refightalized:main 16t
+
+# Inititate newly spawned mobs, as long as they are in the modify entity tag list
+execute as @e[type=#gm4_survival_refightalized:modify,tag=!smithed.entity,tag=!gm4_sr_processed,nbt=!{PersistenceRequired:1b}] at @s run function gm4_survival_refightalized:mob/init/check_mob
+schedule function gm4_survival_refightalized:mob/init/stat/check_damage_cap_schedule 1t
+
+# phantoms drown under water
+execute as @e[type=phantom,tag=!smithed.entity] at @s if block ~ ~ ~ #gm4:water run damage @s 2 drown
+
+# restore armor here as well as in player submain to make it happen every 8 ticks
+execute as @a[gamemode=!spectator,tag=gm4_sr_armor.reduction,scores={gm4_sr_armor.reduction_timer=..0}] run function gm4_survival_refightalized:player/armor/recharge
+
+# tick down skeleton arrow fire delay
+execute as @e[type=#gm4_survival_refightalized:can_fire_arrows,scores={gm4_sr_arrow.fire_delay_left=1..}] run function gm4_survival_refightalized:mob/process/arrow/clock_fire_delay
+
+# schedule player submain 8 ticks from now
+schedule function gm4_survival_refightalized:player_submain 8t
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_else.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_else.mcfunction
new file mode 100644
index 0000000000..b3f938baa7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_else.mcfunction
@@ -0,0 +1,17 @@
+# calc base difficulty for this mob and any spawns that originate from it
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/check_mob
+
+# use world difficulty to set base difficulty 10/25/50
+execute store result score $worlddiff gm4_sr_data run difficulty
+execute if score $worlddiff gm4_sr_data matches 3 run scoreboard players set $difficulty_base gm4_sr_data 50
+execute if score $worlddiff gm4_sr_data matches 2 run scoreboard players set $difficulty_base gm4_sr_data 25
+execute unless score $worlddiff gm4_sr_data matches 2..3 run scoreboard players set $difficulty_base gm4_sr_data 10
+
+# add at random 20-80
+execute store result score $random_add gm4_sr_data run random value 20..80
+scoreboard players operation $difficulty_base gm4_sr_data += $random_add gm4_sr_data
+
+# the rest of this function will also run for any additional spawns
+function gm4_survival_refightalized:mob/init/initiate
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_overworld.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_overworld.mcfunction
new file mode 100644
index 0000000000..1e6f402be8
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/calc_difficulty_overworld.mcfunction
@@ -0,0 +1,36 @@
+# calc base difficulty for this mob and any spawns that originate from it
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/check_mob
+
+# use world difficulty to set base difficulty 5/10/20
+execute store result score $worlddiff gm4_sr_data run difficulty
+execute if score $worlddiff gm4_sr_data matches 3 run scoreboard players set $difficulty_base gm4_sr_data 20
+execute if score $worlddiff gm4_sr_data matches 2 run scoreboard players set $difficulty_base gm4_sr_data 10
+execute unless score $worlddiff gm4_sr_data matches 2..3 run scoreboard players set $difficulty_base gm4_sr_data 5
+
+# not underground + raining +10
+execute if predicate gm4_survival_refightalized:technical/raining run scoreboard players add $difficulty_base gm4_sr_data 10
+# not underground + thundering (will also add the raining modifier) +15
+execute if predicate gm4_survival_refightalized:technical/thundering run scoreboard players add $difficulty_base gm4_sr_data 15
+# not underground + nighttime +0-20 based on moon phase (0 at new moon, 20 at full moon)
+scoreboard players operation $moon_diff_add gm4_sr_data = $moon gm4_sr_data
+scoreboard players operation $moon_diff_add gm4_sr_data *= #5 gm4_sr_data
+execute unless predicate gm4_survival_refightalized:mob/underground if predicate gm4_survival_refightalized:technical/night_time run scoreboard players operation $difficulty_base gm4_sr_data += $moon_diff_add gm4_sr_data
+
+# get depth the mob spawned at based on motion_blocking_no_leaves, subtract 16 to shift curve
+execute positioned over motion_blocking_no_leaves summon marker run function gm4_survival_refightalized:mob/init/get_world_surface
+execute store result score $mob_depth gm4_sr_data run data get entity @s Pos[1]
+scoreboard players operation $mob_depth gm4_sr_data -= $world_surface gm4_sr_data
+scoreboard players remove $mob_depth gm4_sr_data 16
+scoreboard players operation $mob_depth gm4_sr_data > #-128 gm4_sr_data
+scoreboard players operation $mob_depth gm4_sr_data < #0 gm4_sr_data
+
+# underground quadratic increase +0-80 based on mob depth
+scoreboard players operation $mob_depth gm4_sr_data *= $mob_depth gm4_sr_data
+scoreboard players operation $mob_depth gm4_sr_data *= #5 gm4_sr_data
+scoreboard players operation $mob_depth gm4_sr_data /= #1024 gm4_sr_data
+execute if predicate gm4_survival_refightalized:mob/underground if score $mob_depth gm4_sr_data matches 1.. run scoreboard players operation $difficulty_base gm4_sr_data += $mob_depth gm4_sr_data
+
+# the rest of this function will also run for any additional spawns
+function gm4_survival_refightalized:mob/init/initiate
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/check_mob.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/check_mob.mcfunction
new file mode 100644
index 0000000000..ad39c5fe32
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/check_mob.mcfunction
@@ -0,0 +1,17 @@
+# initiate newly spawned mobs (mobs without any tags)
+# @s = mobs that can be buffed
+# at @s
+# run from main
+
+# pre-mark mob as processed if it spawned in the air (from a spawner), these do not get modified
+# mobs in the modify_in_air list are ignored here
+execute if block ~ ~-0.01 ~ #gm4:no_collision run tag @s[type=!#gm4_survival_refightalized:modify_in_air] add gm4_sr_processed
+
+# if the mob is riding another mob *do* modify them
+scoreboard players set $mounted gm4_sr_data 0
+execute if entity @s[tag=gm4_sr_processed] on vehicle run scoreboard players set $mounted gm4_sr_data 1
+execute if score $mounted gm4_sr_data matches 1 run tag @s remove gm4_sr_processed
+
+# initiate unless mob is pre-marked
+execute unless entity @s[tag=gm4_sr_processed] if dimension minecraft:overworld run function gm4_survival_refightalized:mob/init/calc_difficulty_overworld
+execute unless entity @s[tag=gm4_sr_processed] unless dimension minecraft:overworld run function gm4_survival_refightalized:mob/init/calc_difficulty_else
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/get_world_surface.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/get_world_surface.mcfunction
new file mode 100644
index 0000000000..19f09d95ca
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/get_world_surface.mcfunction
@@ -0,0 +1,7 @@
+# get y level of world surface (motion blocking no leaves)
+# @s = marker
+# at @s
+# run from mob/init/calc_difficulty_overworld
+
+execute store result score $world_surface gm4_sr_data run data get entity @s Pos[1]
+kill @s
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/initiate.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/initiate.mcfunction
new file mode 100644
index 0000000000..0705fbea8e
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/initiate.mcfunction
@@ -0,0 +1,57 @@
+# initiate newly spawned mobs (mobs without any tags)
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/calc_difficulty_else
+# run from mob/init/calc_difficulty_overworld
+# run from here
+
+# get the highest armor tier from closest player
+scoreboard players operation $armor_tier gm4_sr_data = @p gm4_sr_armor.tier
+
+# get difficulty data in score
+scoreboard players operation $difficulty gm4_sr_data = $difficulty_base gm4_sr_data
+execute store result score $difficulty_mult gm4_sr_data run random value -35..35
+execute store result score $difficulty_flat gm4_sr_data run random value -15..15
+# function tag so other modules can modify the difficulty
+function #gm4_survival_refightalized:init_difficulty
+
+# apply a random difficulty_mult to nudge difficulty around
+scoreboard players operation $difficulty_add gm4_sr_data = $difficulty gm4_sr_data
+scoreboard players operation $difficulty_add gm4_sr_data *= $difficulty_mult gm4_sr_data
+scoreboard players operation $difficulty_add gm4_sr_data /= #100 gm4_sr_data
+scoreboard players operation $difficulty gm4_sr_data += $difficulty_add gm4_sr_data
+# apply a random difficulty_flat to nudge difficulty around
+scoreboard players operation $difficulty gm4_sr_data += $difficulty_flat gm4_sr_data
+
+# make sure difficulty is between 0 - 100
+scoreboard players operation $difficulty gm4_sr_data > #0 gm4_sr_data
+scoreboard players operation $difficulty gm4_sr_data < #100 gm4_sr_data
+
+# store difficulty on mob
+scoreboard players operation @s gm4_sr_mob.difficulty = $difficulty gm4_sr_data
+
+# reset scoreboard
+scoreboard players reset $mob_extras gm4_sr_data
+# initialize different mobs
+function gm4_survival_refightalized:mob/init/mob_type
+# allow expansions to alter mobs
+function #gm4_survival_refightalized:init_mob
+
+# remove the damage bonus from hard difficulty if needed
+# ( Hard normally adds a x1.5 damage multiplier, this counteracts that so mobs can be better tuned )
+execute if score $worlddiff gm4_sr_data matches 3 run attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.hard_difficulty_offset -0.333334 add_multiplied_total
+
+# set modifiers
+execute unless score $removed_mob gm4_sr_data matches 1 run function gm4_survival_refightalized:mob/init/stat/prep
+scoreboard players reset $removed_mob gm4_sr_data
+
+# heal to max health
+effect give @s[type=#minecraft:undead] instant_damage 1 20 true
+effect give @s[type=!#minecraft:undead] instant_health 1 20 true
+
+# mark mob as initiated
+tag @s add gm4_sr_processed
+
+# process any spawned mobs
+execute if score $mob_extras gm4_sr_data matches 1.. unless entity @s[tag=gm4_sr_extra_mob] as @e[type=#gm4_survival_refightalized:modify,tag=gm4_sr_extra_mob] at @s run function gm4_survival_refightalized:mob/init/initiate
+tag @s remove gm4_sr_extra_mob
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type.mcfunction
new file mode 100644
index 0000000000..40483ada79
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type.mcfunction
@@ -0,0 +1,23 @@
+# check what mob is being processed
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/initiate
+
+# these are reset to 0, otherwise if the spawn function fails it can cause a crash due constantly increasing scores
+scoreboard players set $mob_health gm4_sr_data 0
+scoreboard players set $mob_damage gm4_sr_data 0
+scoreboard players set $mob_speed gm4_sr_data 0
+
+# zombie, zombie_villager, husk, drowned
+execute if entity @s[type=#gm4_survival_refightalized:zombie_types] run return run function gm4_survival_refightalized:mob/init/mob_type/zombie
+# skeleton, bogged, stray
+execute if entity @s[type=#gm4_survival_refightalized:skeleton_types,type=!wither_skeleton] run return run function gm4_survival_refightalized:mob/init/mob_type/skeleton
+execute if entity @s[type=spider] run return run function gm4_survival_refightalized:mob/init/mob_type/spider
+execute if entity @s[type=creeper] run return run function gm4_survival_refightalized:mob/init/mob_type/creeper
+execute if entity @s[type=cave_spider] run return run function gm4_survival_refightalized:mob/init/mob_type/spider
+execute if entity @s[type=enderman] run return run function gm4_survival_refightalized:mob/init/mob_type/enderman
+execute if entity @s[type=wither_skeleton] run return run function gm4_survival_refightalized:mob/init/mob_type/wither_skeleton
+execute if entity @s[type=phantom] run return run function gm4_survival_refightalized:mob/init/mob_type/phantom
+execute if entity @s[type=piglin] run return run function gm4_survival_refightalized:mob/init/mob_type/piglin
+execute if entity @s[type=zombified_piglin] run return run function gm4_survival_refightalized:mob/init/mob_type/zombified_piglin
+execute if entity @s[type=silverfish] run return run function gm4_survival_refightalized:mob/init/mob_type/silverfish
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/cave_spider.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/cave_spider.mcfunction
new file mode 100644
index 0000000000..423015ca4c
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/cave_spider.mcfunction
@@ -0,0 +1,19 @@
+# calculate modifiers for newly spawned cave spider
+# @s = cave spider
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 4 - 12
+# damage: 0.5 - 1.5
+# speed: 90 - 135%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -8 add_value
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -1.5 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.1 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 8
+scoreboard players set $mob_damage gm4_sr_data 10
+scoreboard players set $mob_speed gm4_sr_data 45
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/creeper.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/creeper.mcfunction
new file mode 100644
index 0000000000..24b077b679
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/creeper.mcfunction
@@ -0,0 +1,18 @@
+# calculate modifiers for newly spawned creeper
+# @s = creeper
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 12 - 24
+# damage: explosion
+# speed: 90 - 125%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -8 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.1 add_value
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 12
+scoreboard players set $mob_damage gm4_sr_data 0
+scoreboard players set $mob_speed gm4_sr_data 35
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/enderman.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/enderman.mcfunction
new file mode 100644
index 0000000000..e06fc19bcb
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/enderman.mcfunction
@@ -0,0 +1,18 @@
+# calculate modifiers for newly spawned enderman
+# @s = enderman
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 40 - 55
+# damage: 5 - 8
+# speed: 90 - 125%
+
+# base stat nerf
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -2 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.1 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 15
+scoreboard players set $mob_damage gm4_sr_data 30
+scoreboard players set $mob_speed gm4_sr_data 35
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/phantom.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/phantom.mcfunction
new file mode 100644
index 0000000000..79fc4db8e1
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/phantom.mcfunction
@@ -0,0 +1,18 @@
+# calculate modifiers for newly spawned phantom
+# @s = phantom
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 4 - 16
+# damage: 1.5 - 4
+# speed: 100%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -16 add_value
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -0.5 add_value
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 12
+scoreboard players set $mob_damage gm4_sr_data 35
+scoreboard players set $mob_speed gm4_sr_data 0
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/piglin.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/piglin.mcfunction
new file mode 100644
index 0000000000..b035c91f07
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/piglin.mcfunction
@@ -0,0 +1,30 @@
+# calculate modifiers for newly spawned piglin
+# @s = piglin
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 16 - 32
+# damage: 5 - 7 (melee), 2 - 4 (unarmed)
+# speed: 80 - 115%
+
+# base stat nerf
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -3 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.2 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 16
+scoreboard players set $mob_damage gm4_sr_data 20
+scoreboard players set $mob_speed gm4_sr_data 35
+# max damage mob is allowed to deal in one hit (to deal with weapons)
+scoreboard players set @s gm4_sr_mob.damage_cap 70
+tag @s add gm4_sr_check_damage_cap
+
+# set armor
+scoreboard players set $override_equipment gm4_sr_data 0
+function #gm4_survival_refightalized:equip/piglin
+execute if score $override_equipment gm4_sr_data matches 1 run return 1
+loot replace entity @s armor.feet loot gm4_survival_refightalized:mob/piglin/feet
+loot replace entity @s armor.legs loot gm4_survival_refightalized:mob/piglin/legs
+loot replace entity @s armor.chest loot gm4_survival_refightalized:mob/piglin/chest
+loot replace entity @s armor.head loot gm4_survival_refightalized:mob/piglin/head
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/silverfish.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/silverfish.mcfunction
new file mode 100644
index 0000000000..dc806713b3
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/silverfish.mcfunction
@@ -0,0 +1,32 @@
+# calculate modifiers for newly spawned silverfish
+# @s = silverfish
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 1 - 6
+# damage: 1 - 2.5
+# speed: 80 - 120%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -7 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.2 add_multiplied_total
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 5
+scoreboard players set $mob_damage gm4_sr_data 15
+scoreboard players set $mob_speed gm4_sr_data 40
+
+# size changes
+execute store result score $size_change gm4_sr_data run random value 1..100
+# normal (+20% speed)
+execute if score $size_change gm4_sr_data matches ..50 run attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.random_scale 0.2 add_multiplied_total
+# medium (+0.25 scale)
+execute if score $size_change gm4_sr_data matches 51..75 run attribute @s minecraft:scale modifier add gm4_survival_refightalized:stat_change.random_scale 0.25 add_value
+# large (+0.5 scale, +2 health)
+execute if score $size_change gm4_sr_data matches 76..90 run attribute @s minecraft:scale modifier add gm4_survival_refightalized:stat_change.random_scale 0.5 add_value
+execute if score $size_change gm4_sr_data matches 76..90 run attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.random_scale 2 add_value
+# giant (+0.75 scale, +4 health, +1 damage)
+execute if score $size_change gm4_sr_data matches 90..100 run attribute @s minecraft:scale modifier add gm4_survival_refightalized:stat_change.random_scale 0.75 add_value
+execute if score $size_change gm4_sr_data matches 90..100 run attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.random_scale 4 add_value
+execute if score $size_change gm4_sr_data matches 90..100 run attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.random_scale 1 add_value
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/skeleton.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/skeleton.mcfunction
new file mode 100644
index 0000000000..930979cd11
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/skeleton.mcfunction
@@ -0,0 +1,37 @@
+# calculate modifiers for newly spawned skeleton / stray / bogged
+# @s = skeleton / stray / bogged
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 9 - 22
+# damage: 2 - 6.5 (cap 7)
+# speed: 75 - 105%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -11 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.25 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 13
+scoreboard players set $mob_damage gm4_sr_data 45
+scoreboard players set $mob_speed gm4_sr_data 30
+# max damage mob is allowed to deal in one hit (to deal with weapons)
+scoreboard players set @s gm4_sr_mob.damage_cap 70
+tag @s add gm4_sr_check_damage_cap
+
+# arrow damage - only set if it was not preset at spawning
+execute unless score @s gm4_sr_arrow.damage_change matches -2147483648..2147483647 store result score @s gm4_sr_arrow.damage_change run random value -4..4
+execute unless score @s gm4_sr_arrow.fire_delay matches -2147483648..2147483647 store result score @s gm4_sr_arrow.damage_change run random value -4..4
+
+# set weapon
+loot replace entity @s[tag=!gm4_sr_melee_skeleton] weapon.mainhand loot gm4_survival_refightalized:mob/skeleton/weapon
+
+# set armor
+scoreboard players set $override_equipment gm4_sr_data 0
+function #gm4_survival_refightalized:equip/skeleton
+execute if score $override_equipment gm4_sr_data matches 1 run return 1
+loot replace entity @s armor.feet loot gm4_survival_refightalized:mob/generic/feet
+loot replace entity @s armor.legs loot gm4_survival_refightalized:mob/generic/legs
+loot replace entity @s armor.chest loot gm4_survival_refightalized:mob/generic/chest
+loot replace entity @s armor.head loot gm4_survival_refightalized:mob/generic/head
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/spider.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/spider.mcfunction
new file mode 100644
index 0000000000..0103a3270f
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/spider.mcfunction
@@ -0,0 +1,18 @@
+# calculate modifiers for newly spawned spider
+# @s = spider
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 12 - 30
+# damage: 2 - 5.5
+# speed: 95 - 145%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -4 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.05 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 18
+scoreboard players set $mob_damage gm4_sr_data 35
+scoreboard players set $mob_speed gm4_sr_data 50
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/wither_skeleton.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/wither_skeleton.mcfunction
new file mode 100644
index 0000000000..b77366b6c4
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/wither_skeleton.mcfunction
@@ -0,0 +1,44 @@
+# calculate modifiers for newly spawned wither skeleton
+# @s = wither skeleton
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 22 - 36
+# damage: 6.5 - 8.5 (armed), 0.5 - 2.5 (unarmed)
+# speed: 95 - 120%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_buff 2 add_value
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -1.5 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.05 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 14
+scoreboard players set $mob_damage gm4_sr_data 20
+scoreboard players set $mob_speed gm4_sr_data 25
+# max damage mob is allowed to deal in one hit (to deal with weapons)
+scoreboard players set @s gm4_sr_mob.damage_cap 85
+tag @s add gm4_sr_check_damage_cap
+
+# knockback resistance
+attribute @s minecraft:knockback_resistance modifier add gm4_survival_refightalized:stat_change.kb_resist 0.666 add_value
+
+# set weapon
+loot replace entity @s weapon.mainhand loot gm4_survival_refightalized:mob/wither_skeleton/weapon
+
+# withering arrow if a bow is held
+execute if items entity @s weapon.mainhand bow run loot replace entity @s weapon.offhand loot gm4_survival_refightalized:mob/wither_skeleton/arrow
+
+# shoot arrows slower and weaker
+scoreboard players set @s gm4_sr_arrow.fire_delay 4
+execute store result score @s gm4_sr_arrow.damage_change run random value -6..0
+
+# set armor
+scoreboard players set $override_equipment gm4_sr_data 0
+function #gm4_survival_refightalized:equip/wither_skeleton
+execute if score $override_equipment gm4_sr_data matches 1 run return 1
+loot replace entity @s armor.feet loot gm4_survival_refightalized:mob/wither_skeleton/feet
+loot replace entity @s armor.legs loot gm4_survival_refightalized:mob/wither_skeleton/legs
+loot replace entity @s armor.chest loot gm4_survival_refightalized:mob/wither_skeleton/chest
+loot replace entity @s armor.head loot gm4_survival_refightalized:mob/wither_skeleton/head
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombie.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombie.mcfunction
new file mode 100644
index 0000000000..97dd926890
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombie.mcfunction
@@ -0,0 +1,41 @@
+# calculate modifiers for newly spawned zombie / zombie villager / husk / drowned
+# @s = zombie / zombie villager / husk / drowned
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 18 - 36
+# damage: 3 - 6.5 (cap 8)
+# speed: 80 - 120%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -2 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.2 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 18
+scoreboard players set $mob_damage gm4_sr_data 35
+scoreboard players set $mob_speed gm4_sr_data 40
+# max damage mob is allowed to deal in one hit (to deal with weapons)
+scoreboard players set @s gm4_sr_mob.damage_cap 80
+tag @s add gm4_sr_check_damage_cap
+
+# add fire delay to drowned for tridents
+scoreboard players set @s[type=drowned] gm4_sr_arrow.fire_delay 10
+
+# remove leader bonus from zombies
+execute if data entity @s attributes[{id:"minecraft:max_health"}].modifiers[{id:"minecraft:leader_zombie_bonus"}] run attribute @s minecraft:max_health modifier remove minecraft:leader_zombie_bonus
+
+# remove baby zombies except chicken jockeys (will be turned into Elites with Monsters Unbound)
+scoreboard players set $was_baby gm4_sr_data 0
+execute if predicate {condition:"all_of",terms:[{condition:"entity_properties",entity:"this",predicate:{flags:{is_baby:1b}}},{condition:"inverted",term:{condition:"entity_properties",entity:"this",predicate:{vehicle:{}}}}]} store success score $was_baby gm4_sr_data run data modify entity @s IsBaby set value 0b
+execute if score $was_baby gm4_sr_data matches 1 run tag @s add gm4_sr_was_baby
+
+# set armor
+scoreboard players set $override_equipment gm4_sr_data 0
+function #gm4_survival_refightalized:equip/zombie
+execute if score $override_equipment gm4_sr_data matches 1 run return 1
+loot replace entity @s armor.feet loot gm4_survival_refightalized:mob/generic/feet
+loot replace entity @s armor.legs loot gm4_survival_refightalized:mob/generic/legs
+loot replace entity @s armor.chest loot gm4_survival_refightalized:mob/generic/chest
+loot replace entity @s armor.head loot gm4_survival_refightalized:mob/generic/head
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombified_piglin.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombified_piglin.mcfunction
new file mode 100644
index 0000000000..194cd84070
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/mob_type/zombified_piglin.mcfunction
@@ -0,0 +1,25 @@
+# calculate modifiers for newly spawned zombified piglin
+# @s = zombified piglin
+# at @s
+# run from mob/init/mob_type
+
+## Stat Block (normal/hard diff)
+# health: 14 - 20
+# damage: 3.5 - 5 (armed), 0.5 - 2 (unarmed)
+# speed: 90 - 140%
+
+# base stat nerf
+attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.base_nerf -6 add_value
+attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.base_nerf -4.5 add_value
+attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.base_nerf -0.1 add_multiplied_base
+
+# max stat buffs
+scoreboard players set $mob_health gm4_sr_data 18
+scoreboard players set $mob_damage gm4_sr_data 15
+scoreboard players set $mob_speed gm4_sr_data 50
+# max damage mob is allowed to deal in one hit (to deal with weapons)
+scoreboard players set @s gm4_sr_mob.damage_cap 60
+tag @s add gm4_sr_check_damage_cap
+
+# remove zombie leader bonus
+execute if data entity @s attributes[{id:"minecraft:max_health"}].modifiers[{id:"minecraft:leader_zombie_bonus"}] run attribute @s minecraft:max_health modifier remove minecraft:leader_zombie_bonus
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap.mcfunction
new file mode 100644
index 0000000000..50054a3177
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap.mcfunction
@@ -0,0 +1,13 @@
+# cap damage mobs can do
+# @s = mob with gm4_sr_check_damage_cap tag
+# at unspecified
+# run from mob/init/modifier/check_damage_cap_schedule
+
+tag @s remove gm4_sr_check_damage_cap
+
+# check if damage did not exceed the cap, otherwise reduce to get back to it
+execute if score $worlddiff gm4_sr_data matches ..2 store result score $mob_total_damage gm4_sr_data run attribute @s minecraft:attack_damage get 10
+execute if score $worlddiff gm4_sr_data matches 3 store result score $mob_total_damage gm4_sr_data run attribute @s minecraft:attack_damage get 15
+execute store result storage gm4_survival_refightalized:temp picked_stat.damage_capped float 0.1 run scoreboard players operation @s gm4_sr_mob.damage_cap -= $mob_total_damage gm4_sr_data
+execute if score @s gm4_sr_mob.damage_cap matches ..-1 run function gm4_survival_refightalized:mob/init/stat/eval_damage_cap with storage gm4_survival_refightalized:temp picked_stat
+data remove storage gm4_survival_refightalized:temp picked_stat
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap_schedule.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap_schedule.mcfunction
new file mode 100644
index 0000000000..cf62294032
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/check_damage_cap_schedule.mcfunction
@@ -0,0 +1,6 @@
+# schedule damage cap check 1t later to allow mainhand changes to apply
+# @s = unspecified
+# at unspecified
+# schedule from main
+
+execute as @e[tag=gm4_sr_check_damage_cap] run function gm4_survival_refightalized:mob/init/stat/check_damage_cap
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval.mcfunction
new file mode 100644
index 0000000000..125f1c8913
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval.mcfunction
@@ -0,0 +1,8 @@
+# evaluate stats
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/modifier/stat/prep
+
+$execute if score $mob_health gm4_sr_data matches 1.. run attribute @s minecraft:max_health modifier add gm4_survival_refightalized:stat_change.difficulty_buff $(health) add_value
+$execute if score $mob_damage gm4_sr_data matches 1.. run attribute @s minecraft:attack_damage modifier add gm4_survival_refightalized:stat_change.difficulty_buff $(damage) add_value
+$execute if score $mob_speed gm4_sr_data matches 1.. run attribute @s minecraft:movement_speed modifier add gm4_survival_refightalized:stat_change.difficulty_buff $(speed) add_multiplied_base
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval_damage_cap.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval_damage_cap.mcfunction
new file mode 100644
index 0000000000..0e0d0310d1
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/eval_damage_cap.mcfunction
@@ -0,0 +1,7 @@
+# cap damage to this mobs cap
+# @s = mob with gm4_sr_check_damage_cap tag
+# at unspecified
+# run from mob/init/modifier/check_damage_cap
+
+$attribute @s attack_damage modifier add gm4_survival_refightalized:stat_change.damage_cap_reduction $(damage_capped) add_value
+tag @s add gm4_sr_mob.damage_capped
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/prep.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/prep.mcfunction
new file mode 100644
index 0000000000..d06e6c3c3b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/init/stat/prep.mcfunction
@@ -0,0 +1,29 @@
+# randomize mob stats
+# @s = mobs that can be buffed
+# at @s
+# run from mob/init/initiate
+
+# remove bonus health if enderman spawned in end
+execute if entity @s[type=enderman] if dimension the_end run scoreboard players set $mob_health gm4_sr_data 0
+# remove bonus damage if melee weapon is held
+execute if predicate gm4_survival_refightalized:mob/has_weapon run scoreboard players set $mob_damage gm4_sr_data 0
+
+# randomise stats - set values based on:
+# HEALTH = 0.5*score + BINOMDIST(n=0.5*score,p=0.5)
+execute if score $mob_health gm4_sr_data matches 1.. store result score $mob_health gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:randomize_stats/health
+# DAMAGE = 0.15*score + RANDOM(0 - 0.35*score) + BINOMDIST(n=0.5*score,p=0.5)
+execute if score $mob_damage gm4_sr_data matches 1.. store result score $mob_damage gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:randomize_stats/damage
+# SPEED = RANDOM(0 - 0.5*score) + BINOMDIST(n=0.5*score,p=0.5)
+execute if score $mob_speed gm4_sr_data matches 1.. store result score $mob_speed gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:randomize_stats/speed
+execute positioned ~ -4064 ~ run kill @e[type=item,distance=..1]
+
+# store modifiers modified by difficulty
+execute if score $difficulty gm4_sr_data matches 101.. run say problem difficuly
+
+execute store result storage gm4_survival_refightalized:temp picked_stat.health float 0.01 run scoreboard players operation $mob_health gm4_sr_data *= $difficulty gm4_sr_data
+execute store result storage gm4_survival_refightalized:temp picked_stat.damage float 0.001 run scoreboard players operation $mob_damage gm4_sr_data *= $difficulty gm4_sr_data
+execute store result storage gm4_survival_refightalized:temp picked_stat.speed float 0.0001 run scoreboard players operation $mob_speed gm4_sr_data *= $difficulty gm4_sr_data
+
+# evaluate stats and add modifiers to mob
+function gm4_survival_refightalized:mob/init/stat/eval with storage gm4_survival_refightalized:temp picked_stat
+data remove storage gm4_survival_refightalized:temp picked_stat
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/clock_fire_delay.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/clock_fire_delay.mcfunction
new file mode 100644
index 0000000000..7bbc4cfc2b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/clock_fire_delay.mcfunction
@@ -0,0 +1,7 @@
+# tick down arrow fire delay
+# @s = entity that shot an arrow
+# at unspecified
+# run from main
+
+scoreboard players remove @s gm4_sr_arrow.fire_delay_left 1
+attribute @s[scores={gm4_sr_arrow.fire_delay_left=0}] minecraft:follow_range modifier remove gm4_survival_refightalized:arrow_fire_delay
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/run.mcfunction
new file mode 100644
index 0000000000..a094874340
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/mob/process/arrow/run.mcfunction
@@ -0,0 +1,15 @@
+# modify shot arrows
+# @s = arrow
+# at unspecified
+# run from check_arrow
+
+# if origin is a player run function tag for expansions
+execute if entity @s[type=player] run return run function #gm4_survival_refightalized:player_fired_arrow
+
+# | Non-players:
+# add damage to arrow
+scoreboard players operation $arrow_damage gm4_sr_data += @s gm4_sr_arrow.damage_change
+# add fire delay
+# ( A modifier that removes all follow_range is added to stop the entity from firing more arrows)
+scoreboard players operation @s gm4_sr_arrow.fire_delay_left = @s gm4_sr_arrow.fire_delay
+attribute @s[scores={gm4_sr_arrow.fire_delay_left=1..}] minecraft:follow_range modifier add gm4_survival_refightalized:arrow_fire_delay -1 add_multiplied_total
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/eval_reduction.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/eval_reduction.mcfunction
new file mode 100644
index 0000000000..6f0f2f62e6
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/eval_reduction.mcfunction
@@ -0,0 +1,11 @@
+# reduce absorption hearts on player based on their score
+# @s = damaged player
+# at @s
+# run from player/damage/calculate_damage
+
+$attribute @s max_absorption modifier add gm4_sr_absorption_reduced -$(absorption_reduction) add_value
+# restore absorption cap after 4 ticks to let it remove the health properly
+scoreboard players set @s gm4_sr_health.absorption_reduction_timer 3
+schedule function gm4_survival_refightalized:player/absorption/restore_clock 1t
+
+scoreboard players reset $damage_absorption gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/restore_clock.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/restore_clock.mcfunction
new file mode 100644
index 0000000000..dcd1a50b6d
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/absorption/restore_clock.mcfunction
@@ -0,0 +1,10 @@
+# restore absorption hearts cap
+# @s = unspecified
+# at unspecified
+# schedule from player/absorption/eval_reduction
+# schedule from here
+
+execute as @a[scores={gm4_sr_health.absorption_reduction_timer=1}] run attribute @s minecraft:max_absorption modifier remove gm4_sr_absorption_reduced
+scoreboard players remove @a[scores={gm4_sr_health.absorption_reduction_timer=1..}] gm4_sr_health.absorption_reduction_timer 1
+
+execute if entity @a[scores={gm4_sr_health.absorption_reduction_timer=1..}] run schedule function gm4_survival_refightalized:player/absorption/restore_clock 1t
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/break.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/break.mcfunction
new file mode 100644
index 0000000000..ba42956465
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/break.mcfunction
@@ -0,0 +1,11 @@
+# armor is reduced to 0
+# @s = damaged player
+# at @s
+# run from player/damage/calculate_damage
+
+playsound minecraft:entity.armor_stand.break player @a[distance=..8] ~ ~ ~ 0.66 0 0.5
+function gm4_survival_refightalized:player/resistance/remove
+function #gm4_survival_refightalized:armor_break
+
+# set damage taken to the amount of armor remaining so it gets removed
+scoreboard players operation $damage_armor gm4_sr_data = $player_armor gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/check.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/check.mcfunction
new file mode 100644
index 0000000000..0392f36cfd
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/check.mcfunction
@@ -0,0 +1,30 @@
+# apply durability damage on armor item
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# get item data
+item replace block 29999998 1 7134 container.0 from entity @s armor.head
+item replace block 29999998 1 7134 container.1 from entity @s armor.chest
+item replace block 29999998 1 7134 container.2 from entity @s armor.legs
+item replace block 29999998 1 7134 container.3 from entity @s armor.feet
+data modify storage gm4_survival_refightalized:temp Items set from block 29999998 1 7134 Items
+
+execute if items block 29999998 1 7134 container.0 * run function gm4_survival_refightalized:player/armor/durability/head/run
+execute if items block 29999998 1 7134 container.1 * run function gm4_survival_refightalized:player/armor/durability/chest/run
+execute if items block 29999998 1 7134 container.2 * run function gm4_survival_refightalized:player/armor/durability/legs/run
+execute if items block 29999998 1 7134 container.3 * run function gm4_survival_refightalized:player/armor/durability/feet/run
+
+# stopsounds
+stopsound @s player item.armor.equip_chain
+stopsound @s player item.armor.equip_diamond
+stopsound @s player item.armor.equip_generic
+stopsound @s player item.armor.equip_gold
+stopsound @s player item.armor.equip_iron
+stopsound @s player item.armor.equip_leather
+stopsound @s player item.armor.equip_netherite
+stopsound @s player item.armor.equip_turtle
+
+# cleanup
+data remove block 29999998 1 7134 Items
+data remove storage gm4_survival_refightalized:temp Items
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/break.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/break.mcfunction
new file mode 100644
index 0000000000..1761150739
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/break.mcfunction
@@ -0,0 +1,7 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/chest/run
+
+playsound minecraft:entity.item.break player @s ~ ~ ~ 1 1
+item replace entity @s armor.chest with air
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/eval.mcfunction
new file mode 100644
index 0000000000..440125c75b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/eval.mcfunction
@@ -0,0 +1,6 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/chest/run
+
+$item modify entity @s armor.chest {function:"minecraft:set_components",components:{"minecraft:damage":$(damage)}}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/find_durability.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/find_durability.mcfunction
new file mode 100644
index 0000000000..529903fcdd
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/find_durability.mcfunction
@@ -0,0 +1,11 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/chest/run
+
+execute if items block 29999998 1 7134 container.1 leather_chestplate run return 80
+execute if items block 29999998 1 7134 container.1 golden_chestplate run return 112
+execute if items block 29999998 1 7134 container.1 chainmail_chestplate run return 240
+execute if items block 29999998 1 7134 container.1 iron_chestplate run return 240
+execute if items block 29999998 1 7134 container.1 diamond_chestplate run return 528
+execute if items block 29999998 1 7134 container.1 netherite_chestplate run return 592
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/run.mcfunction
new file mode 100644
index 0000000000..4d999912a2
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/chest/run.mcfunction
@@ -0,0 +1,38 @@
+# apply durability damage on armor item
+# @s = damaged player
+# at @s
+# run from player/armor/durability/check
+
+# if unbreakable don't run
+execute if data storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:unbreakable" run return 0
+
+# calculate incoming damage based on unbreaking
+execute store result score $unbreaking_level gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:unbreaking"
+scoreboard players add $unbreaking_level gm4_sr_data 1
+scoreboard players set $damage_chance gm4_sr_data 100
+scoreboard players operation $damage_chance gm4_sr_data /= $unbreaking_level gm4_sr_data
+scoreboard players set $damage_opportunities gm4_sr_data 1
+execute store result score $incoming_damage gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:technical/roll_damage
+execute positioned ~ -4064 ~ run kill @e[type=item,distance=..1]
+
+# if no damage is going to be applied cancel function
+execute unless score $incoming_damage gm4_sr_data matches 1.. run return 0
+
+# find the total durability of this item
+execute store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:max_damage"
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:custom_data".gm4_augmented_armor.durability
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run function gm4_survival_refightalized:player/armor/durability/chest/find_durability
+execute if score $total_durability gm4_sr_data matches 0 run return 0
+
+# add incoming damage to the current damage
+execute store result score $current_damage gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:damage"
+scoreboard players operation $current_damage gm4_sr_data += $incoming_damage gm4_sr_data
+execute if score $current_damage gm4_sr_data > $total_durability gm4_sr_data run return run function gm4_survival_refightalized:player/armor/durability/chest/break
+
+# apply to armor
+execute store result storage gm4_survival_refightalized:temp set.damage int 1 run scoreboard players get $current_damage gm4_sr_data
+function gm4_survival_refightalized:player/armor/durability/chest/eval with storage gm4_survival_refightalized:temp set
+
+# cleanup
+data remove storage gm4_survival_refightalized:temp set
+scoreboard players reset $total_durability gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/break.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/break.mcfunction
new file mode 100644
index 0000000000..83edf25ae8
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/break.mcfunction
@@ -0,0 +1,7 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/feet/run
+
+playsound minecraft:entity.item.break player @s ~ ~ ~ 1 1
+item replace entity @s armor.feet with air
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/eval.mcfunction
new file mode 100644
index 0000000000..ee39e50a65
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/eval.mcfunction
@@ -0,0 +1,6 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/feet/run
+
+$item modify entity @s armor.feet {function:"minecraft:set_components",components:{"minecraft:damage":$(damage)}}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/find_durability.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/find_durability.mcfunction
new file mode 100644
index 0000000000..b3c9d4cb10
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/find_durability.mcfunction
@@ -0,0 +1,11 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/feet/run
+
+execute if items block 29999998 1 7134 container.3 leather_boots run return 65
+execute if items block 29999998 1 7134 container.3 golden_boots run return 91
+execute if items block 29999998 1 7134 container.3 chainmail_boots run return 195
+execute if items block 29999998 1 7134 container.3 iron_boots run return 195
+execute if items block 29999998 1 7134 container.3 diamond_boots run return 429
+execute if items block 29999998 1 7134 container.3 netherite_boots run return 481
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/run.mcfunction
new file mode 100644
index 0000000000..0dffb19ea2
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/feet/run.mcfunction
@@ -0,0 +1,38 @@
+# apply durability damage on armor item
+# @s = damaged player
+# at @s
+# run from player/armor/durability/check
+
+# if unbreakable don't run
+execute if data storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:unbreakable" run return 0
+
+# calculate incoming damage based on unbreaking
+execute store result score $unbreaking_level gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:unbreaking"
+scoreboard players add $unbreaking_level gm4_sr_data 1
+scoreboard players set $damage_chance gm4_sr_data 100
+scoreboard players operation $damage_chance gm4_sr_data /= $unbreaking_level gm4_sr_data
+scoreboard players set $damage_opportunities gm4_sr_data 1
+execute store result score $incoming_damage gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:technical/roll_damage
+execute positioned ~ -4064 ~ run kill @e[type=item,distance=..1]
+
+# if no damage is going to be applied cancel function
+execute unless score $incoming_damage gm4_sr_data matches 1.. run return 0
+
+# find the total durability of this item
+execute store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:max_damage"
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:custom_data".gm4_augmented_armor.durability
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run function gm4_survival_refightalized:player/armor/durability/feet/find_durability
+execute if score $total_durability gm4_sr_data matches 0 run return 0
+
+# add incoming damage to the current damage
+execute store result score $current_damage gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:damage"
+scoreboard players operation $current_damage gm4_sr_data += $incoming_damage gm4_sr_data
+execute if score $current_damage gm4_sr_data > $total_durability gm4_sr_data run return run function gm4_survival_refightalized:player/armor/durability/feet/break
+
+# apply to armor
+execute store result storage gm4_survival_refightalized:temp set.damage int 1 run scoreboard players get $current_damage gm4_sr_data
+function gm4_survival_refightalized:player/armor/durability/feet/eval with storage gm4_survival_refightalized:temp set
+
+# cleanup
+data remove storage gm4_survival_refightalized:temp set
+scoreboard players reset $total_durability gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/break.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/break.mcfunction
new file mode 100644
index 0000000000..5a2c2a31cf
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/break.mcfunction
@@ -0,0 +1,7 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/head/run
+
+playsound minecraft:entity.item.break player @s ~ ~ ~ 1 1
+item replace entity @s armor.head with air
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/eval.mcfunction
new file mode 100644
index 0000000000..147453177b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/eval.mcfunction
@@ -0,0 +1,6 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/head/run
+
+$item modify entity @s armor.head {function:"minecraft:set_components",components:{"minecraft:damage":$(damage)}}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/find_durability.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/find_durability.mcfunction
new file mode 100644
index 0000000000..907834e862
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/find_durability.mcfunction
@@ -0,0 +1,12 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/head/run
+
+execute if items block 29999998 1 7134 container.0 leather_helmet run return 55
+execute if items block 29999998 1 7134 container.0 golden_helmet run return 77
+execute if items block 29999998 1 7134 container.0 chainmail_helmet run return 165
+execute if items block 29999998 1 7134 container.0 iron_helmet run return 165
+execute if items block 29999998 1 7134 container.0 diamond_helmet run return 363
+execute if items block 29999998 1 7134 container.0 netherite_helmet run return 407
+execute if items block 29999998 1 7134 container.0 turtle_helmet run return 275
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/run.mcfunction
new file mode 100644
index 0000000000..77576a9f14
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/head/run.mcfunction
@@ -0,0 +1,38 @@
+# apply durability damage on armor item
+# @s = damaged player
+# at @s
+# run from player/armor/durability/check
+
+# if unbreakable don't run
+execute if data storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:unbreakable" run return 0
+
+# calculate incoming damage based on unbreaking
+execute store result score $unbreaking_level gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:unbreaking"
+scoreboard players add $unbreaking_level gm4_sr_data 1
+scoreboard players set $damage_chance gm4_sr_data 100
+scoreboard players operation $damage_chance gm4_sr_data /= $unbreaking_level gm4_sr_data
+scoreboard players set $damage_opportunities gm4_sr_data 1
+execute store result score $incoming_damage gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:technical/roll_damage
+execute positioned ~ -4064 ~ run kill @e[type=item,distance=..1]
+
+# if no damage is going to be applied cancel function
+execute unless score $incoming_damage gm4_sr_data matches 1.. run return 0
+
+# find the total durability of this item
+execute store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:max_damage"
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:custom_data".gm4_augmented_armor.durability
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run function gm4_survival_refightalized:player/armor/durability/head/find_durability
+execute if score $total_durability gm4_sr_data matches 0 run return 0
+
+# add incoming damage to the current damage
+execute store result score $current_damage gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:damage"
+scoreboard players operation $current_damage gm4_sr_data += $incoming_damage gm4_sr_data
+execute if score $current_damage gm4_sr_data > $total_durability gm4_sr_data run return run function gm4_survival_refightalized:player/armor/durability/head/break
+
+# apply to armor
+execute store result storage gm4_survival_refightalized:temp set.damage int 1 run scoreboard players get $current_damage gm4_sr_data
+function gm4_survival_refightalized:player/armor/durability/head/eval with storage gm4_survival_refightalized:temp set
+
+# cleanup
+data remove storage gm4_survival_refightalized:temp set
+scoreboard players reset $total_durability gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/break.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/break.mcfunction
new file mode 100644
index 0000000000..f001bf95a9
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/break.mcfunction
@@ -0,0 +1,7 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/legs/run
+
+playsound minecraft:entity.item.break player @s ~ ~ ~ 1 1
+item replace entity @s armor.legs with air
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/eval.mcfunction
new file mode 100644
index 0000000000..370f1314f0
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/eval.mcfunction
@@ -0,0 +1,6 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/legs/run
+
+$item modify entity @s armor.legs {function:"minecraft:set_components",components:{"minecraft:damage":$(damage)}}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/find_durability.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/find_durability.mcfunction
new file mode 100644
index 0000000000..6ea617a736
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/find_durability.mcfunction
@@ -0,0 +1,11 @@
+# set damage on armor item
+# @s = player wearing the item
+# at unspecified
+# run from player/armor/durability/legs/run
+
+execute if items block 29999998 1 7134 container.2 leather_leggings run return 75
+execute if items block 29999998 1 7134 container.2 golden_leggings run return 105
+execute if items block 29999998 1 7134 container.2 chainmail_leggings run return 225
+execute if items block 29999998 1 7134 container.2 iron_leggings run return 225
+execute if items block 29999998 1 7134 container.2 diamond_leggings run return 495
+execute if items block 29999998 1 7134 container.2 netherite_leggings run return 555
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/run.mcfunction
new file mode 100644
index 0000000000..d9e77f2e46
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/durability/legs/run.mcfunction
@@ -0,0 +1,38 @@
+# apply durability damage on armor item
+# @s = damaged player
+# at @s
+# run from player/armor/durability/check
+
+# if unbreakable don't run
+execute if data storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:unbreakable" run return 0
+
+# calculate incoming damage based on unbreaking
+execute store result score $unbreaking_level gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:unbreaking"
+scoreboard players add $unbreaking_level gm4_sr_data 1
+scoreboard players set $damage_chance gm4_sr_data 100
+scoreboard players operation $damage_chance gm4_sr_data /= $unbreaking_level gm4_sr_data
+scoreboard players set $damage_opportunities gm4_sr_data 1
+execute store result score $incoming_damage gm4_sr_data run loot spawn ~ -4064 ~ loot gm4_survival_refightalized:technical/roll_damage
+execute positioned ~ -4064 ~ run kill @e[type=item,distance=..1]
+
+# if no damage is going to be applied cancel function
+execute unless score $incoming_damage gm4_sr_data matches 1.. run return 0
+
+# find the total durability of this item
+execute store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:max_damage"
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:custom_data".gm4_augmented_armor.durability
+execute if score $total_durability gm4_sr_data matches 0 store result score $total_durability gm4_sr_data run function gm4_survival_refightalized:player/armor/durability/legs/find_durability
+execute if score $total_durability gm4_sr_data matches 0 run return 0
+
+# add incoming damage to the current damage
+execute store result score $current_damage gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:damage"
+scoreboard players operation $current_damage gm4_sr_data += $incoming_damage gm4_sr_data
+execute if score $current_damage gm4_sr_data > $total_durability gm4_sr_data run return run function gm4_survival_refightalized:player/armor/durability/legs/break
+
+# apply to armor
+execute store result storage gm4_survival_refightalized:temp set.damage int 1 run scoreboard players get $current_damage gm4_sr_data
+function gm4_survival_refightalized:player/armor/durability/legs/eval with storage gm4_survival_refightalized:temp set
+
+# cleanup
+data remove storage gm4_survival_refightalized:temp set
+scoreboard players reset $total_durability gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/eval_reduction.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/eval_reduction.mcfunction
new file mode 100644
index 0000000000..4cdc5dc164
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/eval_reduction.mcfunction
@@ -0,0 +1,9 @@
+# reduce armor on player based on their score
+# @s = damaged player
+# at @s
+# run from player/armor/recharge
+# run from player/damage/calculate_damage
+
+attribute @s minecraft:armor modifier remove gm4_survival_refightalized:armor_reduced
+$attribute @s armor modifier add gm4_survival_refightalized:armor_reduced -$(armor_reduction) add_value
+tag @s add gm4_sr_armor.reduction
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/recharge.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/recharge.mcfunction
new file mode 100644
index 0000000000..aad3fca3b4
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/recharge.mcfunction
@@ -0,0 +1,22 @@
+# regain armor for this player
+# @s = player with reduced armor
+# at unspecified
+# run from player/armor/timer
+
+# only run if health is full
+function gm4_survival_refightalized:player/health/calculate_hp
+execute unless score @s gm4_sr_stat.health_percentage matches 100.. run return 0
+
+scoreboard players remove @s[scores={gm4_sr_armor.reduction=1..}] gm4_sr_armor.reduction 10
+scoreboard players operation @s gm4_sr_armor.reduction > #0 gm4_sr_data
+
+# if no armor reduction is left don't apply armor
+attribute @s[scores={gm4_sr_armor.reduction=..0}] minecraft:armor modifier remove gm4_survival_refightalized:armor_reduced
+execute if entity @s[scores={gm4_sr_armor.reduction=..0}] run return run tag @s remove gm4_sr_armor.reduction
+
+execute store result storage gm4_survival_refightalized:temp set.armor_reduction float 0.1 run scoreboard players get @s gm4_sr_armor.reduction
+function gm4_survival_refightalized:player/armor/eval_reduction with storage gm4_survival_refightalized:temp set
+data remove storage gm4_survival_refightalized:temp set
+
+# reapply resistance
+effect give @s resistance 2 255 true
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/timer.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/timer.mcfunction
new file mode 100644
index 0000000000..f87fa287ab
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/armor/timer.mcfunction
@@ -0,0 +1,11 @@
+# process players that have their armor reduced
+# @s = player
+# at unspecified
+# run from player/player_submain
+
+# gm4_sr_stat.armor_recharge_change is normally 0, but can be changed by expansions
+scoreboard players set $armor_recharge gm4_sr_data 100
+scoreboard players operation $armor_recharge gm4_sr_data += @s gm4_sr_stat.armor_recharge_change
+scoreboard players operation $armor_recharge gm4_sr_data > #0 gm4_sr_data
+scoreboard players operation @s[scores={gm4_sr_armor.reduction_timer=1..}] gm4_sr_armor.reduction_timer -= $armor_recharge gm4_sr_data
+execute unless score @s gm4_sr_armor.reduction_timer matches 1.. run function gm4_survival_refightalized:player/armor/recharge
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_damage.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_damage.mcfunction
new file mode 100644
index 0000000000..cd683a3e75
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_damage.mcfunction
@@ -0,0 +1,52 @@
+# devide damage between armor, absorption and health
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# make sure at least 1 damage is dealt
+scoreboard players operation $damage_total gm4_sr_data > #1 gm4_sr_data
+tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Real Damage Taken (x10): ","color":"gray"},{"score":{"name":"$damage_total","objective":"gm4_sr_data"},"color":"white"}]
+
+# | Armor
+scoreboard players operation $damage_armor gm4_sr_data += $damage_total gm4_sr_data
+# if damage pierces armor no effect
+execute unless entity @s[advancements={gm4_survival_refightalized:damaged={armor_piercing=false,armor_piercing_mob=false}}] run scoreboard players set $damage_armor gm4_sr_data 0
+# if armor is reduced to below 1 play sound and remove resistance effect on player
+execute store result score $player_armor gm4_sr_data run attribute @s minecraft:armor get 10
+scoreboard players operation $armor_check gm4_sr_data = $player_armor gm4_sr_data
+scoreboard players operation $armor_check gm4_sr_data -= $damage_armor gm4_sr_data
+execute if score $armor_check gm4_sr_data matches ..9 run function gm4_survival_refightalized:player/armor/break
+# calc the reduction in armor that should be applied
+execute store result storage gm4_survival_refightalized:temp set.armor_reduction float 0.1 run scoreboard players operation @s gm4_sr_armor.reduction += $damage_armor gm4_sr_data
+# any leftover damage is applied to the players absorption and health
+scoreboard players operation $damage_left gm4_sr_data = $damage_total gm4_sr_data
+scoreboard players operation $damage_left gm4_sr_data -= $damage_armor gm4_sr_data
+
+# | Absorption
+# get scores
+scoreboard players operation $current_absorption_hearts gm4_sr_data = @s gm4_sr_stat.current_absorption
+scoreboard players operation $current_absorption_max gm4_sr_data = @s gm4_sr_stat.max_absorption
+# apply leftover damge to absorption first
+scoreboard players operation $damage_absorption gm4_sr_data += $damage_left gm4_sr_data
+scoreboard players operation $damage_absorption gm4_sr_data < $current_absorption_hearts gm4_sr_data
+scoreboard players operation $current_absorption_hearts gm4_sr_data -= $damage_absorption gm4_sr_data
+# set storage to the amount of reduction of max absorption needed to get to the new absorption total
+execute store result storage gm4_survival_refightalized:temp set.absorption_reduction float 0.1 run scoreboard players operation $current_absorption_max gm4_sr_data -= $current_absorption_hearts gm4_sr_data
+
+# | Health
+scoreboard players operation $damage_left gm4_sr_data -= $damage_absorption gm4_sr_data
+scoreboard players operation $damage_health gm4_sr_data += $damage_left gm4_sr_data
+
+# | Damage the player
+# armor
+execute if score $damage_armor gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Armor: ","color":"gray"},{"score":{"name":"$damage_armor","objective":"gm4_sr_data"},"color":"white"}]
+execute if score $damage_armor gm4_sr_data matches 1.. run function gm4_survival_refightalized:player/armor/eval_reduction with storage gm4_survival_refightalized:temp set
+# absorption hearts
+execute if score $damage_absorption gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Absorption: ","color":"gray"},{"score":{"name":"$damage_absorption","objective":"gm4_sr_data"},"color":"white"}]
+execute if score $damage_absorption gm4_sr_data matches 1.. run function gm4_survival_refightalized:player/absorption/eval_reduction with storage gm4_survival_refightalized:temp set
+# red hearts
+execute if score $damage_health gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Health: ","color":"gray"},{"score":{"name":"$damage_health","objective":"gm4_sr_data"},"color":"white"}]
+execute if score $damage_health gm4_sr_data matches 1.. run function gm4_survival_refightalized:player/health/reduce/activate
+
+# advancement
+execute if score $damage_armor gm4_sr_data matches 1.. run advancement grant @s only gm4:survival_refightalized_armor_damage
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_reduction.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_reduction.mcfunction
new file mode 100644
index 0000000000..ec3a022df7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/calculate_reduction.mcfunction
@@ -0,0 +1,41 @@
+# calculate damage reduction based on different factors - if armor is worn
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# grab active effects to check for resistance later - can be skipped if this was already done for cave spider / witch poison reduction
+execute unless data storage gm4_survival_refightalized:temp active_effects run data modify storage gm4_survival_refightalized:temp active_effects set from entity @s active_effects
+
+# don't run if this resistance level is not due to armor (as the player will already have taken the damage)
+# this should generally not run, and is mostly here as a fail-safe
+execute store result score $resistance_level gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].amplifier
+execute unless score $resistance_level gm4_sr_data matches -1 run return run scoreboard players reset @s gm4_sr_stat.damage_resisted
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Base Damage Taken (x10): ","color":"gray"},{"score":{"name":"@s","objective":"gm4_sr_stat.damage_resisted"},"color":"white"}]
+
+# transfer damage resistance to damage to health score
+scoreboard players operation $damage_total gm4_sr_data = @s gm4_sr_stat.damage_resisted
+
+# first check the resistance level besides from this module
+# if this results in 100% damage reduction skip the rest of this function
+execute store success score $resistance_damage_reduction gm4_sr_data if data storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].hidden_effect.duration
+execute if score $resistance_damage_reduction gm4_sr_data matches 1 store result score $resistance_damage_reduction gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].hidden_effect.amplifier 20
+execute if score $resistance_damage_reduction gm4_sr_data matches 1.. run scoreboard players add $resistance_damage_reduction gm4_sr_data 20
+execute unless score $resistance_damage_reduction gm4_sr_data matches 0..99 run return run data remove storage gm4_survival_refightalized:temp active_effects
+
+# | Reduce damage taken based on
+# /!\ order for these is important!
+# 1. armor toughness (only if player still has armor)
+execute store result score $armor_toughness gm4_sr_data run attribute @s minecraft:armor_toughness get
+execute if score $armor_toughness gm4_sr_data matches 1.. if score @s gm4_sr_stat.armor matches 1.. run function gm4_survival_refightalized:player/damage/reduction/armor_toughness
+
+# 2. enchantments
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={bypasses_enchantments=false}}] run function gm4_survival_refightalized:player/damage/reduction/enchantments/run
+
+# 3. resistance effect (uses highest level besides the one used for this module)
+scoreboard players operation $resistance_damage_reduction_percentage gm4_sr_data = $resistance_damage_reduction gm4_sr_data
+scoreboard players operation $resistance_damage_reduction gm4_sr_data *= $damage_total gm4_sr_data
+scoreboard players operation $resistance_damage_reduction gm4_sr_data /= #100 gm4_sr_data
+scoreboard players operation $damage_total gm4_sr_data -= $resistance_damage_reduction gm4_sr_data
+execute if score $resistance_damage_reduction gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Resistance: ","color":"gray"},{"text":"-","color":"white"},{"score":{"name":"$resistance_damage_reduction","objective":"gm4_sr_data"},"color":"white"},{"text":" = "},{"score":{"name":"$damage_total","objective":"gm4_sr_data"},"color":"white"},{"text":" (","color":"dark_gray"},{"score":{"name":"$resistance_damage_reduction_percentage","objective":"gm4_sr_data"},"color":"dark_gray"},{"text":"%)","color":"dark_gray"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/cave_spider_poison_reduction.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/cave_spider_poison_reduction.mcfunction
new file mode 100644
index 0000000000..35de663a50
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/cave_spider_poison_reduction.mcfunction
@@ -0,0 +1,22 @@
+# reduce poison duration from cave spider attacks
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# dont run on easy, no poison applied
+execute store result score $worlddiff gm4_sr_data run difficulty
+execute if score $worlddiff gm4_sr_data matches 1 run return 0
+
+# get effect data
+data modify storage gm4_survival_refightalized:temp active_effects set from entity @s active_effects
+execute store result score $poison.amplifier gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:poison"}].amplifier
+execute store result score $poison.duration gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:poison"}].duration
+
+# dont run if there is a stronger poison running
+execute unless score $poison.amplifier gm4_sr_data matches 0 run return 0
+execute unless score $poison.duration gm4_sr_data matches 299 unless score $poison.duration gm4_sr_data matches 139 run return 0
+
+# reapply weaker poison, 1 damage for normal, 2 damage for hard
+effect clear @s poison
+execute if score $worlddiff gm4_sr_data matches 2 run effect give @s poison 2 0
+execute if score $worlddiff gm4_sr_data matches 3 run effect give @s poison 4 0
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/armor_toughness.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/armor_toughness.mcfunction
new file mode 100644
index 0000000000..603ec06417
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/armor_toughness.mcfunction
@@ -0,0 +1,32 @@
+# reduce damage with armor toughness
+# @s = damaged player
+# at @s
+# run from player/damage/calculate_reduction
+
+# Formula:
+# Damage reduction percentage = (damage * armor_toughness * 50) / ( damage * armor_toughness + 3500 )
+
+# dividend = damage * armor_toughness * 50
+scoreboard players operation $armor_toughness.dividend gm4_sr_data = $damage_total gm4_sr_data
+scoreboard players operation $armor_toughness.dividend gm4_sr_data *= $armor_toughness gm4_sr_data
+scoreboard players operation $armor_toughness.dividend gm4_sr_data *= #50 gm4_sr_data
+
+# divisor = damage * armor_toughness + 3500
+scoreboard players operation $armor_toughness.divisor gm4_sr_data = $damage_total gm4_sr_data
+scoreboard players operation $armor_toughness.divisor gm4_sr_data *= $armor_toughness gm4_sr_data
+scoreboard players add $armor_toughness.divisor gm4_sr_data 3500
+
+# dividend / divisor (this rounds down!), can max reduce damage by 25%
+scoreboard players operation $armor_toughness.dividend gm4_sr_data /= $armor_toughness.divisor gm4_sr_data
+scoreboard players operation $armor_toughness.dividend gm4_sr_data < #25 gm4_sr_data
+
+# get damage reduction
+scoreboard players operation $armor_toughness_effect gm4_sr_data = $damage_total gm4_sr_data
+scoreboard players operation $armor_toughness_effect gm4_sr_data *= $armor_toughness.dividend gm4_sr_data
+scoreboard players operation $armor_toughness_effect gm4_sr_data /= #100 gm4_sr_data
+
+# reduce damage taken
+scoreboard players operation $damage_total gm4_sr_data -= $armor_toughness_effect gm4_sr_data
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Armor Toughness: ","color":"gray"},{"text":"-","color":"white"},{"score":{"name":"$armor_toughness_effect","objective":"gm4_sr_data"},"color":"white"},{"text":" = ","color":"gray"},{"score":{"name":"$damage_total","objective":"gm4_sr_data"},"color":"white"},{"text":" (","color":"dark_gray"},{"score":{"name":"$armor_toughness.dividend","objective":"gm4_sr_data"},"color":"dark_gray"},{"text":"%)","color":"dark_gray"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/blast_protection.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/blast_protection.mcfunction
new file mode 100644
index 0000000000..b1fb40b649
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/blast_protection.mcfunction
@@ -0,0 +1,16 @@
+# reduce damage with blast protection
+# @s = damaged player
+# at @s
+# run from player/damage/reduction/enchantments/ruun
+
+execute store result score $enchant.blast_protection gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:blast_protection" 4
+execute store result score $enchant.blast_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:blast_protection" 4
+scoreboard players operation $enchant.blast_protection gm4_sr_data += $enchant.blast_protection.add gm4_sr_data
+execute store result score $enchant.blast_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:blast_protection" 4
+scoreboard players operation $enchant.blast_protection gm4_sr_data += $enchant.blast_protection.add gm4_sr_data
+execute store result score $enchant.blast_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:blast_protection" 4
+scoreboard players operation $enchant.blast_protection gm4_sr_data += $enchant.blast_protection.add gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 0 if score $enchant.blast_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Enchantments:","color":"gray"}
+scoreboard players operation $enchant.damage_reduction gm4_sr_data += $enchant.blast_protection gm4_sr_data
+execute if score $enchant.blast_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Blast Protection: ","color":"gray"},{"score":{"name":"$enchant.blast_protection","objective":"gm4_sr_data"},"color":"white"},{"text":"%","color":"white"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/feather_falling.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/feather_falling.mcfunction
new file mode 100644
index 0000000000..1a1a763b62
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/feather_falling.mcfunction
@@ -0,0 +1,16 @@
+# reduce damage with feather falling
+# @s = damaged player
+# at @s
+# run from player/damage/reduction/enchantments/ruun
+
+execute store result score $enchant.feather_falling gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:feather_falling" 12
+execute store result score $enchant.feather_falling.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:feather_falling" 12
+scoreboard players operation $enchant.feather_falling gm4_sr_data += $enchant.feather_falling.add gm4_sr_data
+execute store result score $enchant.feather_falling.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:feather_falling" 12
+scoreboard players operation $enchant.feather_falling gm4_sr_data += $enchant.feather_falling.add gm4_sr_data
+execute store result score $enchant.feather_falling.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:feather_falling" 12
+scoreboard players operation $enchant.feather_falling gm4_sr_data += $enchant.feather_falling.add gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 0 if score $enchant.feather_falling gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Enchantments:","color":"gray"}
+scoreboard players operation $enchant.damage_reduction gm4_sr_data += $enchant.feather_falling gm4_sr_data
+execute if score $enchant.feather_falling gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Feather Falling: ","color":"gray"},{"score":{"name":"$enchant.feather_falling","objective":"gm4_sr_data"},"color":"white"},{"text":"%","color":"white"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/fire_protection.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/fire_protection.mcfunction
new file mode 100644
index 0000000000..652da6caff
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/fire_protection.mcfunction
@@ -0,0 +1,16 @@
+# reduce damage with fire protection
+# @s = damaged player
+# at @s
+# run from player/damage/reduction/enchantments/ruun
+
+execute store result score $enchant.fire_protection gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:fire_protection" 4
+execute store result score $enchant.fire_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:fire_protection" 4
+scoreboard players operation $enchant.fire_protection gm4_sr_data += $enchant.fire_protection.add gm4_sr_data
+execute store result score $enchant.fire_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:fire_protection" 4
+scoreboard players operation $enchant.fire_protection gm4_sr_data += $enchant.fire_protection.add gm4_sr_data
+execute store result score $enchant.fire_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:fire_protection" 4
+scoreboard players operation $enchant.fire_protection gm4_sr_data += $enchant.fire_protection.add gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 0 if score $enchant.fire_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Enchantments:","color":"gray"}
+scoreboard players operation $enchant.damage_reduction gm4_sr_data += $enchant.fire_protection gm4_sr_data
+execute if score $enchant.fire_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Fire Protection: ","color":"gray"},{"score":{"name":"$enchant.fire_protection","objective":"gm4_sr_data"},"color":"white"},{"text":"%","color":"white"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/projectile_protection.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/projectile_protection.mcfunction
new file mode 100644
index 0000000000..2275f352dc
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/projectile_protection.mcfunction
@@ -0,0 +1,16 @@
+# reduce damage with projectile protection
+# @s = damaged player
+# at @s
+# run from player/damage/reduction/enchantments/ruun
+
+execute store result score $enchant.projectile_protection gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:projectile_protection" 4
+execute store result score $enchant.projectile_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:projectile_protection" 4
+scoreboard players operation $enchant.projectile_protection gm4_sr_data += $enchant.projectile_protection.add gm4_sr_data
+execute store result score $enchant.projectile_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:projectile_protection" 4
+scoreboard players operation $enchant.projectile_protection gm4_sr_data += $enchant.projectile_protection.add gm4_sr_data
+execute store result score $enchant.projectile_protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:projectile_protection" 4
+scoreboard players operation $enchant.projectile_protection gm4_sr_data += $enchant.projectile_protection.add gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 0 if score $enchant.projectile_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Enchantments:","color":"gray"}
+scoreboard players operation $enchant.damage_reduction gm4_sr_data += $enchant.projectile_protection gm4_sr_data
+execute if score $enchant.projectile_protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Projectile Protection: ","color":"gray"},{"score":{"name":"$enchant.projectile_protection","objective":"gm4_sr_data"},"color":"white"},{"text":"%","color":"white"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/run.mcfunction
new file mode 100644
index 0000000000..0842fe2c27
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/reduction/enchantments/run.mcfunction
@@ -0,0 +1,53 @@
+# reduce damage with enchantments
+# @s = damaged player
+# at @s
+# run from player/damage/calculate_reduction
+
+# get required data
+item replace block 29999998 1 7134 container.0 from entity @s armor.head
+item replace block 29999998 1 7134 container.1 from entity @s armor.chest
+item replace block 29999998 1 7134 container.2 from entity @s armor.legs
+item replace block 29999998 1 7134 container.3 from entity @s armor.feet
+data modify storage gm4_survival_refightalized:temp Items set from block 29999998 1 7134 Items
+data remove block 29999998 1 7134 Items
+
+# /?\ enchantments have been nerfed! Protection values are:
+# 1% per level of Protection
+# 4% per level of Fire / Blast / Projectile Protection
+
+scoreboard players set $enchant.damage_reduction gm4_sr_data 0
+
+# generic protection enchantment
+execute store result score $enchant.protection gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:0b}].components."minecraft:enchantments"."minecraft:protection" 1
+execute store result score $enchant.protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:1b}].components."minecraft:enchantments"."minecraft:protection" 1
+scoreboard players operation $enchant.protection gm4_sr_data += $enchant.protection.add gm4_sr_data
+execute store result score $enchant.protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:2b}].components."minecraft:enchantments"."minecraft:protection" 1
+scoreboard players operation $enchant.protection gm4_sr_data += $enchant.protection.add gm4_sr_data
+execute store result score $enchant.protection.add gm4_sr_data run data get storage gm4_survival_refightalized:temp Items[{Slot:3b}].components."minecraft:enchantments"."minecraft:protection" 1
+scoreboard players operation $enchant.protection gm4_sr_data += $enchant.protection.add gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 0 if score $enchant.protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Enchantments:","color":"gray"}
+scoreboard players operation $enchant.damage_reduction gm4_sr_data += $enchant.protection gm4_sr_data
+execute if score $enchant.protection gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" > Protection: ","color":"gray"},{"score":{"name":"$enchant.protection","objective":"gm4_sr_data"},"color":"white"},{"text":"%","color":"white"}]
+
+# check if specific protection enchants would apply
+scoreboard players set $enchant.fire_protection gm4_sr_data 0
+scoreboard players set $enchant.blast_protection gm4_sr_data 0
+scoreboard players set $enchant.projectile_protection gm4_sr_data 0
+scoreboard players set $enchant.feather_falling gm4_sr_data 0
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={is_fire=true}}] run function gm4_survival_refightalized:player/damage/reduction/enchantments/fire_protection
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={is_explosion=true}}] run function gm4_survival_refightalized:player/damage/reduction/enchantments/blast_protection
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={is_projectile=true}}] run function gm4_survival_refightalized:player/damage/reduction/enchantments/projectile_protection
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={is_fall=true}}] run function gm4_survival_refightalized:player/damage/reduction/enchantments/feather_falling
+
+# total enchantment damage reduction is capped at 80%
+scoreboard players operation $enchant.damage_reduction gm4_sr_data < #80 gm4_sr_data
+scoreboard players operation $enchant.damage_reduction_percentage gm4_sr_data = $enchant.damage_reduction gm4_sr_data
+scoreboard players operation $enchant.damage_reduction gm4_sr_data *= $damage_total gm4_sr_data
+scoreboard players operation $enchant.damage_reduction gm4_sr_data /= #100 gm4_sr_data
+scoreboard players operation $damage_total gm4_sr_data -= $enchant.damage_reduction gm4_sr_data
+
+execute if score $enchant.damage_reduction gm4_sr_data matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":" >> Total: ","color":"gray"},{"text":"-","color":"white"},{"score":{"name":"$enchant.damage_reduction","objective":"gm4_sr_data"},"color":"white"},{"text":" = ","color":"gray"},{"score":{"name":"$damage_total","objective":"gm4_sr_data"},"color":"white"},{"text":" (","color":"dark_gray"},{"score":{"name":"$enchant.damage_reduction_percentage","objective":"gm4_sr_data"},"color":"dark_gray"},{"text":"%)","color":"dark_gray"}]
+
+# cleanup
+data remove storage gm4_survival_refightalized:temp Items
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/run.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/run.mcfunction
new file mode 100644
index 0000000000..757f5c3213
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/run.mcfunction
@@ -0,0 +1,66 @@
+# run when player gets damaged
+# @s = damaged player
+# at @s
+# run from tick
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"-- Damage Log --"}
+
+# prep scores
+function gm4_survival_refightalized:player/health/calculate_hp
+scoreboard players set $damage_armor gm4_sr_data 0
+scoreboard players set $damage_absorption gm4_sr_data 0
+scoreboard players set $damage_health gm4_sr_data 0
+scoreboard players set $damage_total gm4_sr_data 0
+
+### TEMP - paper fix - damage resist score gets multiplied by 51.2, so we need to revert that or the player instantly dies
+### this currently breaks if a player takes a multiple of 51.2 damage, but that should be rare enough
+scoreboard players set #512 gm4_sr_data 512
+execute if score $on_paper gm4_sr_data matches 1 run tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Paper Bug - divided damage by 51.2","color":"red","italic":true}
+execute if score $on_paper gm4_sr_data matches 1 run scoreboard players operation @s gm4_sr_stat.damage_resisted *= #10 gm4_sr_data
+execute if score $on_paper gm4_sr_data matches 1 run scoreboard players operation @s gm4_sr_stat.damage_resisted /= #512 gm4_sr_data
+
+# disable shield if damage was blocked, don't run the rest of this function
+execute unless score @s[scores={gm4_sr_shield.timer=1..2,gm4_sr_shield.use_ticks=1..}] gm4_sr_stat.damage_taken matches 1.. unless score @s gm4_sr_stat.damage_absorbed matches 1.. run return run function gm4_survival_refightalized:player/damage/shield/blocked_damage
+
+# cave spider / witch poison reduction
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={cave_spider=true}}] run function gm4_survival_refightalized:player/damage/cave_spider_poison_reduction
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={witch=true}}] run function gm4_survival_refightalized:player/damage/witch_poison_reduction
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log,advancements={gm4_survival_refightalized:damaged={combat_damage=false}}] {"text":"Non-Combat Damage","color":"dark_gray","italic":true}
+
+# calculate damage if player has armor
+execute if score @s gm4_sr_stat.armor matches 1.. run function gm4_survival_refightalized:player/damage/calculate_reduction
+execute unless score @s gm4_sr_stat.armor matches 1.. run tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"No Armor - Damage (x10): ","color":"gray"},{"score":{"name":"@s","objective":"gm4_sr_stat.damage_taken"},"color":"white"}]
+
+# set combat regeneration timers, allow to be altered by function call
+scoreboard players operation $set gm4_sr_armor.reduction_timer = $armor_recharge_timer gm4_sr_config
+scoreboard players operation $set gm4_sr_health.regeneration_timer = $combat_regen_timer gm4_sr_config
+
+# function call
+# called after damage is calculated but before it is applied (unless there was no armor, then it is applied by the game)
+function #gm4_survival_refightalized:damage_taken
+
+# divide the damage taken between armor, absorption and health
+execute if score $damage_total gm4_sr_data matches 1.. run function gm4_survival_refightalized:player/damage/calculate_damage
+
+# apply armor recharge timer, /5 if damage was non-combat, 0 if damage did not apply to armor
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={combat_damage=false}}] run scoreboard players operation $set gm4_sr_armor.reduction_timer /= #5 gm4_sr_data
+execute if score $damage_armor gm4_sr_data matches 1.. run scoreboard players operation @s gm4_sr_armor.reduction_timer > $set gm4_sr_armor.reduction_timer
+# apply durability damage to armor unless it was armor piercing damage
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={armor_piercing=false,armor_piercing_mob=false}}] run function gm4_survival_refightalized:player/armor/durability/check
+
+# apply health regeneration timer, /5 if damage was non-combat, 0 if damage did not apply to health
+execute if entity @s[advancements={gm4_survival_refightalized:damaged={combat_damage=false}}] run scoreboard players operation $set gm4_sr_health.regeneration_timer /= #5 gm4_sr_data
+execute if score $damage_health gm4_sr_data matches 1.. run scoreboard players operation @s gm4_sr_health.regeneration_timer > $set gm4_sr_health.regeneration_timer
+scoreboard players operation @s[scores={gm4_sr_stat.damage_taken=1..}] gm4_sr_health.regeneration_timer > $set gm4_sr_health.regeneration_timer
+
+# cleanup
+scoreboard players reset @s gm4_sr_stat.damage_taken
+scoreboard players reset @s gm4_sr_stat.damage_absorbed
+scoreboard players reset @s gm4_sr_stat.damage_resisted
+scoreboard players reset @s gm4_sr_stat.damage_blocked
+advancement revoke @s only gm4_survival_refightalized:damaged
+data remove storage gm4_survival_refightalized:temp active_effects
+data remove storage gm4_survival_refightalized:temp set
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/blocked_damage.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/blocked_damage.mcfunction
new file mode 100644
index 0000000000..0d01f214fa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/blocked_damage.mcfunction
@@ -0,0 +1,34 @@
+# disable shield if it blocked damage
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# revoke advancement as it's not needed for shield blocking
+advancement revoke @s only gm4_survival_refightalized:damaged
+
+# get shield data
+scoreboard players set $mainhand_shield gm4_sr_data 0
+execute if items entity @s weapon.mainhand *[custom_data~{gm4_survival_refightalized:{shield:{}}}] store success score $mainhand_shield gm4_sr_data run item replace block 29999998 1 7134 container.0 from entity @s weapon.mainhand
+execute if score $mainhand_shield gm4_sr_data matches 0 run item replace block 29999998 1 7134 container.0 from entity @s weapon.offhand
+data modify storage gm4_survival_refightalized:temp Item set from block 29999998 1 7134 Items[0]
+data remove block 29999998 1 7134 Items
+
+# non-player attacker is weak for 1 second so they don't immediatly hit again
+execute on attacker run effect give @s[type=!player] weakness 1 9 true
+
+# parry attack (shield won't get disabled)
+execute store result score $parry_ticks gm4_sr_data run data get storage gm4_survival_refightalized:temp Item.components."minecraft:custom_data".gm4_survival_refightalized.shield.parry_ticks
+execute if score @s gm4_sr_shield.use_ticks <= $parry_ticks gm4_sr_data unless score @s gm4_sr_shield.spam_detection matches 10.. run return run function gm4_survival_refightalized:player/damage/shield/parry
+
+# disable shield
+tag @s add gm4_sr_target
+execute at @s anchored eyes positioned ^ ^ ^1 summon armor_stand run return run function gm4_survival_refightalized:player/damage/shield/disable
+tag @s remove gm4_sr_target
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Damage blocked by shield","color":"dark_gray"}
+
+# cleanup
+scoreboard players reset @s gm4_sr_stat.damage_resisted
+scoreboard players reset @s gm4_sr_stat.damage_blocked
+advancement revoke @s only gm4_survival_refightalized:damaged
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/disable.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/disable.mcfunction
new file mode 100644
index 0000000000..2e7bc14ac1
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/disable.mcfunction
@@ -0,0 +1,8 @@
+# damage the player from an axe to disable their shield
+# @s = armor stand
+# at @s
+# run from player/damage/shield/blocked_damage
+
+item replace entity @s weapon.mainhand with iron_axe[weapon={disable_blocking_for_seconds:2}]
+damage @p[tag=gm4_sr_target] 0.01 mob_attack by @s
+kill @s
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry.mcfunction
new file mode 100644
index 0000000000..182dfdebf7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry.mcfunction
@@ -0,0 +1,33 @@
+# shield parry
+# @s = damaged player
+# at @s
+# run from player/damage/shield/blocked_damage
+
+tag @s add gm4_sr_attack_parried
+
+# advancements
+advancement grant @s only gm4:survival_refightalized_parry
+execute store result score $lethal_damage gm4_sr_data run attribute @s minecraft:armor get 10
+scoreboard players operation $lethal_damage gm4_sr_data += @s gm4_sr_stat.current_health
+scoreboard players operation $lethal_damage gm4_sr_data += @s gm4_sr_stat.current_absorption
+execute if score @s gm4_sr_stat.damage_resisted >= $lethal_damage gm4_sr_data run advancement grant @s only gm4:survival_refightalized_parry_lethal_damage
+
+# parry sounds
+playsound entity.arrow.hit_player player @s ~ ~ ~ 0.25 0.5
+playsound item.shield.block player @a ~ ~ ~ 1 1.25
+
+# reset spam detection
+scoreboard players set @s gm4_sr_shield.spam_detection 0
+
+# stop attacker for a bit
+tag @s add gm4_sr_parrier
+execute on attacker run function gm4_survival_refightalized:player/damage/shield/parry_effect
+tag @s remove gm4_sr_parrier
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] {"text":"Parry","color":"dark_gray"}
+
+# cleanup
+scoreboard players reset @s gm4_sr_stat.damage_resisted
+scoreboard players reset @s gm4_sr_stat.damage_blocked
+advancement revoke @s only gm4_survival_refightalized:damaged
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry_effect.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry_effect.mcfunction
new file mode 100644
index 0000000000..3a2dd185ce
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/parry_effect.mcfunction
@@ -0,0 +1,12 @@
+# shield parry effects
+# @s = entity that was parried
+# at @s
+# run from player/damage/shield/parry
+
+# weakness is already applied from the blocking action
+
+stopsound @s player minecraft:entity.player.hurt
+effect give @s[distance=..3] nausea 2 0
+effect give @s[distance=..3,type=!player] slowness 1 9 true
+effect give @s[distance=..3] slowness 2 0 true
+damage @s[distance=..3] 0.01 player_attack by @p[tag=gm4_sr_parrier]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/remove_using.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/remove_using.mcfunction
new file mode 100644
index 0000000000..091c93a522
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/remove_using.mcfunction
@@ -0,0 +1,9 @@
+# remove shield using status from player that stopped using a shield
+# @s = player
+# at unspecified
+# run from tick
+
+attribute @s minecraft:knockback_resistance modifier remove gm4_survival_refightalized:using_shield
+scoreboard players add @s gm4_sr_shield.use_ticks 999
+
+tag @s remove gm4_sr_attack_parried
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/update_vanilla_shield.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/update_vanilla_shield.mcfunction
new file mode 100644
index 0000000000..2d80a757f7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/update_vanilla_shield.mcfunction
@@ -0,0 +1,49 @@
+# update vanilla shields
+# @s = player using a shield
+# at @s
+# run from advancement using_vanilla_shield
+
+# in order for shields to work with the module we add custom_data gm4_survival_refightalized:{shield:{}}, optionally with parry_ticks
+# parry_ticks indicates the ticks after the shield is raised that the attack must be blocked for the attack to be considered a parry
+# the vanilla blocks_attacks is also copied into the item, with the exception that block_delay_seconds is set to 0.0
+
+# offhand
+execute if entity @s[advancements={gm4_survival_refightalized:using_vanilla_shield={offhand=true}}] run item modify entity @s weapon.offhand {function:"set_components",components:{\
+"custom_data":\
+ {"gm4_survival_refightalized":{\
+ "shield":{\
+ "parry_ticks":5\
+}}},\
+"minecraft:blocks_attacks": {\
+ "block_delay_seconds": 0.0,\
+ "disable_cooldown_scale": 1,\
+ "block_sound": "minecraft:item.shield.block",\
+ "bypassed_by": "#minecraft:bypasses_shield",\
+ "disabled_sound": "minecraft:item.shield.break",\
+ "item_damage": {\
+ "base": 1.0,\
+ "factor": 1.0,\
+ "threshold": 3.0\
+}}}}
+
+# mainhand
+execute if entity @s[advancements={gm4_survival_refightalized:using_vanilla_shield={mainhand=true}}] run item modify entity @s weapon.mainhand {function:"set_components",components:{\
+"custom_data":\
+ {"gm4_survival_refightalized":{\
+ "shield":{\
+ "parry_ticks":5\
+}}},\
+"minecraft:blocks_attacks": {\
+ "block_delay_seconds": 0.0,\
+ "disable_cooldown_scale": 1,\
+ "block_sound": "minecraft:item.shield.block",\
+ "bypassed_by": "#minecraft:bypasses_shield",\
+ "disabled_sound": "minecraft:item.shield.break",\
+ "item_damage": {\
+ "base": 1.0,\
+ "factor": 1.0,\
+ "threshold": 3.0\
+}}}}
+
+# revoke advancement
+advancement revoke @s only gm4_survival_refightalized:using_vanilla_shield
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/using.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/using.mcfunction
new file mode 100644
index 0000000000..095a1e4bfe
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/shield/using.mcfunction
@@ -0,0 +1,12 @@
+# run while using a shield
+# @s = player using a shield
+# at @s
+advancement revoke @s only gm4_survival_refightalized:using_custom_shield
+
+# add to spam detection so you can't just spam click your shield to parry
+execute unless score @s gm4_sr_shield.timer matches 1.. unless score @s gm4_sr_shield.spam_detection matches 30.. run scoreboard players add @s gm4_sr_shield.spam_detection 6
+
+# track how many ticks shield is being held in gm4_sr_shield.use_ticks
+execute unless score @s gm4_sr_shield.timer matches 1.. run scoreboard players set @s gm4_sr_shield.use_ticks 0
+scoreboard players add @s gm4_sr_shield.use_ticks 1
+scoreboard players set @s gm4_sr_shield.timer 2
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/witch_poison_reduction.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/witch_poison_reduction.mcfunction
new file mode 100644
index 0000000000..3c3f749058
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/damage/witch_poison_reduction.mcfunction
@@ -0,0 +1,31 @@
+# reduce poison duration from witch potions
+# @s = damaged player
+# at @s
+# run from player/damage/run
+
+# get effect data
+data modify storage gm4_survival_refightalized:temp active_effects set from entity @s active_effects
+execute store result score $poison.amplifier gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:poison"}].amplifier
+execute store result score $poison.duration gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:poison"}].duration
+
+# dont run if there is a stronger poison running
+execute unless score $poison.amplifier gm4_sr_data matches 0 run return 0
+execute unless score $poison.duration gm4_sr_data matches ..900 run return 0
+
+# reapply shorter poison by dividing duration by 3 (60 as it is in ticks), at least 2 seconds
+effect clear @s poison
+scoreboard players operation $poison.duration gm4_sr_data /= #60 gm4_sr_data
+execute if score $poison.duration gm4_sr_data matches 15.. run return run effect give @s poison 15 0
+execute if score $poison.duration gm4_sr_data matches 14 run return run effect give @s poison 14 0
+execute if score $poison.duration gm4_sr_data matches 13 run return run effect give @s poison 13 0
+execute if score $poison.duration gm4_sr_data matches 12 run return run effect give @s poison 12 0
+execute if score $poison.duration gm4_sr_data matches 11 run return run effect give @s poison 11 0
+execute if score $poison.duration gm4_sr_data matches 10 run return run effect give @s poison 10 0
+execute if score $poison.duration gm4_sr_data matches 9 run return run effect give @s poison 9 0
+execute if score $poison.duration gm4_sr_data matches 8 run return run effect give @s poison 8 0
+execute if score $poison.duration gm4_sr_data matches 7 run return run effect give @s poison 7 0
+execute if score $poison.duration gm4_sr_data matches 6 run return run effect give @s poison 6 0
+execute if score $poison.duration gm4_sr_data matches 5 run return run effect give @s poison 5 0
+execute if score $poison.duration gm4_sr_data matches 4 run return run effect give @s poison 4 0
+execute if score $poison.duration gm4_sr_data matches 3 run return run effect give @s poison 3 0
+execute if score $poison.duration gm4_sr_data matches ..2 run effect give @s poison 2 0
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/death.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/death.mcfunction
new file mode 100644
index 0000000000..1d0654aa26
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/death.mcfunction
@@ -0,0 +1,13 @@
+# process players that died
+# @s = player
+# at player that died
+# run from player/player_submain
+
+# reset scores
+scoreboard players set @s gm4_sr_stat.deaths 0
+scoreboard players set @s gm4_sr_armor.reduction 0
+scoreboard players set @s gm4_sr_armor.reduction_timer 0
+scoreboard players set @s gm4_sr_health.restoration 0
+
+# remove armor reduction so player respawns with full armor in case of KeepInventory
+attribute @s minecraft:armor modifier remove gm4_survival_refightalized:armor_reduced
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/calculate_hp.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/calculate_hp.mcfunction
new file mode 100644
index 0000000000..8b015951f4
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/calculate_hp.mcfunction
@@ -0,0 +1,27 @@
+# calculate the red health of player calling this function and store in scoreboards
+# @s = player to calculate health from
+# at unspecified
+# run from player/health/detect_sleep
+# run from player/health/regen_combat_health
+# run from player/health/regen_fast_health
+# run from player/health/heal/heal_calc
+# run from player/health/reduce/activate
+# called from expansion modules to get player health stats
+
+# get max health x10
+execute store result score @s gm4_sr_stat.max_health run attribute @s minecraft:max_health get 10
+
+# calculate current health x10 (only red hearts)
+# add healstore as that will be added to health this tick and should be counted
+execute store result score @s gm4_sr_stat.current_health run data get entity @s Health 10
+scoreboard players operation @s gm4_sr_stat.current_health += @s gm4_sr_health.restoration
+
+# calculate percentage of max health
+# this uses the rounded values displayed to the player
+scoreboard players operation @s gm4_sr_stat.health_percentage = @s gm4_sr_stat.current_health
+scoreboard players operation @s gm4_sr_stat.health_percentage *= #100 gm4_sr_data
+scoreboard players operation @s gm4_sr_stat.health_percentage /= @s gm4_sr_stat.max_health
+
+# calculate absorption health same as red hearts
+execute store result score @s gm4_sr_stat.max_absorption run attribute @s minecraft:max_absorption get 10
+execute store result score @s gm4_sr_stat.current_absorption run data get entity @s AbsorptionAmount 10
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/activate.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/activate.mcfunction
new file mode 100644
index 0000000000..5fc1002817
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/activate.mcfunction
@@ -0,0 +1,26 @@
+# code taken from sweethearts
+# @s = player to heal
+# at unspecified
+# run from player_submain
+
+# calculate health
+function gm4_survival_refightalized:player/health/calculate_hp
+
+# calculate max health to get player to new health
+# we can use stat.current_health as that already has the restoration added to it
+scoreboard players operation $remove_health gm4_sr_data = @s gm4_sr_stat.max_health
+scoreboard players operation $remove_health gm4_sr_data -= @s gm4_sr_stat.current_health
+execute store result storage gm4_survival_refightalized:temp heal_player.remove_health float 0.1 run scoreboard players get $remove_health gm4_sr_data
+
+execute unless score $remove_health gm4_sr_data matches 0 run function gm4_survival_refightalized:player/health/heal/eval with storage gm4_survival_refightalized:temp heal_player
+data remove storage gm4_survival_refightalized:temp heal_player
+
+# prepare reverting
+tag @s add gm4_sr_healed
+schedule function gm4_survival_refightalized:player/health/heal/context 1t
+
+# heal player
+effect give @s minecraft:instant_health 1 10 true
+
+# cleanup
+scoreboard players reset @s gm4_sr_health.restoration
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/context.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/context.mcfunction
new file mode 100644
index 0000000000..d883332c86
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/context.mcfunction
@@ -0,0 +1,6 @@
+# code taken from sweethearts
+# @s = unspecified
+# at unspecified
+# scheduled from player/health/heal/activate
+
+execute as @a[tag=gm4_sr_healed] run function gm4_survival_refightalized:player/health/heal/revert
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/eval.mcfunction
new file mode 100644
index 0000000000..f3f39e2a0b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/eval.mcfunction
@@ -0,0 +1,6 @@
+# reduce max health of player to their new health
+# @s = player to heal
+# at unspecified
+# run from player/health/heal/activate
+
+$attribute @s minecraft:max_health modifier add gm4_survival_refightalized:remove_health.healing -$(remove_health) add_value
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/revert.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/revert.mcfunction
new file mode 100644
index 0000000000..296729867d
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/heal/revert.mcfunction
@@ -0,0 +1,7 @@
+# code taken from sweethearts
+# @s = player to revert max health
+# at unspecified
+# run from player/health/heal/context
+
+attribute @s minecraft:max_health modifier remove gm4_survival_refightalized:remove_health.healing
+tag @s remove gm4_sr_healed
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/activate.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/activate.mcfunction
new file mode 100644
index 0000000000..6be75a3359
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/activate.mcfunction
@@ -0,0 +1,27 @@
+# code taken from sweethearts
+# @s = player to damage
+# at unspecified
+# run from player/damage/calculate_damage
+
+# calc hp and remove the healstore to get the actual current health
+function gm4_survival_refightalized:player/health/calculate_hp
+scoreboard players operation @s gm4_sr_stat.current_health -= @s gm4_sr_health.restoration
+
+# calculate max health to get player to new health
+scoreboard players operation $remove_health gm4_sr_data = @s gm4_sr_stat.max_health
+scoreboard players operation $remove_health gm4_sr_data -= @s gm4_sr_stat.current_health
+scoreboard players operation $remove_health gm4_sr_data += $damage_health gm4_sr_data
+
+# if player dies from this damage
+execute if score $remove_health gm4_sr_data >= @s gm4_sr_stat.max_health run return run function gm4_survival_refightalized:player/health/reduce/death
+
+execute store result storage gm4_survival_refightalized damage_player.remove_health float 0.1 run scoreboard players get $remove_health gm4_sr_data
+execute unless score $remove_health gm4_sr_data matches 0 run function gm4_survival_refightalized:player/health/reduce/eval with storage gm4_survival_refightalized damage_player
+data remove storage gm4_survival_refightalized damage_player
+
+# heal player to set their health
+effect give @s minecraft:instant_health 1 10 true
+
+# prepare reverting
+tag @s add gm4_sr_damaged
+schedule function gm4_survival_refightalized:player/health/reduce/context 2t
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/context.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/context.mcfunction
new file mode 100644
index 0000000000..a6eee557ef
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/context.mcfunction
@@ -0,0 +1,6 @@
+# code taken from sweethearts
+# @s = unspecified
+# at unspecified
+# schedule from player/health/reduce/activate
+
+execute as @a[tag=gm4_sr_damaged] run function gm4_survival_refightalized:player/health/reduce/revert
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death.mcfunction
new file mode 100644
index 0000000000..c310112ad3
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death.mcfunction
@@ -0,0 +1,16 @@
+# kill the player if they get reduced to 0 health
+# @s = player to damage
+# at unspecified
+# run from player/health/reduce/activate
+
+# check if player is holding item with death_protection component
+execute if items entity @s weapon.* *[death_protection] run return run function gm4_survival_refightalized:player/health/reduce/death_protection
+
+tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Custom Death Message:","color":"gray"}]
+
+# kill player with custom death message
+execute store result score $showDeathMessages gm4_sr_data run gamerule showDeathMessages
+gamerule showDeathMessages false
+kill @s
+execute if score $showDeathMessages gm4_sr_data matches 1 run tellraw @a ["",{"selector":"@s"},{"translate":"text.gm4.survival_refightalized.death","fallback":" ran out of health"}]
+execute if score $showDeathMessages gm4_sr_data matches 1 run gamerule showDeathMessages true
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death_protection.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death_protection.mcfunction
new file mode 100644
index 0000000000..ffe902a6ca
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/death_protection.mcfunction
@@ -0,0 +1,14 @@
+# preventing death with death_protection item
+# @s = player to damage
+# at unspecified
+# run from player/health/reduce/death
+
+# if player has resistance from module remove said resistance
+execute store result score $resistance_level gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].amplifier
+execute if score $resistance_level gm4_sr_data matches -1 run function gm4_survival_refightalized:player/resistance/remove
+
+# damage player to trigger death_protection item
+damage @s 99999999999999 generic
+
+# dev damage log
+tellraw @s[tag=gm4_sr_dev.damage_log] [{"text":"Triggered death_protection item","color":"gray"}]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/eval.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/eval.mcfunction
new file mode 100644
index 0000000000..7ec2445782
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/eval.mcfunction
@@ -0,0 +1,6 @@
+# reduce max health of player to their new health
+# @s = player to heal
+# at unspecified
+# run from player/health/reduce/activate
+
+$attribute @s minecraft:max_health modifier add gm4_survival_refightalized:remove_health.damaging -$(remove_health) add_value
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/revert.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/revert.mcfunction
new file mode 100644
index 0000000000..1c986876b4
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/reduce/revert.mcfunction
@@ -0,0 +1,8 @@
+# code taken from sweethearts
+# @s = player to revert max health
+# at unspecified
+# run from player/health/reduce/context
+
+# revert max health
+attribute @s minecraft:max_health modifier remove gm4_survival_refightalized:remove_health.damaging
+tag @s remove gm4_sr_damaged
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/combat_health.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/combat_health.mcfunction
new file mode 100644
index 0000000000..9985721553
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/combat_health.mcfunction
@@ -0,0 +1,11 @@
+# check if player can get some healing
+# @s = player to regenerate
+# at unspecified
+# run from player/health/regeneration/timer
+
+function gm4_survival_refightalized:player/health/calculate_hp
+execute unless score @s gm4_sr_stat.current_health < @s gm4_sr_stat.max_health run return 0
+
+# base restore 10 (half a heart), call function tag for expansions
+scoreboard players add @s gm4_sr_health.restoration 10
+function #gm4_survival_refightalized:health_regeneration
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/timer.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/timer.mcfunction
new file mode 100644
index 0000000000..e251af26ca
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/health/regeneration/timer.mcfunction
@@ -0,0 +1,11 @@
+# process the player's regen timer
+# @s = player
+# at unspecified
+# run from player_submain
+
+# gm4_sr_stat.regeneration_rate_change is normally 0, but can be changed by expansions
+scoreboard players set $regeneration_timer gm4_sr_data 100
+scoreboard players operation $regeneration_timer gm4_sr_data += @s gm4_sr_stat.regeneration_rate_change
+scoreboard players operation $regeneration_timer gm4_sr_data > #0 gm4_sr_data
+scoreboard players operation @s[scores={gm4_sr_health.regeneration_timer=1..}] gm4_sr_health.regeneration_timer -= $regeneration_timer gm4_sr_data
+execute unless score @s gm4_sr_health.regeneration_timer matches 1.. unless score @s gm4_sr_stat.hunger matches ..6 run function gm4_survival_refightalized:player/health/regeneration/combat_health
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/diamond_netherite.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/diamond_netherite.mcfunction
new file mode 100644
index 0000000000..b0efb77429
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/diamond_netherite.mcfunction
@@ -0,0 +1,6 @@
+# improve the gear mobs can use
+# @s = player with diamond / netherite gear
+# at unspecified
+# run from advancement reach_tier/diamond_netherite
+
+scoreboard players operation @s gm4_sr_armor.tier > #2 gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/iron_golden.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/iron_golden.mcfunction
new file mode 100644
index 0000000000..81a650cc3c
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/reach_tier/iron_golden.mcfunction
@@ -0,0 +1,6 @@
+# improve the gear mobs can use
+# @s = player with iron / golden gear
+# at unspecified
+# run from advancement reach_tier/iron_golden
+
+scoreboard players operation @s gm4_sr_armor.tier > #1 gm4_sr_data
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/reapply_loop.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/reapply_loop.mcfunction
new file mode 100644
index 0000000000..37b7bf8eaa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/reapply_loop.mcfunction
@@ -0,0 +1,23 @@
+# reapply resistance effects that the player had besides the one from this module
+# @s = damaged player
+# at @s
+# run from player/resistance/remove
+# run from here
+
+# reapply
+$execute unless score $duration gm4_sr_data matches 0..19 run effect give @s resistance $(duration_set) $(amplifier) $(show_icon)
+
+# check if this should keep looping
+execute unless data storage gm4_survival_refightalized:temp reapply_resistance.hidden_effect run return 0
+
+data modify storage gm4_survival_refightalized:temp reapply_resistance set from storage gm4_survival_refightalized:temp reapply_resistance.hidden_effect
+
+execute store result score $show_particles gm4_sr_data run data get storage gm4_survival_refightalized:temp reapply_resistance.show_icon
+execute if score $show_particles gm4_sr_data matches 0 run data modify storage gm4_survival_refightalized:temp reapply_resistance.show_icon set value "true"
+execute if score $show_particles gm4_sr_data matches 1 run data modify storage gm4_survival_refightalized:temp reapply_resistance.show_icon set value "false"
+
+execute store result score $duration gm4_sr_data run data get storage gm4_survival_refightalized:temp reapply_resistance.duration
+execute if score $duration gm4_sr_data matches 20.. store result storage gm4_survival_refightalized:temp reapply_resistance.duration_set int 0.05 run scoreboard players get $duration gm4_sr_data
+execute if score $duration gm4_sr_data matches -1 run data modify storage gm4_survival_refightalized:temp reapply_resistance.duration_set set value "infinite"
+
+function gm4_survival_refightalized:player/resistance/reapply_loop with storage gm4_survival_refightalized:temp reapply_resistance
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/remove.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/remove.mcfunction
new file mode 100644
index 0000000000..e1c12a9ec2
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player/resistance/remove.mcfunction
@@ -0,0 +1,28 @@
+# remove resistance from armor if armor is broken
+# @s = damaged player
+# at @s
+# run from player/damage/armor/break
+# run from player/
+
+# check if player actually has resistance that should be removed
+execute store result score $resistance_level gm4_sr_data run data get storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].amplifier
+execute unless score $resistance_level gm4_sr_data matches -1 run return 0
+
+# clear resistance to remove the immunite from armor
+effect clear @s resistance
+
+# check if the player had additional resistance levels
+execute unless data storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].hidden_effect run return 0
+
+# reapply the resistance levels that should stay
+data modify storage gm4_survival_refightalized:temp reapply_resistance set from storage gm4_survival_refightalized:temp active_effects[{id:"minecraft:resistance"}].hidden_effect
+
+execute store result score $show_particles gm4_sr_data run data get storage gm4_survival_refightalized:temp reapply_resistance.show_icon
+execute if score $show_particles gm4_sr_data matches 0 run data modify storage gm4_survival_refightalized:temp reapply_resistance.show_icon set value "true"
+execute if score $show_particles gm4_sr_data matches 1 run data modify storage gm4_survival_refightalized:temp reapply_resistance.show_icon set value "false"
+
+execute store result score $duration gm4_sr_data run data get storage gm4_survival_refightalized:temp reapply_resistance.duration
+execute if score $duration gm4_sr_data matches 20.. store result storage gm4_survival_refightalized:temp reapply_resistance.duration_set int 0.05 run scoreboard players get $duration gm4_sr_data
+execute if score $duration gm4_sr_data matches -1 run data modify storage gm4_survival_refightalized:temp reapply_resistance.duration_set set value "infinite"
+
+function gm4_survival_refightalized:player/resistance/reapply_loop with storage gm4_survival_refightalized:temp reapply_resistance
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player_submain.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player_submain.mcfunction
new file mode 100644
index 0000000000..b10d49ab1c
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/player_submain.mcfunction
@@ -0,0 +1,29 @@
+# process anything player related
+# @s = unspecified
+# at unspecified
+# scheduled from main (8t)
+
+## /!\
+# This function is NOT run as the player because the order of some of these functions is important
+
+# DEV: trigger for players with `gm4_sr_dev.mob_stats` tag
+execute as @a[tag=gm4_sr_dev.mob_stats] at @s as @n[type=#gm4_survival_refightalized:modify] run function gm4_survival_refightalized:debug/dont_run/dev
+
+# process players that died
+execute as @a[scores={gm4_sr_stat.deaths=1..}] run function gm4_survival_refightalized:player/death
+
+# reset regeneration and armor recharge changes, can be set from function tag
+scoreboard players set @a gm4_sr_stat.armor_recharge_change 0
+scoreboard players set @a gm4_sr_stat.regeneration_rate_change 0
+
+# armor recharge timer
+execute as @a[gamemode=!spectator,tag=gm4_sr_armor.reduction] run function gm4_survival_refightalized:player/armor/timer
+# health regen timer
+execute unless score $natural_regen gm4_sr_config matches -1 store result score $natural_regen gm4_sr_config run gamerule naturalRegeneration
+execute if score $natural_regen gm4_sr_config matches 0 as @a[gamemode=!spectator] run function gm4_survival_refightalized:player/health/regeneration/timer
+
+# if player has armor use new damage calculation
+effect give @a[gamemode=!spectator,scores={gm4_sr_stat.armor=1..}] resistance 2 255 true
+
+# heal players if they have stored health
+execute as @a[gamemode=!spectator,scores={gm4_sr_health.restoration=1..}] run function gm4_survival_refightalized:player/health/heal/activate
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/slow_clock.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/slow_clock.mcfunction
new file mode 100644
index 0000000000..009ab13e56
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/slow_clock.mcfunction
@@ -0,0 +1,8 @@
+schedule function gm4_survival_refightalized:slow_clock 30s
+
+# get moon cycle (0 = new moon, 4 = full moon)
+execute store result score $moon gm4_sr_data run time query day
+scoreboard players operation $moon gm4_sr_data %= #8 gm4_sr_data
+scoreboard players set $8 gm4_sr_data 8
+execute if score $moon gm4_sr_data matches ..3 store result score $moon gm4_sr_data run scoreboard players operation $8 gm4_sr_data -= $moon gm4_sr_data
+scoreboard players remove $moon gm4_sr_data 4
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/function/tick.mcfunction b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/tick.mcfunction
new file mode 100644
index 0000000000..9bcccebf13
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/function/tick.mcfunction
@@ -0,0 +1,12 @@
+schedule function gm4_survival_refightalized:tick 1t
+
+# check for player damage
+execute as @a[advancements={gm4_survival_refightalized:damaged=true}] at @s run function gm4_survival_refightalized:player/damage/run
+
+# check for projectiles
+execute as @e[type=#gm4_survival_refightalized:arrow,tag=!gm4_sr_arrow_checked,tag=!smithed.strict,tag=!smithed.entity] run function gm4_survival_refightalized:check_arrow
+
+# shield parry
+execute as @a[scores={gm4_sr_shield.timer=1}] run function gm4_survival_refightalized:player/damage/shield/remove_using
+scoreboard players remove @a[scores={gm4_sr_shield.timer=1..}] gm4_sr_shield.timer 1
+scoreboard players remove @a[scores={gm4_sr_shield.spam_detection=1..}] gm4_sr_shield.spam_detection 1
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/guidebook/survival_refightalized.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/guidebook/survival_refightalized.json
new file mode 100644
index 0000000000..ef74c1f0ee
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/guidebook/survival_refightalized.json
@@ -0,0 +1,165 @@
+{
+ "id": "survival_refightalized",
+ "name": "Survival Refightalized",
+ "module_type": "module",
+ "icon": {
+ "id": "minecraft:leather_chestplate"
+ },
+ "criteria": {
+ "equip_armor": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "feet": {
+ "items": "#gm4_survival_refightalized:armor"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "legs": {
+ "items": "#gm4_survival_refightalized:armor"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "chest": {
+ "items": "#gm4_survival_refightalized:armor"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "head": {
+ "items": "#gm4_survival_refightalized:armor"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "obtain_shield": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "player": [],
+ "items": [
+ {
+ "items": "minecraft:shield"
+ }
+ ]
+ }
+ },
+ "kill_hostile": {
+ "trigger": "minecraft:player_hurt_entity",
+ "conditions": {
+ "player": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "type_specific": {
+ "type": "player",
+ "advancements": {
+ "minecraft:adventure/kill_a_mob": true
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "sections": [
+ {
+ "name": "health",
+ "enable": [],
+ "requirements": [],
+ "pages": [
+ [
+ {
+ "insert": "title"
+ },
+ {
+ "translate": "text.gm4.guidebook.survival_refightalized.description.health",
+ "fallback": "Damage taken is split in combat and non-combat damage.\nCombat damage regenerates every 60 seconds, while non-combat damage regenerates rapidly when out of combat."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "armor",
+ "enable": [],
+ "requirements": [
+ [
+ "equip_armor"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.survival_refightalized.description.armor",
+ "fallback": "Armor no longer reduces damage taken, instead serving as a second health bar. Armor recharges rapidly shortly after it takes damage.\nProtection enchantments have reduced effectiveness."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "shield",
+ "enable": [],
+ "requirements": [
+ [
+ "obtain_shield"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.survival_refightalized.description.shield",
+ "fallback": "Shields will go on cooldown after blocking any damage.\n\nBlocking damage within 0.25s of holding the Shield performs a Parry, releasing the Shield within that 0.25s will not disable it."
+ }
+ ]
+ ]
+ },
+ {
+ "name": "mobs",
+ "enable": [],
+ "requirements": [
+ [
+ "kill_hostile"
+ ]
+ ],
+ "pages": [
+ [
+ {
+ "translate": "text.gm4.guidebook.survival_refightalized.description.mobs",
+ "fallback": "Mobs are stronger based on their environment, such as being outside during a thunderstorm or full moon, or being deep underground.\nSome mobs are altered, such as Skeletons firing slower, and Phantoms drowning."
+ }
+ ]
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/chest.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/chest.json
new file mode 100644
index 0000000000..1cf5959e69
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/chest.json
@@ -0,0 +1,115 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:diamond_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/diamond"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 2
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "golden_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/golden"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "iron_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "leather_chestplate"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_chance"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.05
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/feet.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/feet.json
new file mode 100644
index 0000000000..124f009e71
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/feet.json
@@ -0,0 +1,115 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "diamond_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/diamond"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 2
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "golden_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/golden"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "iron_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "leather_boots"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_chance"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.05
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/head.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/head.json
new file mode 100644
index 0000000000..6cb672e21d
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/head.json
@@ -0,0 +1,125 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "turtle_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/turtle_helmet"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "diamond_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/diamond"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 2
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "golden_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/golden"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "iron_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "leather_helmet"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_chance"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.05
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/legs.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/legs.json
new file mode 100644
index 0000000000..89ec7e19c4
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/generic/legs.json
@@ -0,0 +1,115 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "diamond_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/diamond"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 2
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "golden_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/golden"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "iron_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ },
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_tier"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "leather_leggings"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$armor_chance"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.05
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/chest.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/chest.json
new file mode 100644
index 0000000000..527ee03dd9
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/chest.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "golden_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.5
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/feet.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/feet.json
new file mode 100644
index 0000000000..338385a00b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/feet.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "golden_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.5
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/head.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/head.json
new file mode 100644
index 0000000000..579f3e5cfd
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/head.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "golden_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.5
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/legs.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/legs.json
new file mode 100644
index 0000000000..80fd604061
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/piglin/legs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "golden_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.5
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/skeleton/weapon.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/skeleton/weapon.json
new file mode 100644
index 0000000000..dda4a2636a
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/skeleton/weapon.json
@@ -0,0 +1,30 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:bow",
+ "functions": [
+ {
+ "function": "minecraft:enchant_with_levels",
+ "levels": {
+ "min": 0,
+ "max": 20
+ },
+ "options": "#minecraft:non_treasure",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.15
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/arrow.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/arrow.json
new file mode 100644
index 0000000000..e0beac3385
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/arrow.json
@@ -0,0 +1,49 @@
+{
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:tipped_arrow",
+ "functions": [
+ {
+ "function": "minecraft:set_components",
+ "components": {
+ "minecraft:potion_contents": {
+ "custom_color": 7561558,
+ "custom_effects": [
+ {
+ "id": "minecraft:wither",
+ "amplifier": 0,
+ "duration": 1600,
+ "show_particles": true,
+ "show_icon": true,
+ "ambient": false
+ }
+ ]
+ }
+ }
+ },
+ {
+ "function": "minecraft:set_name",
+ "target": "custom_name",
+ "name": {
+ "translate": "item.gm4.survival_refightalized.lore.wither_arrow",
+ "fallback": "Arrow of Wither",
+ "italic": false
+ }
+ },
+ {
+ "function": "minecraft:set_count",
+ "count": {
+ "min": 1,
+ "max": 4
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/chest.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/chest.json
new file mode 100644
index 0000000000..6f9311acd0
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/chest.json
@@ -0,0 +1,45 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "iron_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_chestplate",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:loot_table",
+ "value": "gm4:empty"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.666
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/feet.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/feet.json
new file mode 100644
index 0000000000..f38584fcbb
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/feet.json
@@ -0,0 +1,45 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "iron_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_boots",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:loot_table",
+ "value": "gm4:empty"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.666
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/head.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/head.json
new file mode 100644
index 0000000000..078e98895b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/head.json
@@ -0,0 +1,45 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "iron_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_helmet",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:loot_table",
+ "value": "gm4:empty"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.666
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/legs.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/legs.json
new file mode 100644
index 0000000000..19a8a64fa6
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/legs.json
@@ -0,0 +1,45 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "iron_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/iron"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "chainmail_leggings",
+ "conditions": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/material_check/chainmail"
+ }
+ ]
+ },
+ {
+ "type": "minecraft:loot_table",
+ "value": "gm4:empty"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.666
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/weapon.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/weapon.json
new file mode 100644
index 0000000000..1deb5b837a
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/mob/wither_skeleton/weapon.json
@@ -0,0 +1,29 @@
+{
+ "type": "minecraft:entity",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:bow",
+ "conditions": [
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.4
+ }
+ ]
+ },
+ {
+ "type": "minecraft:item",
+ "name": "stone_sword"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/damage.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/damage.json
new file mode 100644
index 0000000000..1498f01404
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/damage.json
@@ -0,0 +1,62 @@
+{
+ "pools": [
+ {
+ "rolls": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_damage"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.15
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ },
+ {
+ "rolls": {
+ "min": 1,
+ "max": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_damage"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.35
+ }
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ },
+ {
+ "rolls": {
+ "type": "minecraft:binomial",
+ "n": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_damage"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.5
+ },
+ "p": 0.5
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/health.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/health.json
new file mode 100644
index 0000000000..c8f0888b27
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/health.json
@@ -0,0 +1,42 @@
+{
+ "pools": [
+ {
+ "rolls": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_health"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.5
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ },
+ {
+ "rolls": {
+ "type": "minecraft:binomial",
+ "n": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_health"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.5
+ },
+ "p": 0.5
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/speed.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/speed.json
new file mode 100644
index 0000000000..d7b50a0eef
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/randomize_stats/speed.json
@@ -0,0 +1,45 @@
+{
+ "pools": [
+ {
+ "rolls": {
+ "min": 1,
+ "max": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_speed"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.5
+ }
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ },
+ {
+ "rolls": {
+ "type": "minecraft:binomial",
+ "n": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$mob_speed"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.5
+ },
+ "p": 0.5
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/technical/roll_damage.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/technical/roll_damage.json
new file mode 100644
index 0000000000..32c37c83ff
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/loot_table/technical/roll_damage.json
@@ -0,0 +1,33 @@
+{
+ "type": "minecraft:generic",
+ "pools": [
+ {
+ "rolls": {
+ "type": "minecraft:binomial",
+ "n": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$damage_opportunities"
+ },
+ "score": "gm4_sr_data"
+ },
+ "p": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$damage_chance"
+ },
+ "score": "gm4_sr_data",
+ "scale": 0.01
+ }
+ },
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/has_weapon.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/has_weapon.json
new file mode 100644
index 0000000000..8d9b27382b
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/has_weapon.json
@@ -0,0 +1,11 @@
+{
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "mainhand": {
+ "items": "#gm4_survival_refightalized:weapon"
+ }
+ }
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/chainmail.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/chainmail.json
new file mode 100644
index 0000000000..1400b12981
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/chainmail.json
@@ -0,0 +1,4 @@
+{
+ "condition": "minecraft:random_chance",
+ "chance": 0.45
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/diamond.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/diamond.json
new file mode 100644
index 0000000000..a030d4dfe2
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/diamond.json
@@ -0,0 +1,20 @@
+[
+ {
+ "condition": "minecraft:value_check",
+ "value": {
+ "type": "minecraft:score",
+ "target": {
+ "type": "minecraft:fixed",
+ "name": "$difficulty"
+ },
+ "score": "gm4_sr_data"
+ },
+ "range": {
+ "min": 25
+ }
+ },
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.0075
+ }
+]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/golden.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/golden.json
new file mode 100644
index 0000000000..cdc78a55a0
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/golden.json
@@ -0,0 +1,40 @@
+[
+ {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "#minecraft:is_badlands"
+ }
+ },
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.30
+ }
+ ]
+ },
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "biomes": "#minecraft:is_badlands"
+ }
+ }
+ },
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.15
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/iron.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/iron.json
new file mode 100644
index 0000000000..991067b543
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/iron.json
@@ -0,0 +1,36 @@
+[
+ {
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ },
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.55
+ }
+ ]
+ },
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ },
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.35
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/turtle_helmet.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/turtle_helmet.json
new file mode 100644
index 0000000000..4ea708bae8
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/material_check/turtle_helmet.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": "minecraft:random_chance",
+ "chance": 0.75
+ },
+ {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "fluid": {
+ "fluids": "#minecraft:water"
+ }
+ }
+ }
+]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/underground.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/underground.json
new file mode 100644
index 0000000000..cb9dd3a090
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/mob/underground.json
@@ -0,0 +1,22 @@
+[
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "block": {
+ "blocks": "#gm4:water"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:location_check",
+ "offsetY": 1,
+ "predicate": {
+ "light": {
+ "light": 0
+ }
+ }
+ }
+]
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/holding_vanilla_shield.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/holding_vanilla_shield.json
new file mode 100644
index 0000000000..b49412fd93
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/holding_vanilla_shield.json
@@ -0,0 +1,73 @@
+{
+ "condition": "minecraft:any_of",
+ "terms": [
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "mainhand": {
+ "items": "shield"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "mainhand": {
+ "predicates": {
+ "minecraft:custom_data": {
+ "gm4_survival_refightalized": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "offhand": {
+ "items": "shield"
+ }
+ }
+ }
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:entity_properties",
+ "entity": "this",
+ "predicate": {
+ "equipment": {
+ "offhand": {
+ "predicates": {
+ "minecraft:custom_data": {
+ "gm4_survival_refightalized": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/in_witch_hut.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/in_witch_hut.json
new file mode 100644
index 0000000000..c45cbb3197
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/in_witch_hut.json
@@ -0,0 +1,6 @@
+{
+ "condition": "minecraft:location_check",
+ "predicate": {
+ "structures": "minecraft:swamp_hut"
+ }
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/night_time.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/night_time.json
new file mode 100644
index 0000000000..26225d2480
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/night_time.json
@@ -0,0 +1,8 @@
+{
+ "condition": "minecraft:time_check",
+ "value": {
+ "min": 13188,
+ "max": 23031
+ },
+ "period": 24000
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/raining.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/raining.json
new file mode 100644
index 0000000000..5e9da27811
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/raining.json
@@ -0,0 +1,16 @@
+{
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:weather_check",
+ "raining": true
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/thundering.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/thundering.json
new file mode 100644
index 0000000000..e4afeb4bb6
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/predicate/technical/thundering.json
@@ -0,0 +1,16 @@
+{
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:weather_check",
+ "thundering": true
+ },
+ {
+ "condition": "minecraft:inverted",
+ "term": {
+ "condition": "minecraft:reference",
+ "name": "gm4_survival_refightalized:mob/underground"
+ }
+ }
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/armor_piercing.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/armor_piercing.json
new file mode 100644
index 0000000000..0422f3cdcb
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/armor_piercing.json
@@ -0,0 +1,23 @@
+{
+ "values": [
+ "minecraft:cramming",
+ "minecraft:dragon_breath",
+ "minecraft:drown",
+ "minecraft:ender_pearl",
+ "minecraft:fall",
+ "minecraft:fly_into_wall",
+ "minecraft:freeze",
+ "minecraft:generic",
+ "minecraft:generic_kill",
+ "minecraft:in_wall",
+ "minecraft:indirect_magic",
+ "minecraft:magic",
+ "minecraft:on_fire",
+ "minecraft:out_of_world",
+ "minecraft:outside_border",
+ "minecraft:sonic_boom",
+ "minecraft:stalagmite",
+ "minecraft:starve",
+ "minecraft:wither"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/combat.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/combat.json
new file mode 100644
index 0000000000..0e2442d628
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/combat.json
@@ -0,0 +1,33 @@
+{
+ "values": [
+ "minecraft:arrow",
+ "minecraft:bad_respawn_point",
+ "minecraft:dragon_breath",
+ "minecraft:falling_anvil",
+ "minecraft:falling_block",
+ "minecraft:falling_stalactite",
+ "minecraft:explosion",
+ "minecraft:hot_floor",
+ "minecraft:in_fire",
+ "minecraft:fireball",
+ "minecraft:lava",
+ "minecraft:magic",
+ "minecraft:fireworks",
+ "minecraft:indirect_magic",
+ "minecraft:lightning_bolt",
+ "minecraft:mob_attack_no_aggro",
+ "minecraft:out_of_world",
+ "minecraft:mob_attack",
+ "minecraft:mob_projectile",
+ "minecraft:player_attack",
+ "minecraft:player_explosion",
+ "minecraft:sonic_boom",
+ "minecraft:sting",
+ "minecraft:thorns",
+ "minecraft:thrown",
+ "minecraft:trident",
+ "minecraft:unattributed_fireball",
+ "minecraft:wither",
+ "minecraft:wither_skull"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/ignore.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/ignore.json
new file mode 100644
index 0000000000..7af2603929
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/damage_type/ignore.json
@@ -0,0 +1,6 @@
+{
+ "values": [
+ "#minecraft:bypasses_invulnerability",
+ "#minecraft:bypasses_resistance"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/arrow.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/arrow.json
new file mode 100644
index 0000000000..2992991bd0
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/arrow.json
@@ -0,0 +1,6 @@
+{
+ "values": [
+ "minecraft:arrow",
+ "minecraft:spectral_arrow"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/can_fire_arrows.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/can_fire_arrows.json
new file mode 100644
index 0000000000..d33f3c5294
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/can_fire_arrows.json
@@ -0,0 +1,7 @@
+{
+ "values": [
+ "#gm4_survival_refightalized:skeleton_types",
+ "minecraft:drowned",
+ "minecraft:player"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify.json
new file mode 100644
index 0000000000..9ec8e2d3ca
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify.json
@@ -0,0 +1,20 @@
+{
+ "values": [
+ "minecraft:bogged",
+ "minecraft:cave_spider",
+ "minecraft:creeper",
+ "minecraft:drowned",
+ "minecraft:enderman",
+ "minecraft:husk",
+ "minecraft:phantom",
+ "minecraft:piglin",
+ "minecraft:silverfish",
+ "minecraft:skeleton",
+ "minecraft:spider",
+ "minecraft:stray",
+ "minecraft:wither_skeleton",
+ "minecraft:zombie",
+ "minecraft:zombie_villager",
+ "minecraft:zombified_piglin"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify_in_air.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify_in_air.json
new file mode 100644
index 0000000000..e396af5310
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/modify_in_air.json
@@ -0,0 +1,8 @@
+{
+ "values": [
+ "minecraft:cave_spider",
+ "minecraft:drowned",
+ "minecraft:phantom",
+ "minecraft:silverfish"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/skeleton_types.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/skeleton_types.json
new file mode 100644
index 0000000000..0dbca73205
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/skeleton_types.json
@@ -0,0 +1,8 @@
+{
+ "values": [
+ "minecraft:bogged",
+ "minecraft:skeleton",
+ "minecraft:stray",
+ "minecraft:wither_skeleton"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/zombie_types.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/zombie_types.json
new file mode 100644
index 0000000000..d52516baa7
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/entity_type/zombie_types.json
@@ -0,0 +1,8 @@
+{
+ "values": [
+ "minecraft:drowned",
+ "minecraft:husk",
+ "minecraft:zombie",
+ "minecraft:zombie_villager"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/armor_break.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/armor_break.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/armor_break.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/damage_taken.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/damage_taken.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/damage_taken.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/piglin.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/piglin.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/piglin.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/skeleton.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/skeleton.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/skeleton.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/wither_skeleton.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/wither_skeleton.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/wither_skeleton.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/zombie.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/zombie.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/equip/zombie.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/health_regeneration.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/health_regeneration.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/health_regeneration.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_difficulty.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_difficulty.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_difficulty.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_mob.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_mob.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/init_mob.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/player_fired_arrow.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/player_fired_arrow.json
new file mode 100644
index 0000000000..82523888aa
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/function/player_fired_arrow.json
@@ -0,0 +1,3 @@
+{
+ "values": []
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/armor.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/armor.json
new file mode 100644
index 0000000000..6286d505c1
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/armor.json
@@ -0,0 +1,30 @@
+{
+ "values": [
+ "chainmail_boots",
+ "chainmail_chestplate",
+ "chainmail_helmet",
+ "chainmail_leggings",
+ "diamond_boots",
+ "diamond_chestplate",
+ "diamond_helmet",
+ "diamond_leggings",
+ "golden_boots",
+ "golden_chestplate",
+ "golden_helmet",
+ "golden_leggings",
+ "iron_boots",
+ "iron_chestplate",
+ "iron_helmet",
+ "iron_leggings",
+ "leather_boots",
+ "leather_chestplate",
+ "leather_helmet",
+ "leather_leggings",
+ "netherite_boots",
+ "netherite_chestplate",
+ "netherite_helmet",
+ "netherite_leggings",
+ "player_head",
+ "turtle_helmet"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/weapon.json b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/weapon.json
new file mode 100644
index 0000000000..670df20aba
--- /dev/null
+++ b/gm4_survival_refightalized/data/gm4_survival_refightalized/tags/item/weapon.json
@@ -0,0 +1,28 @@
+{
+ "values": [
+ "diamond_axe",
+ "diamond_pickaxe",
+ "diamond_shovel",
+ "diamond_sword",
+ "golden_axe",
+ "golden_pickaxe",
+ "golden_shovel",
+ "golden_sword",
+ "iron_axe",
+ "iron_pickaxe",
+ "iron_shovel",
+ "iron_sword",
+ "netherite_axe",
+ "netherite_pickaxe",
+ "netherite_shovel",
+ "netherite_sword",
+ "stone_axe",
+ "stone_pickaxe",
+ "stone_shovel",
+ "stone_sword",
+ "wooden_axe",
+ "wooden_pickaxe",
+ "wooden_shovel",
+ "wooden_sword"
+ ]
+}
diff --git a/gm4_survival_refightalized/data/minecraft/enchantment/blast_protection.json b/gm4_survival_refightalized/data/minecraft/enchantment/blast_protection.json
new file mode 100644
index 0000000000..c0a0c885ad
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/enchantment/blast_protection.json
@@ -0,0 +1,62 @@
+{
+ "description": {
+ "translate": "enchantment.minecraft.blast_protection"
+ },
+ "exclusive_set": "#minecraft:exclusive_set/armor",
+ "supported_items": "#minecraft:enchantable/armor",
+ "weight": 2,
+ "max_level": 4,
+ "min_cost": {
+ "base": 5,
+ "per_level_above_first": 8
+ },
+ "max_cost": {
+ "base": 13,
+ "per_level_above_first": 8
+ },
+ "anvil_cost": 4,
+ "slots": [
+ "armor"
+ ],
+ "effects": {
+ "minecraft:attributes": [
+ {
+ "id": "minecraft:enchantment.blast_protection",
+ "attribute": "minecraft:explosion_knockback_resistance",
+ "amount": {
+ "type": "minecraft:linear",
+ "base": 0.15,
+ "per_level_above_first": 0.15
+ },
+ "operation": "add_value"
+ }
+ ],
+ "minecraft:damage_protection": [
+ {
+ "effect": {
+ "type": "minecraft:add",
+ "value": {
+ "type": "minecraft:linear",
+ "base": 1,
+ "per_level_above_first": 1
+ }
+ },
+ "requirements": {
+ "condition": "minecraft:damage_source_properties",
+ "predicate": {
+ "tags": [
+ {
+ "id": "minecraft:is_explosion",
+ "expected": true
+ },
+ {
+ "id": "minecraft:bypasses_invulnerability",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/gm4_survival_refightalized/data/minecraft/enchantment/fire_protection.json b/gm4_survival_refightalized/data/minecraft/enchantment/fire_protection.json
new file mode 100644
index 0000000000..aa247b271a
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/enchantment/fire_protection.json
@@ -0,0 +1,67 @@
+{
+ "description": {
+ "translate": "enchantment.minecraft.fire_protection"
+ },
+ "exclusive_set": "#minecraft:exclusive_set/armor",
+ "supported_items": "#minecraft:enchantable/armor",
+ "weight": 5,
+ "max_level": 4,
+ "min_cost": {
+ "base": 10,
+ "per_level_above_first": 8
+ },
+ "max_cost": {
+ "base": 18,
+ "per_level_above_first": 8
+ },
+ "anvil_cost": 2,
+ "slots": [
+ "armor"
+ ],
+ "effects": {
+ "minecraft:attributes": [
+ {
+ "id": "minecraft:enchantment.fire_protection",
+ "attribute": "minecraft:burning_time",
+ "amount": {
+ "type": "minecraft:linear",
+ "base": -0.15,
+ "per_level_above_first": -0.15
+ },
+ "operation": "add_multiplied_base"
+ }
+ ],
+ "minecraft:damage_protection": [
+ {
+ "effect": {
+ "type": "minecraft:add",
+ "value": {
+ "type": "minecraft:linear",
+ "base": 1,
+ "per_level_above_first": 1
+ }
+ },
+ "requirements": {
+ "condition": "minecraft:all_of",
+ "terms": [
+ {
+ "condition": "minecraft:damage_source_properties",
+ "predicate": {
+ "tags": [
+ {
+ "id": "minecraft:is_fire",
+ "expected": true
+ },
+ {
+ "id": "minecraft:bypasses_invulnerability",
+ "expected": false
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
diff --git a/gm4_survival_refightalized/data/minecraft/enchantment/projectile_protection.json b/gm4_survival_refightalized/data/minecraft/enchantment/projectile_protection.json
new file mode 100644
index 0000000000..5e5d906297
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/enchantment/projectile_protection.json
@@ -0,0 +1,50 @@
+{
+ "description": {
+ "translate": "enchantment.minecraft.projectile_protection"
+ },
+ "exclusive_set": "#minecraft:exclusive_set/armor",
+ "supported_items": "#minecraft:enchantable/armor",
+ "weight": 5,
+ "max_level": 4,
+ "min_cost": {
+ "base": 3,
+ "per_level_above_first": 6
+ },
+ "max_cost": {
+ "base": 9,
+ "per_level_above_first": 6
+ },
+ "anvil_cost": 2,
+ "slots": [
+ "armor"
+ ],
+ "effects": {
+ "minecraft:damage_protection": [
+ {
+ "effect": {
+ "type": "minecraft:add",
+ "value": {
+ "type": "minecraft:linear",
+ "base": 1,
+ "per_level_above_first": 1
+ }
+ },
+ "requirements": {
+ "condition": "minecraft:damage_source_properties",
+ "predicate": {
+ "tags": [
+ {
+ "id": "minecraft:is_projectile",
+ "expected": true
+ },
+ {
+ "id": "minecraft:bypasses_invulnerability",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/gm4_survival_refightalized/data/minecraft/enchantment/protection.json b/gm4_survival_refightalized/data/minecraft/enchantment/protection.json
new file mode 100644
index 0000000000..57caa44613
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/enchantment/protection.json
@@ -0,0 +1,46 @@
+{
+ "description": {
+ "translate": "enchantment.minecraft.protection"
+ },
+ "exclusive_set": "#minecraft:exclusive_set/armor",
+ "supported_items": "#minecraft:enchantable/armor",
+ "weight": 10,
+ "max_level": 4,
+ "min_cost": {
+ "base": 1,
+ "per_level_above_first": 11
+ },
+ "max_cost": {
+ "base": 12,
+ "per_level_above_first": 11
+ },
+ "anvil_cost": 1,
+ "slots": [
+ "armor"
+ ],
+ "effects": {
+ "minecraft:damage_protection": [
+ {
+ "effect": {
+ "type": "minecraft:add",
+ "value": {
+ "type": "minecraft:linear",
+ "base": 0.25,
+ "per_level_above_first": 0.25
+ }
+ },
+ "requirements": {
+ "condition": "minecraft:damage_source_properties",
+ "predicate": {
+ "tags": [
+ {
+ "id": "minecraft:bypasses_invulnerability",
+ "expected": false
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_armor.json b/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_armor.json
new file mode 100644
index 0000000000..c9dc2505f3
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_armor.json
@@ -0,0 +1,54 @@
+{
+ "replace": false,
+ "values": [
+ "minecraft:arrow",
+ "minecraft:bad_respawn_point",
+ "minecraft:cactus",
+ "minecraft:campfire",
+ "minecraft:cramming",
+ "minecraft:dragon_breath",
+ "minecraft:drown",
+ "minecraft:dry_out",
+ "minecraft:explosion",
+ "minecraft:fall",
+ "minecraft:falling_anvil",
+ "minecraft:falling_block",
+ "minecraft:falling_stalactite",
+ "minecraft:fireball",
+ "minecraft:fireworks",
+ "minecraft:fireworks",
+ "minecraft:fly_into_wall",
+ "minecraft:freeze",
+ "minecraft:generic",
+ "minecraft:generic_kill",
+ "minecraft:hot_floor",
+ "minecraft:in_fire",
+ "minecraft:in_wall",
+ "minecraft:indirect_magic",
+ "minecraft:lava",
+ "minecraft:lightning_bolt",
+ "minecraft:magic",
+ "minecraft:mob_attack",
+ "minecraft:mob_attack_no_aggro",
+ "minecraft:mob_projectile",
+ "minecraft:on_fire",
+ "minecraft:out_of_world",
+ "minecraft:outside_border",
+ "minecraft:player_attack",
+ "minecraft:player_explosion",
+ "minecraft:sonic_boom",
+ "minecraft:spit",
+ "minecraft:stalagmite",
+ "minecraft:starve",
+ "minecraft:sting",
+ "minecraft:sweet_berry_bush",
+ "minecraft:thorns",
+ "minecraft:thrown",
+ "minecraft:trident",
+ "minecraft:unattributed_fireball",
+ "minecraft:wind_charge",
+ "minecraft:wither",
+ "minecraft:wither_skull"
+ ]
+ }
+
\ No newline at end of file
diff --git a/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_shield.json b/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_shield.json
new file mode 100644
index 0000000000..2fed131b67
--- /dev/null
+++ b/gm4_survival_refightalized/data/minecraft/tags/damage_type/bypasses_shield.json
@@ -0,0 +1,35 @@
+{
+ "replace": true,
+ "values": [
+ "minecraft:cramming",
+ "minecraft:dragon_breath",
+ "minecraft:drown",
+ "minecraft:ender_pearl",
+ "minecraft:fall",
+ "minecraft:fly_into_wall",
+ "minecraft:freeze",
+ "minecraft:generic",
+ "minecraft:generic_kill",
+ "minecraft:in_wall",
+ "minecraft:indirect_magic",
+ "minecraft:magic",
+ "minecraft:on_fire",
+ "minecraft:out_of_world",
+ "minecraft:outside_border",
+ "minecraft:sonic_boom",
+ "minecraft:stalagmite",
+ "minecraft:starve",
+ "minecraft:wither",
+
+ "minecraft:cactus",
+ "minecraft:campfire",
+ "minecraft:dry_out",
+ "minecraft:falling_anvil",
+ "minecraft:falling_stalactite",
+ "minecraft:hot_floor",
+ "minecraft:in_fire",
+ "minecraft:lava",
+ "minecraft:lightning_bolt",
+ "minecraft:sweet_berry_bush"
+ ]
+}
diff --git a/gm4_survival_refightalized/images/survival_refightalized.png b/gm4_survival_refightalized/images/survival_refightalized.png
new file mode 100644
index 0000000000..2691a6e511
Binary files /dev/null and b/gm4_survival_refightalized/images/survival_refightalized.png differ
diff --git a/gm4_survival_refightalized/pack.svg b/gm4_survival_refightalized/pack.svg
new file mode 100644
index 0000000000..1c1522260c
--- /dev/null
+++ b/gm4_survival_refightalized/pack.svg
@@ -0,0 +1,118 @@
+
+
+
diff --git a/gm4_survival_refightalized/translations.csv b/gm4_survival_refightalized/translations.csv
new file mode 100644
index 0000000000..79b2243fb4
--- /dev/null
+++ b/gm4_survival_refightalized/translations.csv
@@ -0,0 +1,14 @@
+key,en_us
+advancement.gm4.survival_refightalized.armor_damage.title,Armor Up!
+advancement.gm4.survival_refightalized.armor_damage.description,Discover that Armor works a bit differently now
+advancement.gm4.survival_refightalized.parry.title,Not Today
+advancement.gm4.survival_refightalized.parry.description,Parry with a Shield by blocking just before an attack
+advancement.gm4.survival_refightalized.parry_lethal_damage.title,"Not Today, Either"
+advancement.gm4.survival_refightalized.parry_lethal_damage.description,Block lethal damage with a Shield Parry
+item.gm4.survival_refightalized.lore.wither_arrow,Arrow of Wither
+text.gm4.survival_refightalized.death, ran out of health
+text.gm4.guidebook.module_desc.survival_refightalized,A reworked survival experience with more varied mobs and new armor and shield mechanics.
+text.gm4.guidebook.survival_refightalized.description.health,"Damage taken is split in combat and non-combat damage.\nCombat damage regenerates every 60 seconds, while non-combat damage regenerates rapidly when out of combat."
+text.gm4.guidebook.survival_refightalized.description.mobs,"Mobs are stronger based on their environment, such as being outside during a thunderstorm or full moon, or being deep underground.\nSome mobs are altered, such as Skeletons firing slower, and Phantoms drowning."
+text.gm4.guidebook.survival_refightalized.description.armor,"Armor no longer reduces damage taken, instead serving as a second health bar. Armor recharges rapidly shortly after it takes damage.\nProtection enchantments have reduced effectiveness."
+text.gm4.guidebook.survival_refightalized.description.shield,"Shields will go on cooldown after blocking any damage.\n\nBlocking damage within 0.25s of holding the Shield performs a Parry, releasing the Shield within that 0.25s will not disable it."