diff --git a/assets/entities.json b/assets/entities.json index aa29958ed..5b4ee54df 100644 --- a/assets/entities.json +++ b/assets/entities.json @@ -8,7 +8,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "acacia_chest_boat": { "id": 1, @@ -19,7 +23,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "allay": { "id": 2, @@ -35,6 +43,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/allay" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "area_effect_cloud": { @@ -46,7 +58,11 @@ 6.0, 0.5 ], - "eye_height": 0.425 + "eye_height": 0.425, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "armadillo": { "id": 4, @@ -62,6 +78,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/armadillo" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "armor_stand": { @@ -78,6 +98,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/armor_stand" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "arrow": { @@ -89,7 +113,11 @@ 0.5, 0.5 ], - "eye_height": 0.13 + "eye_height": 0.13, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "axolotl": { "id": 7, @@ -105,6 +133,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/axolotl" + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "bamboo_chest_raft": { @@ -116,7 +148,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "bamboo_raft": { "id": 9, @@ -127,7 +163,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "bat": { "id": 10, @@ -143,6 +183,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/bat" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "bee": { @@ -159,6 +203,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/bee" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "birch_boat": { @@ -170,7 +218,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "birch_chest_boat": { "id": 13, @@ -181,7 +233,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "blaze": { "id": 14, @@ -234,6 +290,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "block_display": { @@ -245,7 +305,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "bogged": { "id": 16, @@ -363,6 +427,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "breeze": { @@ -416,6 +484,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "breeze_wind_charge": { @@ -427,7 +499,11 @@ 0.3125, 0.3125 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "camel": { "id": 19, @@ -443,6 +519,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/camel" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "cat": { @@ -482,6 +562,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "cave_spider": { @@ -565,6 +649,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "cherry_boat": { @@ -576,7 +664,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "cherry_chest_boat": { "id": 23, @@ -587,7 +679,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "chest_minecart": { "id": 24, @@ -598,7 +694,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "chicken": { "id": 25, @@ -703,6 +803,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "cod": { @@ -785,6 +889,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "command_block_minecart": { @@ -796,7 +904,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "cow": { "id": 28, @@ -910,6 +1022,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "creaking": { @@ -926,6 +1042,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/creaking" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "creeper": { @@ -994,6 +1114,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "dark_oak_boat": { @@ -1005,7 +1129,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "dark_oak_chest_boat": { "id": 32, @@ -1016,7 +1144,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "dolphin": { "id": 33, @@ -1100,6 +1232,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "donkey": { @@ -1148,6 +1284,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "dragon_fireball": { @@ -1159,7 +1299,11 @@ 1.0, 1.0 ], - "eye_height": 0.85 + "eye_height": 0.85, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "drowned": { "id": 36, @@ -1232,6 +1376,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "egg": { @@ -1243,7 +1391,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "elder_guardian": { "id": 38, @@ -1460,6 +1612,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "enderman": { @@ -1508,6 +1664,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "endermite": { @@ -1524,6 +1684,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/endermite" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "ender_dragon": { @@ -1540,6 +1704,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/ender_dragon" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "ender_pearl": { @@ -1551,7 +1719,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "end_crystal": { "id": 43, @@ -1562,7 +1734,11 @@ 2.0, 2.0 ], - "eye_height": 1.7 + "eye_height": 1.7, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "evoker": { "id": 44, @@ -1625,6 +1801,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "evoker_fangs": { @@ -1636,7 +1816,11 @@ 0.5, 0.8 ], - "eye_height": 0.68 + "eye_height": 0.68, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "experience_bottle": { "id": 46, @@ -1647,7 +1831,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "experience_orb": { "id": 47, @@ -1658,7 +1846,11 @@ 0.5, 0.5 ], - "eye_height": 0.425 + "eye_height": 0.425, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "eye_of_ender": { "id": 48, @@ -1669,7 +1861,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "falling_block": { "id": 49, @@ -1680,7 +1876,11 @@ 0.98, 0.98 ], - "eye_height": 0.83300006 + "eye_height": 0.83300006, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "fireball": { "id": 50, @@ -1691,7 +1891,11 @@ 1.0, 1.0 ], - "eye_height": 0.85 + "eye_height": 0.85, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "firework_rocket": { "id": 51, @@ -1702,7 +1906,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "fox": { "id": 52, @@ -1718,6 +1926,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/fox" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "frog": { @@ -1734,6 +1946,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/frog" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "furnace_minecart": { @@ -1745,7 +1961,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "ghast": { "id": 55, @@ -1823,6 +2043,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "giant": { @@ -1839,6 +2063,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/giant" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "glow_item_frame": { @@ -1850,7 +2078,11 @@ 0.5, 0.5 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "glow_squid": { "id": 58, @@ -1898,6 +2130,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "goat": { @@ -1914,6 +2150,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/goat" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "guardian": { @@ -2102,6 +2342,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "hoglin": { @@ -2216,6 +2460,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "hopper_minecart": { @@ -2227,7 +2475,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "horse": { "id": 63, @@ -2275,6 +2527,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "husk": { @@ -2394,6 +2650,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "illusioner": { @@ -2410,6 +2670,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/illusioner" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "interaction": { @@ -2421,7 +2685,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "iron_golem": { "id": 67, @@ -2481,6 +2749,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "item": { @@ -2492,7 +2764,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "item_display": { "id": 69, @@ -2503,7 +2779,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "item_frame": { "id": 70, @@ -2514,7 +2794,11 @@ 0.5, 0.5 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "jungle_boat": { "id": 71, @@ -2525,7 +2809,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "jungle_chest_boat": { "id": 72, @@ -2536,7 +2824,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "leash_knot": { "id": 73, @@ -2547,7 +2839,11 @@ 0.375, 0.5 ], - "eye_height": 0.0625 + "eye_height": 0.0625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "lightning_bolt": { "id": 74, @@ -2558,7 +2854,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "llama": { "id": 75, @@ -2606,6 +2906,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "llama_spit": { @@ -2617,7 +2921,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "magma_cube": { "id": 77, @@ -2762,6 +3070,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "mangrove_boat": { @@ -2773,7 +3085,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "mangrove_chest_boat": { "id": 79, @@ -2784,7 +3100,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "marker": { "id": 80, @@ -2795,7 +3115,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "minecart": { "id": 81, @@ -2806,7 +3130,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "mooshroom": { "id": 82, @@ -2920,6 +3248,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "mule": { @@ -2968,6 +3300,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "oak_boat": { @@ -2979,7 +3315,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "oak_chest_boat": { "id": 85, @@ -2990,7 +3330,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "ocelot": { "id": 86, @@ -3006,6 +3350,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/ocelot" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING" } }, "ominous_item_spawner": { @@ -3017,7 +3365,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "painting": { "id": 88, @@ -3028,7 +3380,11 @@ 0.5, 0.5 ], - "eye_height": 0.425 + "eye_height": 0.425, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "pale_oak_boat": { "id": 89, @@ -3039,7 +3395,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "pale_oak_chest_boat": { "id": 90, @@ -3050,7 +3410,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "panda": { "id": 91, @@ -3085,6 +3449,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "parrot": { @@ -3133,6 +3501,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING" } }, "phantom": { @@ -3186,6 +3558,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "pig": { @@ -3270,6 +3646,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "piglin": { @@ -3286,6 +3666,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/piglin" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "piglin_brute": { @@ -3302,6 +3686,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/piglin_brute" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "pillager": { @@ -3357,6 +3745,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "polar_bear": { @@ -3502,6 +3894,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "splash_potion": { @@ -3513,7 +3909,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "lingering_potion": { "id": 100, @@ -3524,7 +3924,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "pufferfish": { "id": 101, @@ -3575,6 +3979,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "rabbit": { @@ -3710,6 +4118,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "ravager": { @@ -3745,6 +4157,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "salmon": { @@ -3827,6 +4243,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "sheep": { @@ -4226,6 +4646,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "shulker": { @@ -4266,6 +4690,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "shulker_bullet": { @@ -4277,7 +4705,11 @@ 0.3125, 0.3125 ], - "eye_height": 0.265625 + "eye_height": 0.265625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "silverfish": { "id": 108, @@ -4293,6 +4725,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/silverfish" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "skeleton": { @@ -4371,6 +4807,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "skeleton_horse": { @@ -4419,6 +4859,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "slime": { @@ -4513,6 +4957,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "small_fireball": { @@ -4524,7 +4972,11 @@ 0.3125, 0.3125 ], - "eye_height": 0.265625 + "eye_height": 0.265625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "sniffer": { "id": 113, @@ -4540,6 +4992,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/sniffer" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "snowball": { @@ -4551,7 +5007,11 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "snow_golem": { "id": 115, @@ -4590,6 +5050,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "spawner_minecart": { @@ -4601,7 +5065,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "spectral_arrow": { "id": 117, @@ -4612,7 +5080,11 @@ 0.5, 0.5 ], - "eye_height": 0.13 + "eye_height": 0.13, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "spider": { "id": 118, @@ -4695,6 +5167,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "spruce_boat": { @@ -4706,7 +5182,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "spruce_chest_boat": { "id": 120, @@ -4717,7 +5197,11 @@ 1.375, 0.5625 ], - "eye_height": 0.5625 + "eye_height": 0.5625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "squid": { "id": 121, @@ -4765,6 +5249,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "stray": { @@ -4883,6 +5371,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "strider": { @@ -4931,6 +5423,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_LAVA", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "tadpole": { @@ -4947,6 +5443,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/tadpole" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "text_display": { @@ -4958,7 +5458,11 @@ 0.0, 0.0 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "tnt": { "id": 126, @@ -4969,7 +5473,11 @@ 0.98, 0.98 ], - "eye_height": 0.15 + "eye_height": 0.15, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "tnt_minecart": { "id": 127, @@ -4980,7 +5488,11 @@ 0.98, 0.7 ], - "eye_height": 0.595 + "eye_height": 0.595, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "trader_llama": { "id": 128, @@ -5028,6 +5540,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "trident": { @@ -5039,7 +5555,11 @@ 0.5, 0.5 ], - "eye_height": 0.13 + "eye_height": 0.13, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "tropical_fish": { "id": 130, @@ -5090,6 +5610,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "IN_WATER", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "turtle": { @@ -5162,6 +5686,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "vex": { @@ -5178,6 +5706,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/vex" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "villager": { @@ -5194,6 +5726,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/villager" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "vindicator": { @@ -5247,6 +5783,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "wandering_trader": { @@ -5263,6 +5803,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/wandering_trader" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "warden": { @@ -5291,6 +5835,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "wind_charge": { @@ -5302,7 +5850,11 @@ 0.3125, 0.3125 ], - "eye_height": 0.0 + "eye_height": 0.0, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "witch": { "id": 138, @@ -5505,6 +6057,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "wither": { @@ -5521,6 +6077,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/wither" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "wither_skeleton": { @@ -5624,6 +6184,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "wither_skull": { @@ -5635,7 +6199,11 @@ 0.3125, 0.3125 ], - "eye_height": 0.265625 + "eye_height": 0.265625, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } }, "wolf": { "id": 142, @@ -5651,6 +6219,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/wolf" + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "zoglin": { @@ -5699,6 +6271,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "zombie": { @@ -5818,6 +6394,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "zombie_horse": { @@ -5866,6 +6446,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "zombie_villager": { @@ -5985,6 +6569,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "zombified_piglin": { @@ -6088,6 +6676,10 @@ ] } ] + }, + "spawn_restriction": { + "location": "ON_GROUND", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "player": { @@ -6102,6 +6694,10 @@ "loot_table": { "type": "minecraft:entity", "random_sequence": "minecraft:entities/player" + }, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" } }, "fishing_bobber": { @@ -6113,6 +6709,10 @@ 0.25, 0.25 ], - "eye_height": 0.2125 + "eye_height": 0.2125, + "spawn_restriction": { + "location": "UNRESTRICTED", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + } } } \ No newline at end of file diff --git a/pumpkin-data/build/biome.rs b/pumpkin-data/build/biome.rs index bd443a9aa..c39cdfb4c 100644 --- a/pumpkin-data/build/biome.rs +++ b/pumpkin-data/build/biome.rs @@ -14,9 +14,39 @@ struct Biome { temperature_modifier: Option, //carvers: Vec, features: Vec>, + creature_spawn_probability: Option, + spawners: SpawnGroups, id: u8, } +#[derive(Deserialize, PartialEq, Eq, Hash)] +struct SpawnGroups { + monster: Vec, + ambient: Vec, + axolotls: Vec, + creature: Vec, + misc: Vec, + underground_water_creature: Vec, + water_ambient: Vec, + water_creature: Vec, +} + +#[derive(Deserialize, Hash, PartialEq, Eq)] +struct Spawner { + r#type: String, +} + +impl Spawner { + pub fn to_tokens(&self) -> TokenStream { + let r#type = &self.r#type; + quote! { + Spawner { + r#type: #r#type, + } + } + } +} + #[derive(Deserialize, Clone)] #[serde(rename_all = "snake_case")] enum TemperatureModifier { @@ -123,11 +153,70 @@ pub(crate) fn build() -> TokenStream { let downfall = biome.downfall; // let carvers = &biome.carvers; let features = &biome.features; + let creature_spawn_probability = &biome.creature_spawn_probability.unwrap_or(0.1); + let temperature_modifier = biome .temperature_modifier .clone() .unwrap_or(TemperatureModifier::None); + let monster: Vec<_> = biome + .spawners + .monster + .iter() + .map(|s| s.to_tokens()) + .collect(); + let ambient: Vec<_> = biome + .spawners + .ambient + .iter() + .map(|s| s.to_tokens()) + .collect(); + let axolotls: Vec<_> = biome + .spawners + .axolotls + .iter() + .map(|s| s.to_tokens()) + .collect(); + let creature: Vec<_> = biome + .spawners + .creature + .iter() + .map(|s| s.to_tokens()) + .collect(); + let misc: Vec<_> = biome.spawners.misc.iter().map(|s| s.to_tokens()).collect(); + let underground_water_creature: Vec<_> = biome + .spawners + .underground_water_creature + .iter() + .map(|s| s.to_tokens()) + .collect(); + let water_ambient: Vec<_> = biome + .spawners + .water_ambient + .iter() + .map(|s| s.to_tokens()) + .collect(); + let water_creature: Vec<_> = biome + .spawners + .water_creature + .iter() + .map(|s| s.to_tokens()) + .collect(); + + let spawners = quote! { + SpawnGroups { + monster: &[#(#monster),*], + ambient: &[#(#ambient),*], + axolotls: &[#(#axolotls),*], + creature: &[#(#creature),*], + misc: &[#(#misc),*], + underground_water_creature: &[#(#underground_water_creature),*], + water_ambient: &[#(#water_ambient),*], + water_creature: &[#(#water_creature),*], + } + }; + let temperature_modifier = match temperature_modifier { TemperatureModifier::Frozen => quote! { TemperatureModifier::Frozen }, TemperatureModifier::None => quote! { TemperatureModifier::None }, @@ -144,7 +233,9 @@ pub(crate) fn build() -> TokenStream { #temperature_modifier, #downfall ), - features: &[#(&[#(#features),*]),*] + features: &[#(&[#(#features),*]),*], + creature_spawn_probability: #creature_spawn_probability, + spawners: #spawners, }; }]); @@ -154,188 +245,207 @@ pub(crate) fn build() -> TokenStream { let overworld_tree = biome_trees.overworld.into_token_stream(); let nether_tree = biome_trees.nether.into_token_stream(); - quote! { - use pumpkin_util::biome::{TemperatureModifier, Weather}; - use serde::{Deserializer, de}; - use crate::biome::de::Deserialize; - use std::{fmt, hash::{Hasher, Hash}}; - #[derive(Debug)] - pub struct Biome { - pub id: u8, - pub registry_id: &'static str, - pub weather: Weather, - // carvers: &'static [&str], - pub features: &'static [&'static [&'static str]] - } + use pumpkin_util::biome::{TemperatureModifier, Weather}; + use serde::{Deserializer, de}; + use crate::biome::de::Deserialize; + use std::{fmt, hash::{Hasher, Hash}}; - impl PartialEq for Biome { - fn eq(&self, other: &Biome) -> bool { - self.id == other.id + #[derive(Debug)] + pub struct Biome { + pub id: u8, + pub registry_id: &'static str, + pub weather: Weather, + // carvers: &'static [&str], + pub features: &'static [&'static [&'static str]], + pub creature_spawn_probability: f32, + pub spawners: SpawnGroups, } - } - impl Eq for Biome {} - - impl Hash for Biome { - fn hash(&self, state: &mut H) where H: Hasher { - self.id.hash(state); + #[derive(Debug)] + pub struct SpawnGroups { + pub monster: &'static [Spawner], + pub ambient: &'static [Spawner], + pub axolotls: &'static [Spawner], + pub creature: &'static [Spawner], + pub misc: &'static [Spawner], + pub underground_water_creature: &'static [Spawner], + pub water_ambient: &'static [Spawner], + pub water_creature: &'static [Spawner], } - } - impl<'de> Deserialize<'de> for &'static Biome { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct BiomeVisitor; + #[derive(Debug)] + pub struct Spawner { + pub r#type: &'static str, + } - impl de::Visitor<'_> for BiomeVisitor { - type Value = &'static Biome; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a biome name as a string") - } - - fn visit_string(self, v: String) -> Result - where - E: serde::de::Error, - { - self.visit_str(&v) - } - - fn visit_str(self, value: &str) -> Result - where - E: de::Error, - { - let biome = Biome::from_name(value.strip_prefix("minecraft:").unwrap_or(value)); - biome.ok_or_else(|| E::unknown_variant(value, &["unknown biome"])) - } - } - - deserializer.deserialize_str(BiomeVisitor) - } - } - - impl Biome { - #variants - - pub fn from_name(name: &str) -> Option<&'static Self> { - match name { - #name_to_type - _ => None + impl PartialEq for Biome { + fn eq(&self, other: &Biome) -> bool { + self.id == other.id } } - pub const fn from_id(id: u8) -> Option<&'static Self> { - match id { - #id_to_type - _ => None - } - } - } + impl Eq for Biome {} - #[derive(PartialEq)] - pub struct ParameterRange { - min: i64, - max: i64, - } - - impl ParameterRange { - fn calc_distance(&self, noise: i64) -> i64 { - if noise > self.max { - noise - self.max - } else if noise < self.min { - self.min - noise - } else { - 0 - } - } - } - - #[derive(PartialEq)] - pub enum BiomeTree { - Leaf { - parameters: [ParameterRange; 7], - biome: &'static Biome, - }, - Branch { - parameters: [ParameterRange; 7], - nodes: &'static [BiomeTree], - }, - } - - - impl BiomeTree { - pub fn get( - &'static self, - point_list: &[i64; 7], - previous_result_node: &mut Option<&'static BiomeTree>, - ) -> &'static Biome { - let result_node = self.get_resulting_node(point_list, *previous_result_node); - match result_node { - BiomeTree::Leaf { biome, .. } => { - *previous_result_node = Some(result_node); - biome - } - _ => unreachable!(), + impl Hash for Biome { + fn hash(&self, state: &mut H) where H: Hasher { + self.id.hash(state); } } - fn get_resulting_node( - &'static self, - point_list: &[i64; 7], - previous_result_node: Option<&'static BiomeTree>, - ) -> &'static BiomeTree { - match self { - Self::Leaf { .. } => self, - Self::Branch { nodes, .. } => { - let mut distance = previous_result_node - .map(|node| node.get_squared_distance(point_list)) - .unwrap_or(i64::MAX); - let mut best_node = previous_result_node; + impl<'de> Deserialize<'de> for &'static Biome { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct BiomeVisitor; - for node in *nodes { - let node_distance = node.get_squared_distance(point_list); - if distance > node_distance { - let node2 = node.get_resulting_node(point_list, best_node); - let node2_distance = if node == node2 { - node_distance - } else { - node2.get_squared_distance(point_list) - }; + impl de::Visitor<'_> for BiomeVisitor { + type Value = &'static Biome; - if distance > node2_distance { - distance = node2_distance; - best_node = Some(node2); - } - } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a biome name as a string") } - best_node.expect("This should be populated after traversing the tree") + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + self.visit_str(&v) + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + let biome = Biome::from_name(value.strip_prefix("minecraft:").unwrap_or(value)); + biome.ok_or_else(|| E::unknown_variant(value, &["unknown biome"])) + } + } + + deserializer.deserialize_str(BiomeVisitor) + } + } + + impl Biome { + #variants + + pub fn from_name(name: &str) -> Option<&'static Self> { + match name { + #name_to_type + _ => None + } + } + + pub const fn from_id(id: u8) -> Option<&'static Self> { + match id { + #id_to_type + _ => None } } } - fn get_squared_distance(&self, point_list: &[i64; 7]) -> i64 { - let parameters = match self { - Self::Leaf { parameters, .. } => parameters, - Self::Branch { parameters, .. } => parameters, - }; - - parameters - .iter() - .zip(point_list) - .map(|(bound, value)| { - let distance = bound.calc_distance(*value); - distance * distance - }) - .sum() + #[derive(PartialEq)] + pub struct ParameterRange { + min: i64, + max: i64, } - } - pub const OVERWORLD_BIOME_SOURCE: BiomeTree = #overworld_tree; - pub const NETHER_BIOME_SOURCE: BiomeTree = #nether_tree; - } + impl ParameterRange { + fn calc_distance(&self, noise: i64) -> i64 { + if noise > self.max { + noise - self.max + } else if noise < self.min { + self.min - noise + } else { + 0 + } + } + } + + #[derive(PartialEq)] + pub enum BiomeTree { + Leaf { + parameters: [ParameterRange; 7], + biome: &'static Biome, + }, + Branch { + parameters: [ParameterRange; 7], + nodes: &'static [BiomeTree], + }, + } + + + impl BiomeTree { + pub fn get( + &'static self, + point_list: &[i64; 7], + previous_result_node: &mut Option<&'static BiomeTree>, + ) -> &'static Biome { + let result_node = self.get_resulting_node(point_list, *previous_result_node); + match result_node { + BiomeTree::Leaf { biome, .. } => { + *previous_result_node = Some(result_node); + biome + } + _ => unreachable!(), + } + } + + fn get_resulting_node( + &'static self, + point_list: &[i64; 7], + previous_result_node: Option<&'static BiomeTree>, + ) -> &'static BiomeTree { + match self { + Self::Leaf { .. } => self, + Self::Branch { nodes, .. } => { + let mut distance = previous_result_node + .map(|node| node.get_squared_distance(point_list)) + .unwrap_or(i64::MAX); + let mut best_node = previous_result_node; + + for node in *nodes { + let node_distance = node.get_squared_distance(point_list); + if distance > node_distance { + let node2 = node.get_resulting_node(point_list, best_node); + let node2_distance = if node == node2 { + node_distance + } else { + node2.get_squared_distance(point_list) + }; + + if distance > node2_distance { + distance = node2_distance; + best_node = Some(node2); + } + } + } + + best_node.expect("This should be populated after traversing the tree") + } + } + } + + fn get_squared_distance(&self, point_list: &[i64; 7]) -> i64 { + let parameters = match self { + Self::Leaf { parameters, .. } => parameters, + Self::Branch { parameters, .. } => parameters, + }; + + parameters + .iter() + .zip(point_list) + .map(|(bound, value)| { + let distance = bound.calc_distance(*value); + distance * distance + }) + .sum() + } + } + + pub const OVERWORLD_BIOME_SOURCE: BiomeTree = #overworld_tree; + pub const NETHER_BIOME_SOURCE: BiomeTree = #nether_tree; + } } diff --git a/pumpkin-data/build/block.rs b/pumpkin-data/build/block.rs index bd461a11b..8fbbad725 100644 --- a/pumpkin-data/build/block.rs +++ b/pumpkin-data/build/block.rs @@ -1368,8 +1368,8 @@ pub(crate) fn build() -> TokenStream { ]; pub fn get_block(registry_id: &str) -> Option { - let key = registry_id.replace("minecraft:", ""); - Block::from_registry_key(key.as_str()) + let key = registry_id.strip_prefix("minecraft:").unwrap_or(registry_id); + Block::from_registry_key(key) } pub fn get_block_by_id(id: u16) -> Option { diff --git a/pumpkin-data/build/entity_type.rs b/pumpkin-data/build/entity_type.rs index c21e9e65b..9af264b06 100644 --- a/pumpkin-data/build/entity_type.rs +++ b/pumpkin-data/build/entity_type.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, fs}; use proc_macro2::TokenStream; +use pumpkin_util::HeightMap; use quote::{ToTokens, format_ident, quote}; use serde::Deserialize; use syn::LitInt; @@ -14,6 +15,22 @@ pub struct EntityType { pub fire_immune: bool, pub dimension: [f32; 2], pub eye_height: f32, + pub spawn_restriction: SpawnRestriction, +} + +#[derive(Deserialize)] +pub struct SpawnRestriction { + location: SpawnLocation, + heightmap: HeightMap, +} + +#[derive(Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum SpawnLocation { + InLava, + InWater, + OnGround, + Unrestricted, } pub struct NamedEntityType<'a>(&'a str, &'a EntityType); @@ -34,6 +51,27 @@ impl ToTokens for NamedEntityType<'_> { None => quote! { None }, }; + let spawn_restriction_location = match entity.spawn_restriction.location { + SpawnLocation::InLava => quote! {SpawnLocation::InLava}, + SpawnLocation::InWater => quote! {SpawnLocation::InWater}, + SpawnLocation::OnGround => quote! {SpawnLocation::OnGround}, + SpawnLocation::Unrestricted => quote! {SpawnLocation::Unrestricted}, + }; + + let spawn_restriction_heightmap = match entity.spawn_restriction.heightmap { + HeightMap::WorldSurfaceWg => quote! { HeightMap::WorldSurfaceWg }, + HeightMap::WorldSurface => quote! { HeightMap::WorldSurface }, + HeightMap::OceanFloorWg => quote! { HeightMap::OceanFloorWg }, + HeightMap::OceanFloor => quote! { HeightMap::OceanFloor }, + HeightMap::MotionBlocking => quote! { HeightMap::MotionBlocking }, + HeightMap::MotionBlockingNoLeaves => quote! { HeightMap::MotionBlockingNoLeaves }, + }; + + let spawn_restriction = quote! { SpawnRestriction { + location: #spawn_restriction_location, + heightmap: #spawn_restriction_heightmap, + }}; + let summonable = entity.summonable; let fire_immune = entity.fire_immune; let eye_height = entity.eye_height; @@ -50,6 +88,7 @@ impl ToTokens for NamedEntityType<'_> { fire_immune: #fire_immune, dimension: [#dimension0, #dimension1], // Correctly construct the array eye_height: #eye_height, + spawn_restriction: #spawn_restriction, resource_name: #name, } }); @@ -87,6 +126,8 @@ pub(crate) fn build() -> TokenStream { }); } quote! { + use pumpkin_util::HeightMap; + #[derive(Clone, Copy, Debug, PartialEq)] pub struct EntityType { pub id: u16, @@ -96,9 +137,24 @@ pub(crate) fn build() -> TokenStream { pub fire_immune: bool, pub dimension: [f32; 2], pub eye_height: f32, + pub spawn_restriction: SpawnRestriction, pub resource_name: &'static str, } + #[derive(Clone, Copy, Debug, PartialEq)] + pub struct SpawnRestriction { + location: SpawnLocation, + heightmap: HeightMap, + } + + #[derive(Clone, Copy, Debug, PartialEq)] + pub enum SpawnLocation { + InLava, + InWater, + OnGround, + Unrestricted + } + impl EntityType { #consts diff --git a/pumpkin-util/src/lib.rs b/pumpkin-util/src/lib.rs index e77af90f1..542334330 100644 --- a/pumpkin-util/src/lib.rs +++ b/pumpkin-util/src/lib.rs @@ -18,6 +18,17 @@ pub mod serde_enum_as_integer; pub mod text; pub mod translation; +#[derive(Deserialize, Clone, Copy, Debug, PartialEq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum HeightMap { + WorldSurfaceWg, + WorldSurface, + OceanFloorWg, + OceanFloor, + MotionBlocking, + MotionBlockingNoLeaves, +} + #[macro_export] macro_rules! global_path { ($path:expr) => {{ diff --git a/pumpkin-world/src/chunk/format/mod.rs b/pumpkin-world/src/chunk/format/mod.rs index 682fa4137..054c5e165 100644 --- a/pumpkin-world/src/chunk/format/mod.rs +++ b/pumpkin-world/src/chunk/format/mod.rs @@ -144,7 +144,9 @@ impl ChunkData { delay: tick.delay as u16, priority: TickPriority::from(tick.priority), target_block_id: Block::from_registry_key( - &tick.target_block.replace("minecraft:", ""), + tick.target_block + .strip_prefix("minecraft:") + .unwrap_or(&tick.target_block), ) .unwrap_or(Block::AIR) .id, @@ -158,7 +160,9 @@ impl ChunkData { delay: tick.delay as u16, priority: TickPriority::from(tick.priority), target_block_id: Block::from_registry_key( - &tick.target_block.replace("minecraft:", ""), + tick.target_block + .strip_prefix("minecraft:") + .unwrap_or(&tick.target_block), ) .unwrap_or(Block::AIR) .id, diff --git a/pumpkin-world/src/generation/block_predicate.rs b/pumpkin-world/src/generation/block_predicate.rs index 5f8933dd2..1d1812c1e 100644 --- a/pumpkin-world/src/generation/block_predicate.rs +++ b/pumpkin-world/src/generation/block_predicate.rs @@ -84,11 +84,11 @@ impl MatchingBlocksBlockPredicate { let block = self.offset.get_block(chunk, pos); match &self.blocks { MatchingBlocksWrapper::Single(single_block) => { - single_block.replace("minecraft:", "") == block.name + single_block.strip_prefix("minecraft:").unwrap() == block.name } MatchingBlocksWrapper::Multiple(blocks) => blocks .iter() - .map(|s| s.replace("minecraft:", "")) + .map(|s| s.strip_prefix("minecraft:").unwrap()) .contains(block.name), } } diff --git a/pumpkin-world/src/generation/feature/placed_features.rs b/pumpkin-world/src/generation/feature/placed_features.rs index de13b6f33..7635a1eb7 100644 --- a/pumpkin-world/src/generation/feature/placed_features.rs +++ b/pumpkin-world/src/generation/feature/placed_features.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use pumpkin_data::BlockDirection; +use pumpkin_util::HeightMap; use serde::Deserialize; use std::collections::HashMap; use std::iter; @@ -13,12 +14,12 @@ use pumpkin_util::math::vector2::Vector2; use pumpkin_util::math::vector3::Vector3; use pumpkin_util::random::{RandomGenerator, RandomImpl}; +use crate::ProtoChunk; use crate::generation::block_predicate::BlockPredicate; use crate::generation::height_limit::HeightLimitView; use crate::generation::height_provider::HeightProvider; use crate::level::Level; use crate::world::BlockRegistryExt; -use crate::{HeightMap, ProtoChunk}; use super::configured_features::{CONFIGURED_FEATURES, ConfiguredFeature}; diff --git a/pumpkin-world/src/generation/proto_chunk.rs b/pumpkin-world/src/generation/proto_chunk.rs index e79113dfb..e0de61c25 100644 --- a/pumpkin-world/src/generation/proto_chunk.rs +++ b/pumpkin-world/src/generation/proto_chunk.rs @@ -12,12 +12,12 @@ use pumpkin_data::{ }; use pumpkin_macros::default_block_state; use pumpkin_util::{ + HeightMap, math::{position::BlockPos, vector2::Vector2, vector3::Vector3}, random::{RandomGenerator, get_decorator_seed, xoroshiro128::Xoroshiro}, }; use crate::{ - HeightMap, biome::{BiomeSupplier, MultiNoiseBiomeSupplier, end::TheEndBiomeSupplier, hash_seed}, block::RawBlockState, chunk::CHUNK_AREA, @@ -547,6 +547,24 @@ impl<'a> ProtoChunk<'a> { } } + pub fn generate_entities(&self) { + let start_x = self.start_block_x(); + let start_z = self.start_block_z(); + + let population_seed = + Xoroshiro::get_population_seed(self.random_config.seed, start_x, start_z); + let _random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(population_seed)); + let _biome = self.get_biome(&Vector3::new( + start_x, + self.bottom_section_coord() as i32 + self.height() as i32 - 1, + start_z, + )); + // while random.next_f32() < biome.creature_spawn_probability { + + // } + todo!() + } + pub fn get_biome_for_terrain_gen(&self, global_block_pos: &Vector3) -> &'static Biome { let seed_biome_pos = biome::get_biome_blend( self.bottom_y(), diff --git a/pumpkin-world/src/generation/surface/mod.rs b/pumpkin-world/src/generation/surface/mod.rs index 58fef5b85..a09f742a4 100644 --- a/pumpkin-world/src/generation/surface/mod.rs +++ b/pumpkin-world/src/generation/surface/mod.rs @@ -327,7 +327,7 @@ impl NoiseThresholdMaterialCondition { pub fn test(&self, context: &mut MaterialRuleContext) -> bool { let sampler = context .noise_builder - .get_noise_sampler_for_id(&self.noise.replace("minecraft:", "")); + .get_noise_sampler_for_id(self.noise.strip_prefix("minecraft:").unwrap()); let value = sampler.sample(context.block_pos.x as f64, 0.0, context.block_pos.z as f64); value >= self.min_threshold && value <= self.max_threshold } diff --git a/pumpkin-world/src/lib.rs b/pumpkin-world/src/lib.rs index 493ac91fa..211898ff2 100644 --- a/pumpkin-world/src/lib.rs +++ b/pumpkin-world/src/lib.rs @@ -20,17 +20,6 @@ pub mod world_info; pub type BlockId = u16; pub type BlockStateId = u16; -#[derive(Deserialize, Clone)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum HeightMap { - WorldSurfaceWg, - WorldSurface, - OceanFloorWg, - OceanFloor, - MotionBlocking, - MotionBlockingNoLeaves, -} - #[macro_export] macro_rules! global_path { ($path:expr) => {{ @@ -60,8 +49,6 @@ pub use generation::{ GlobalRandomConfig, noise_router::proto_noise_router::ProtoNoiseRouters, proto_chunk::ProtoChunk, settings::GENERATION_SETTINGS, settings::GeneratorSetting, }; -use serde::Deserialize; - pub fn bench_create_and_populate_noise( base_router: &ProtoNoiseRouters, random_config: &GlobalRandomConfig, diff --git a/pumpkin/src/block/loot.rs b/pumpkin/src/block/loot.rs index 38d735d3a..7b5426e34 100644 --- a/pumpkin/src/block/loot.rs +++ b/pumpkin/src/block/loot.rs @@ -114,7 +114,7 @@ impl LootPoolEntryTypesExt for LootPoolEntryTypes { match self { Self::Empty => Vec::new(), Self::Item(item_entry) => { - let key = &item_entry.name.replace("minecraft:", ""); + let key = &item_entry.name.strip_prefix("minecraft:").unwrap(); vec![ItemStack::new(1, Item::from_registry_key(key).unwrap())] } Self::LootTable => todo!(), diff --git a/pumpkin/src/command/args/resource/effect.rs b/pumpkin/src/command/args/resource/effect.rs index 6209e8537..cf2002c3b 100644 --- a/pumpkin/src/command/args/resource/effect.rs +++ b/pumpkin/src/command/args/resource/effect.rs @@ -38,7 +38,7 @@ impl ArgumentConsumer for EffectTypeArgumentConsumer { let name = args.pop()?; // Create a static damage type first - let damage_type = EffectType::from_name(&name.replace("minecraft:", ""))?; + let damage_type = EffectType::from_name(name.strip_prefix("minecraft:").unwrap_or(name))?; // Find matching static damage type from values array Some(Arg::Effect(damage_type)) } diff --git a/pumpkin/src/command/args/resource/item.rs b/pumpkin/src/command/args/resource/item.rs index aa9d00995..fdad1edde 100644 --- a/pumpkin/src/command/args/resource/item.rs +++ b/pumpkin/src/command/args/resource/item.rs @@ -58,15 +58,17 @@ impl<'a> FindArg<'a> for ItemArgumentConsumer { fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result { match args.get(name) { - Some(Arg::Item(name)) => Item::from_registry_key(&name.replace("minecraft:", "")) - .map_or_else( - || { - Err(CommandError::GeneralCommandIssue(format!( - "Item {name} does not exist." - ))) - }, - |item| Ok((*name, item)), - ), + Some(Arg::Item(name)) => { + Item::from_registry_key(name.strip_prefix("minecraft:").unwrap_or(name)) + .map_or_else( + || { + Err(CommandError::GeneralCommandIssue(format!( + "Item {name} does not exist." + ))) + }, + |item| Ok((*name, item)), + ) + } _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), } } diff --git a/pumpkin/src/command/args/resource/particle.rs b/pumpkin/src/command/args/resource/particle.rs index fce508226..edf1cff42 100644 --- a/pumpkin/src/command/args/resource/particle.rs +++ b/pumpkin/src/command/args/resource/particle.rs @@ -38,7 +38,7 @@ impl ArgumentConsumer for ParticleArgumentConsumer { let name = args.pop()?; // Create a static damage type first - let particle = Particle::from_name(&name.replace("minecraft:", ""))?; + let particle = Particle::from_name(name.strip_prefix("minecraft:").unwrap_or(name))?; // Find matching static damage type from values array Some(Arg::Particle(particle)) } diff --git a/pumpkin/src/command/args/sound.rs b/pumpkin/src/command/args/sound.rs index da95efa9f..494e8feab 100644 --- a/pumpkin/src/command/args/sound.rs +++ b/pumpkin/src/command/args/sound.rs @@ -57,15 +57,16 @@ impl<'a> FindArg<'a> for SoundArgumentConsumer { fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { - Some(Arg::Block(name)) => Sound::from_name(&name.replace("minecraft:", "")) - .map_or_else( + Some(Arg::Block(name)) => { + Sound::from_name(name.strip_prefix("minecraft:").unwrap_or(name)).map_or_else( || { Err(CommandError::GeneralCommandIssue(format!( "Sound {name} does not exist." ))) }, Result::Ok, - ), + ) + } _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), } } diff --git a/pumpkin/src/command/args/summonable_entities.rs b/pumpkin/src/command/args/summonable_entities.rs index caca0744e..57b9cbae0 100644 --- a/pumpkin/src/command/args/summonable_entities.rs +++ b/pumpkin/src/command/args/summonable_entities.rs @@ -57,15 +57,16 @@ impl<'a> FindArg<'a> for SummonableEntitiesArgumentConsumer { fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { - Some(Arg::Block(name)) => EntityType::from_name(&name.replace("minecraft:", "")) - .map_or_else( + Some(Arg::Block(name)) => { + EntityType::from_name(name.strip_prefix("minecraft:").unwrap_or(name)).map_or_else( || { Err(CommandError::GeneralCommandIssue(format!( "Entity {name} does not exist." ))) }, Result::Ok, - ), + ) + } _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), } }