package net.minecraft.world.level.levelgen;

import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.entity.monster.Pillager;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.entity.monster.PatrollingMonster;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.entity.player.Player;
import java.util.Random;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.level.ServerLevel;

public class PatrolSpawner {
    private int nextTick;
    
    public int tick(final ServerLevel xd, final boolean boolean2, final boolean boolean3) {
        if (!boolean2) {
            return 0;
        }
        if (!xd.getGameRules().getBoolean(GameRules.RULE_DO_PATROL_SPAWNING)) {
            return 0;
        }
        final Random random5 = xd.random;
        --this.nextTick;
        if (this.nextTick > 0) {
            return 0;
        }
        this.nextTick += 12000 + random5.nextInt(1200);
        final long long6 = xd.getDayTime() / 24000L;
        if (long6 < 5L || !xd.isDay()) {
            return 0;
        }
        if (random5.nextInt(5) != 0) {
            return 0;
        }
        final int integer8 = xd.players().size();
        if (integer8 < 1) {
            return 0;
        }
        final Player ayj9 = xd.players().get(random5.nextInt(integer8));
        if (ayj9.isSpectator()) {
            return 0;
        }
        if (xd.isVillage(ayj9.getCommandSenderBlockPosition())) {
            return 0;
        }
        final int integer9 = (24 + random5.nextInt(24)) * (random5.nextBoolean() ? -1 : 1);
        final int integer10 = (24 + random5.nextInt(24)) * (random5.nextBoolean() ? -1 : 1);
        final BlockPos.MutableBlockPos a12 = new BlockPos.MutableBlockPos(ayj9).move(integer9, 0, integer10);
        if (!xd.hasChunksAt(a12.getX() - 10, a12.getY() - 10, a12.getZ() - 10, a12.getX() + 10, a12.getY() + 10, a12.getZ() + 10)) {
            return 0;
        }
        final Biome bkt13 = xd.getBiome(a12);
        final Biome.BiomeCategory b14 = bkt13.getBiomeCategory();
        if (b14 == Biome.BiomeCategory.MUSHROOM) {
            return 0;
        }
        int integer11 = 0;
        for (int integer12 = (int)Math.ceil(xd.getCurrentDifficultyAt(a12).getEffectiveDifficulty()) + 1, integer13 = 0; integer13 < integer12; ++integer13) {
            ++integer11;
            a12.setY(xd.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, a12).getY());
            if (integer13 == 0) {
                if (!this.spawnPatrolMember(xd, a12, random5, true)) {
                    break;
                }
            }
            else {
                this.spawnPatrolMember(xd, a12, random5, false);
            }
            a12.setX(a12.getX() + random5.nextInt(5) - random5.nextInt(5));
            a12.setZ(a12.getZ() + random5.nextInt(5) - random5.nextInt(5));
        }
        return integer11;
    }
    
    private boolean spawnPatrolMember(final Level bjw, final BlockPos fk, final Random random, final boolean boolean4) {
        final BlockState byj6 = bjw.getBlockState(fk);
        if (!NaturalSpawner.isValidEmptySpawnBlock(bjw, fk, byj6, byj6.getFluidState())) {
            return false;
        }
        if (!PatrollingMonster.checkPatrollingMonsterSpawnRules(EntityType.PILLAGER, bjw, MobSpawnType.PATROL, fk, random)) {
            return false;
        }
        final PatrollingMonster awx7 = EntityType.PILLAGER.create(bjw);
        if (awx7 != null) {
            if (boolean4) {
                awx7.setPatrolLeader(true);
                awx7.findPatrolTarget();
            }
            awx7.setPos(fk.getX(), fk.getY(), fk.getZ());
            awx7.finalizeSpawn(bjw, bjw.getCurrentDifficultyAt(fk), MobSpawnType.PATROL, null, null);
            bjw.addFreshEntity(awx7);
            return true;
        }
        return false;
    }
}
