minecraft-src/net/minecraft/world/level/levelgen/PatrolSpawner.java
2025-07-04 02:00:41 +03:00

112 lines
4.1 KiB
Java

package net.minecraft.world.level.levelgen;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BiomeTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.PatrollingMonster;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.CustomSpawner;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.state.BlockState;
public class PatrolSpawner implements CustomSpawner {
private int nextTick;
@Override
public int tick(ServerLevel level, boolean spawnEnemies, boolean spawnFriendlies) {
if (!spawnEnemies) {
return 0;
} else if (!level.getGameRules().getBoolean(GameRules.RULE_DO_PATROL_SPAWNING)) {
return 0;
} else {
RandomSource randomSource = level.random;
this.nextTick--;
if (this.nextTick > 0) {
return 0;
} else {
this.nextTick = this.nextTick + 12000 + randomSource.nextInt(1200);
long l = level.getDayTime() / 24000L;
if (l < 5L || !level.isDay()) {
return 0;
} else if (randomSource.nextInt(5) != 0) {
return 0;
} else {
int i = level.players().size();
if (i < 1) {
return 0;
} else {
Player player = (Player)level.players().get(randomSource.nextInt(i));
if (player.isSpectator()) {
return 0;
} else if (level.isCloseToVillage(player.blockPosition(), 2)) {
return 0;
} else {
int j = (24 + randomSource.nextInt(24)) * (randomSource.nextBoolean() ? -1 : 1);
int k = (24 + randomSource.nextInt(24)) * (randomSource.nextBoolean() ? -1 : 1);
BlockPos.MutableBlockPos mutableBlockPos = player.blockPosition().mutable().move(j, 0, k);
int m = 10;
if (!level.hasChunksAt(mutableBlockPos.getX() - 10, mutableBlockPos.getZ() - 10, mutableBlockPos.getX() + 10, mutableBlockPos.getZ() + 10)) {
return 0;
} else {
Holder<Biome> holder = level.getBiome(mutableBlockPos);
if (holder.is(BiomeTags.WITHOUT_PATROL_SPAWNS)) {
return 0;
} else {
int n = 0;
int o = (int)Math.ceil(level.getCurrentDifficultyAt(mutableBlockPos).getEffectiveDifficulty()) + 1;
for (int p = 0; p < o; p++) {
n++;
mutableBlockPos.setY(level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, mutableBlockPos).getY());
if (p == 0) {
if (!this.spawnPatrolMember(level, mutableBlockPos, randomSource, true)) {
break;
}
} else {
this.spawnPatrolMember(level, mutableBlockPos, randomSource, false);
}
mutableBlockPos.setX(mutableBlockPos.getX() + randomSource.nextInt(5) - randomSource.nextInt(5));
mutableBlockPos.setZ(mutableBlockPos.getZ() + randomSource.nextInt(5) - randomSource.nextInt(5));
}
return n;
}
}
}
}
}
}
}
}
private boolean spawnPatrolMember(ServerLevel level, BlockPos pos, RandomSource random, boolean leader) {
BlockState blockState = level.getBlockState(pos);
if (!NaturalSpawner.isValidEmptySpawnBlock(level, pos, blockState, blockState.getFluidState(), EntityType.PILLAGER)) {
return false;
} else if (!PatrollingMonster.checkPatrollingMonsterSpawnRules(EntityType.PILLAGER, level, EntitySpawnReason.PATROL, pos, random)) {
return false;
} else {
PatrollingMonster patrollingMonster = EntityType.PILLAGER.create(level, EntitySpawnReason.PATROL);
if (patrollingMonster != null) {
if (leader) {
patrollingMonster.setPatrolLeader(true);
patrollingMonster.findPatrolTarget();
}
patrollingMonster.setPos(pos.getX(), pos.getY(), pos.getZ());
patrollingMonster.finalizeSpawn(level, level.getCurrentDifficultyAt(pos), EntitySpawnReason.PATROL, null);
level.addFreshEntityWithPassengers(patrollingMonster);
return true;
} else {
return false;
}
}
}
}