112 lines
4.1 KiB
Java
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;
|
|
}
|
|
}
|
|
}
|
|
}
|