package net.minecraft.world.level.levelgen;

import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.entity.Entity;
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.level.BlockGetter;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.entity.EntityType;
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.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.CustomSpawner;

public class PatrolSpawner implements CustomSpawner {
    private int nextTick;
    
    @Override
    public int tick(final ServerLevel zd, final boolean boolean2, final boolean boolean3) {
        if (!boolean2) {
            return 0;
        }
        if (!zd.getGameRules().getBoolean(GameRules.RULE_DO_PATROL_SPAWNING)) {
            return 0;
        }
        final Random random5 = zd.random;
        --this.nextTick;
        if (this.nextTick > 0) {
            return 0;
        }
        this.nextTick += 12000 + random5.nextInt(1200);
        final long long6 = zd.getDayTime() / 24000L;
        if (long6 < 5L || !zd.isDay()) {
            return 0;
        }
        if (random5.nextInt(5) != 0) {
            return 0;
        }
        final int integer8 = zd.players().size();
        if (integer8 < 1) {
            return 0;
        }
        final Player bec9 = zd.players().get(random5.nextInt(integer8));
        if (bec9.isSpectator()) {
            return 0;
        }
        if (zd.isCloseToVillage(bec9.blockPosition(), 2)) {
            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 = bec9.blockPosition().mutable().move(integer9, 0, integer10);
        if (!zd.hasChunksAt(a12.getX() - 10, a12.getY() - 10, a12.getZ() - 10, a12.getX() + 10, a12.getY() + 10, a12.getZ() + 10)) {
            return 0;
        }
        final Biome bre13 = zd.getBiome(a12);
        final Biome.BiomeCategory b14 = bre13.getBiomeCategory();
        if (b14 == Biome.BiomeCategory.MUSHROOM) {
            return 0;
        }
        int integer11 = 0;
        for (int integer12 = (int)Math.ceil(zd.getCurrentDifficultyAt(a12).getEffectiveDifficulty()) + 1, integer13 = 0; integer13 < integer12; ++integer13) {
            ++integer11;
            a12.setY(zd.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, a12).getY());
            if (integer13 == 0) {
                if (!this.spawnPatrolMember(zd, a12, random5, true)) {
                    break;
                }
            }
            else {
                this.spawnPatrolMember(zd, 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 bqb, final BlockPos fu, final Random random, final boolean boolean4) {
        final BlockState cfj6 = bqb.getBlockState(fu);
        if (!NaturalSpawner.isValidEmptySpawnBlock(bqb, fu, cfj6, cfj6.getFluidState(), EntityType.PILLAGER)) {
            return false;
        }
        if (!PatrollingMonster.checkPatrollingMonsterSpawnRules(EntityType.PILLAGER, bqb, MobSpawnType.PATROL, fu, random)) {
            return false;
        }
        final PatrollingMonster bcc7 = EntityType.PILLAGER.create(bqb);
        if (bcc7 != null) {
            if (boolean4) {
                bcc7.setPatrolLeader(true);
                bcc7.findPatrolTarget();
            }
            bcc7.setPos(fu.getX(), fu.getY(), fu.getZ());
            bcc7.finalizeSpawn(bqb, bqb.getCurrentDifficultyAt(fu), MobSpawnType.PATROL, null, null);
            bqb.addFreshEntity(bcc7);
            return true;
        }
        return false;
    }
}
