Code/net/minecraft/util/SpawnUtil.java

108 lines
5.1 KiB
Java

package net.minecraft.util;
import java.util.Optional;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.StainedGlassBlock;
import net.minecraft.world.level.block.StainedGlassPaneBlock;
import net.minecraft.world.level.block.state.BlockState;
public class SpawnUtil {
public static <T extends Mob> Optional<T> trySpawnMob(
EntityType<T> p_216404_,
EntitySpawnReason p_369127_,
ServerLevel p_216406_,
BlockPos p_216407_,
int p_216408_,
int p_216409_,
int p_216410_,
SpawnUtil.Strategy p_216411_,
boolean p_378332_
) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_216407_.mutable();
for (int i = 0; i < p_216408_; i++) {
int j = Mth.randomBetweenInclusive(p_216406_.random, -p_216409_, p_216409_);
int k = Mth.randomBetweenInclusive(p_216406_.random, -p_216409_, p_216409_);
blockpos$mutableblockpos.setWithOffset(p_216407_, j, p_216410_, k);
if (p_216406_.getWorldBorder().isWithinBounds(blockpos$mutableblockpos)
&& moveToPossibleSpawnPosition(p_216406_, p_216410_, blockpos$mutableblockpos, p_216411_)
&& (
!p_378332_
|| p_216406_.noCollision(
p_216404_.getSpawnAABB(
blockpos$mutableblockpos.getX() + 0.5, blockpos$mutableblockpos.getY(), blockpos$mutableblockpos.getZ() + 0.5
)
)
)) {
T t = (T)p_216404_.create(p_216406_, null, blockpos$mutableblockpos, p_369127_, false, false);
if (t != null) {
if (t.checkSpawnRules(p_216406_, p_369127_) && t.checkSpawnObstruction(p_216406_)) {
p_216406_.addFreshEntityWithPassengers(t);
t.playAmbientSound();
return Optional.of(t);
}
t.discard();
}
}
}
return Optional.empty();
}
private static boolean moveToPossibleSpawnPosition(ServerLevel p_216399_, int p_216400_, BlockPos.MutableBlockPos p_216401_, SpawnUtil.Strategy p_216402_) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos().set(p_216401_);
BlockState blockstate = p_216399_.getBlockState(blockpos$mutableblockpos);
for (int i = p_216400_; i >= -p_216400_; i--) {
p_216401_.move(Direction.DOWN);
blockpos$mutableblockpos.setWithOffset(p_216401_, Direction.UP);
BlockState blockstate1 = p_216399_.getBlockState(p_216401_);
if (p_216402_.canSpawnOn(p_216399_, p_216401_, blockstate1, blockpos$mutableblockpos, blockstate)) {
p_216401_.move(Direction.UP);
return true;
}
blockstate = blockstate1;
}
return false;
}
public interface Strategy {
@Deprecated
SpawnUtil.Strategy LEGACY_IRON_GOLEM = (p_289751_, p_289752_, p_289753_, p_289754_, p_289755_) -> !p_289753_.is(Blocks.COBWEB)
&& !p_289753_.is(Blocks.CACTUS)
&& !p_289753_.is(Blocks.GLASS_PANE)
&& !(p_289753_.getBlock() instanceof StainedGlassPaneBlock)
&& !(p_289753_.getBlock() instanceof StainedGlassBlock)
&& !(p_289753_.getBlock() instanceof LeavesBlock)
&& !p_289753_.is(Blocks.CONDUIT)
&& !p_289753_.is(Blocks.ICE)
&& !p_289753_.is(Blocks.TNT)
&& !p_289753_.is(Blocks.GLOWSTONE)
&& !p_289753_.is(Blocks.BEACON)
&& !p_289753_.is(Blocks.SEA_LANTERN)
&& !p_289753_.is(Blocks.FROSTED_ICE)
&& !p_289753_.is(Blocks.TINTED_GLASS)
&& !p_289753_.is(Blocks.GLASS)
? (p_289755_.isAir() || p_289755_.liquid()) && (p_289753_.isSolid() || p_289753_.is(Blocks.POWDER_SNOW))
: false;
SpawnUtil.Strategy ON_TOP_OF_COLLIDER = (p_358812_, p_358813_, p_358814_, p_358815_, p_358816_) -> p_358816_.getCollisionShape(p_358812_, p_358815_).isEmpty()
&& Block.isFaceFull(p_358814_.getCollisionShape(p_358812_, p_358813_), Direction.UP);
SpawnUtil.Strategy ON_TOP_OF_COLLIDER_NO_LEAVES = (p_358807_, p_358808_, p_358809_, p_358810_, p_358811_) -> p_358811_.getCollisionShape(p_358807_, p_358810_).isEmpty()
&& !p_358809_.is(BlockTags.LEAVES)
&& Block.isFaceFull(p_358809_.getCollisionShape(p_358807_, p_358808_), Direction.UP);
boolean canSpawnOn(ServerLevel p_216428_, BlockPos p_216429_, BlockState p_216430_, BlockPos p_216431_, BlockState p_216432_);
}
}