SpawnUtil.java
net.minecraft.util.SpawnUtil
信息
- 全限定名:net.minecraft.util.SpawnUtil
- 类型:public class
- 包:net.minecraft.util
- 源码路径:src/main/java/net/minecraft/util/SpawnUtil.java
- 起始行号:L18
- 职责:
TODO
字段/常量
- 无
内部类/嵌套类型
net.minecraft.util.SpawnUtil.Strategy- 类型:
interface - 修饰符:
public - 源码定位:
L75 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entityType, EntitySpawnReason spawnReason, ServerLevel level, BlockPos start, int spawnAttempts, int spawnRangeXZ, int spawnRangeY, SpawnUtil.Strategy strategy, boolean checkCollisions) @ L19
- 方法名:trySpawnMob
- 源码定位:L19
- 返回类型:
Optional - 修饰符:public static
参数:
- entityType: EntityType
- spawnReason: EntitySpawnReason
- level: ServerLevel
- start: BlockPos
- spawnAttempts: int
- spawnRangeXZ: int
- spawnRangeY: int
- strategy: SpawnUtil.Strategy
- checkCollisions: boolean
说明:
TODO
private static boolean moveToPossibleSpawnPosition(ServerLevel level, int spawnRangeY, BlockPos.MutableBlockPos searchPos, SpawnUtil.Strategy strategy) @ L56
- 方法名:moveToPossibleSpawnPosition
- 源码定位:L56
- 返回类型:boolean
- 修饰符:private static
参数:
- level: ServerLevel
- spawnRangeY: int
- searchPos: BlockPos.MutableBlockPos
- strategy: SpawnUtil.Strategy
说明:
TODO
代码
public class SpawnUtil {
public static <T extends Mob> Optional<T> trySpawnMob(
EntityType<T> entityType,
EntitySpawnReason spawnReason,
ServerLevel level,
BlockPos start,
int spawnAttempts,
int spawnRangeXZ,
int spawnRangeY,
SpawnUtil.Strategy strategy,
boolean checkCollisions
) {
BlockPos.MutableBlockPos searchPos = start.mutable();
RandomSource random = level.getRandom();
for (int i = 0; i < spawnAttempts; i++) {
int dx = Mth.randomBetweenInclusive(random, -spawnRangeXZ, spawnRangeXZ);
int dz = Mth.randomBetweenInclusive(random, -spawnRangeXZ, spawnRangeXZ);
searchPos.setWithOffset(start, dx, spawnRangeY, dz);
if (level.getWorldBorder().isWithinBounds(searchPos)
&& moveToPossibleSpawnPosition(level, spawnRangeY, searchPos, strategy)
&& (!checkCollisions || level.noCollision(entityType.getSpawnAABB(searchPos.getX() + 0.5, searchPos.getY(), searchPos.getZ() + 0.5)))) {
T mob = (T)entityType.create(level, null, searchPos, spawnReason, false, false);
if (mob != null) {
if (mob.checkSpawnRules(level, spawnReason) && mob.checkSpawnObstruction(level)) {
level.addFreshEntityWithPassengers(mob);
mob.playAmbientSound();
return Optional.of(mob);
}
mob.discard();
}
}
}
return Optional.empty();
}
private static boolean moveToPossibleSpawnPosition(ServerLevel level, int spawnRangeY, BlockPos.MutableBlockPos searchPos, SpawnUtil.Strategy strategy) {
BlockPos.MutableBlockPos abovePos = new BlockPos.MutableBlockPos().set(searchPos);
BlockState aboveState = level.getBlockState(abovePos);
for (int y = spawnRangeY; y >= -spawnRangeY; y--) {
searchPos.move(Direction.DOWN);
abovePos.setWithOffset(searchPos, Direction.UP);
BlockState currentState = level.getBlockState(searchPos);
if (strategy.canSpawnOn(level, searchPos, currentState, abovePos, aboveState)) {
searchPos.move(Direction.UP);
return true;
}
aboveState = currentState;
}
return false;
}
public interface Strategy {
@Deprecated
SpawnUtil.Strategy LEGACY_IRON_GOLEM = (level, pos, blockState, abovePos, aboveState) -> !blockState.is(Blocks.COBWEB)
&& !blockState.is(Blocks.CACTUS)
&& !blockState.is(Blocks.GLASS_PANE)
&& !(blockState.getBlock() instanceof StainedGlassPaneBlock)
&& !(blockState.getBlock() instanceof StainedGlassBlock)
&& !(blockState.getBlock() instanceof LeavesBlock)
&& !blockState.is(Blocks.CONDUIT)
&& !blockState.is(Blocks.ICE)
&& !blockState.is(Blocks.TNT)
&& !blockState.is(Blocks.GLOWSTONE)
&& !blockState.is(Blocks.BEACON)
&& !blockState.is(Blocks.SEA_LANTERN)
&& !blockState.is(Blocks.FROSTED_ICE)
&& !blockState.is(Blocks.TINTED_GLASS)
&& !blockState.is(Blocks.GLASS)
? (aboveState.isAir() || aboveState.liquid()) && (blockState.isSolid() || blockState.is(Blocks.POWDER_SNOW))
: false;
SpawnUtil.Strategy ON_TOP_OF_COLLIDER = (level, pos, blockState, abovePos, aboveState) -> aboveState.getCollisionShape(level, abovePos).isEmpty()
&& Block.isFaceFull(blockState.getCollisionShape(level, pos), Direction.UP);
SpawnUtil.Strategy ON_TOP_OF_COLLIDER_NO_LEAVES = (level, pos, blockState, abovePos, aboveState) -> aboveState.getCollisionShape(level, abovePos)
.isEmpty()
&& !blockState.is(BlockTags.LEAVES)
&& Block.isFaceFull(blockState.getCollisionShape(level, pos), Direction.UP);
boolean canSpawnOn(ServerLevel level, BlockPos pos, BlockState blockState, BlockPos abovePos, BlockState aboveState);
}
}引用的其他类
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
BlockPos.MutableBlockPos(), MutableBlockPos()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.randomBetweenInclusive()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Block.isFaceFull()
- 引用位置: