diff --git a/docs/entities/livingentity.md b/docs/entities/livingentity.md index d94b22bb2..7ad6383bc 100644 --- a/docs/entities/livingentity.md +++ b/docs/entities/livingentity.md @@ -221,6 +221,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._ diff --git a/versioned_docs/version-1.21.10/entities/livingentity.md b/versioned_docs/version-1.21.10/entities/livingentity.md index b741d7d3a..bd5b11b37 100644 --- a/versioned_docs/version-1.21.10/entities/livingentity.md +++ b/versioned_docs/version-1.21.10/entities/livingentity.md @@ -221,6 +221,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._ diff --git a/versioned_docs/version-1.21.11/entities/livingentity.md b/versioned_docs/version-1.21.11/entities/livingentity.md index d94b22bb2..7ad6383bc 100644 --- a/versioned_docs/version-1.21.11/entities/livingentity.md +++ b/versioned_docs/version-1.21.11/entities/livingentity.md @@ -221,6 +221,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._ diff --git a/versioned_docs/version-1.21.4/entities/livingentity.md b/versioned_docs/version-1.21.4/entities/livingentity.md index b1411088a..f5e587db5 100644 --- a/versioned_docs/version-1.21.4/entities/livingentity.md +++ b/versioned_docs/version-1.21.4/entities/livingentity.md @@ -216,6 +216,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._ diff --git a/versioned_docs/version-1.21.5/entities/livingentity.md b/versioned_docs/version-1.21.5/entities/livingentity.md index b1411088a..f5e587db5 100644 --- a/versioned_docs/version-1.21.5/entities/livingentity.md +++ b/versioned_docs/version-1.21.5/entities/livingentity.md @@ -216,6 +216,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._ diff --git a/versioned_docs/version-1.21.8/entities/livingentity.md b/versioned_docs/version-1.21.8/entities/livingentity.md index 49784cffe..fc6c62395 100644 --- a/versioned_docs/version-1.21.8/entities/livingentity.md +++ b/versioned_docs/version-1.21.8/entities/livingentity.md @@ -215,6 +215,73 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.registerItem("my_entity_s As an item like any other, the item should be added to a [creative tab][creative], and a [client item][clientitem], [model] and [translation] should be added. +### Spawn Placements + +By default, spawning will be possible anywhere, including inside blocks and in midair. To prevent this, a spawn placement must be registered. This happens in the `RegisterSpawnPlacementsEvent` like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // SpawnPlacementType is a functional interface that checks whether a given position is valid + // for spawning. You can add your own SpawnPlacementType if needed, + // see the implementation of SpawnPlacementTypes for reference. + // Vanilla values include NO_RESTRICTIONS, IN_WATER, IN_LAVA and ON_GROUND. + SpawnPlacementTypes.ON_GROUND, + // The heightmap type to use. This provides the initial height to check during world generation, + // later this is ignored and just uses the world surface. Possible values are + // WORLD_SURFACE, OCEAN_FLOOR, MOTION_BLOCKING and MOTION_BLOCKING_NO_LEAVES. + Heightmap.Types.WORLD_SURFACE, + // A predicate to check additional spawn rules, e.g. light. Can either be specified here + // as a lambda, or (more commonly) as a static method in the entity class. + (entityType, level, spawnReason, pos, random) -> { + // Make our mob only spawn on grass blocks. + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // For our own mobs, any operation may be used. + RegisterSpawnPlacementsEvent.Operation.OR + ); +} +``` + +It is also possible to modify vanilla's or other mods' spawn placements. You can use one of `Operation.AND` (for extra spawn restrictions), `Operation.OR` (for alternate spawn mechanisms) or `Operation.REPLACE` (to completely replace the spawn placement, use a [low-priority event listener][priority] in this case) like so: + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register( + // The EntityType to register the spawn placement for. + MY_ENTITY.get(), + // When not using Operation.REPLACE, leave the spawn placement type + // and the heightmap type at null. + null, + null, + // Like above, check the additional/alternate spawn rules. + (entityType, level, spawnReason, pos, random) -> { + return level.getBlockState(pos.below()).is(Blocks.GRASS_BLOCK) + || Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random); + }, + // Use the appropriate Operation here. + RegisterSpawnPlacementsEvent.Operation.AND + ); +} +``` + +The event also provides two utility overloads (where `spawnPredicate` is the lambda we used earlier): + +```java +@SubscribeEvent // on the mod event bus +public static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, Operation.OR) + event.register(MY_ENTITY.get(), spawnPredicate); + // Identical to event.register(MY_ENTITY.get(), null, null, spawnPredicate, operation) + event.register(MY_ENTITY.get(), spawnPredicate, operation); +} +``` + ### Natural Spawning _See also [Entities/`MobCategory`][mobcategory], [Worldgen/Biome Modifers/Add Spawns][addspawns], [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]; and [Spawn Cycle][spawncycle] on the [Minecraft Wiki][mcwiki]._