import { GameRule, MinecraftDimensionTypes, MolangVariableMap, system, world } from "@minecraft/server";
import { ActionFormData, ModalFormData } from "@minecraft/server-ui";
import { getBoolean, getClosestPlayer, getHorizontalDistance, getRandomInt, getScoreboard } from "nps_tbe/others/my_API";
import { TBEPDP } from "./customPlayer";
import config from "nps_tbe/config";
class EndParticleFunctionManager {
    static initialize() {
        for (const { interval, identifier, isParticle, propertyKey } of this.functions) {
            system.runInterval(() => {
                const dim = world.getDimension(this.dimensionId);
                const players = dim.getPlayers();
                for (const player of players) {
                    if (this.isEnabled(player, propertyKey)) {
                        if (isParticle) {
                            try {
                                dim.spawnParticle(identifier, {
                                    x: player.location.x,
                                    y: 0,
                                    z: player.location.z
                                });
                            }
                            catch { }
                        }
                        else {
                            const x = player.location.x.toFixed(1);
                            const z = player.location.z.toFixed(1);
                            player.runCommand(`/execute positioned ${x} 0 ${z} run function nps/tbe/${identifier}`);
                        }
                    }
                }
            }, interval);
        }
        system.runInterval(() => {
            const end = world.getDimension(MinecraftDimensionTypes.theEnd);
            end.runCommandAsync('/execute as @e[type=minecraft:ender_crystal] at @s run particle nps_tbe:epp');
        }, 5);
        const max_lifetime = 5.0;
        system.runInterval(() => {
            const end = world.getDimension(MinecraftDimensionTypes.theEnd);
            end.runCommand('/tickingarea add circle 0 0 0 1 nps_tbe:end_center');
            const molangVariable = new MolangVariableMap();
            molangVariable.setFloat('max_lifetime', max_lifetime);
            molangVariable.setFloat('current_tick', system.currentTick);
            try {
                end.spawnParticle('nps_tbe:black_hole', { x: 0, y: 0, z: 0 }, molangVariable);
            }
            catch { }
        }, max_lifetime * 20);
    }
    static isEnabled(player, propertyKey) {
        const value = player.getDynamicProperty(propertyKey);
        return value === undefined || value === true;
    }
}
EndParticleFunctionManager.dimensionId = MinecraftDimensionTypes.theEnd;
EndParticleFunctionManager.functions = [
    {
        propertyKey: TBEPDP.GFX_BB_RANDOM,
        interval: 20 * 60,
        isParticle: false,
        identifier: "bb_random"
    },
    {
        propertyKey: TBEPDP.GFX_E_C,
        interval: 20 * 5,
        isParticle: false,
        identifier: "e_c"
    },
    {
        propertyKey: TBEPDP.GFX_StarrySky,
        interval: 20 * 10,
        isParticle: true,
        identifier: "nps_tbe:starry_sky"
    }
];
class GFXButtons {
}
GFXButtons.biomeCategories = [
    { label: "Amanita Mire", icon: "ui/icon_amanita", fog: TBEPDP.Fog_Amanita, sound: TBEPDP.AmbientSoundVolume_Amanita, particle: TBEPDP.Particles_Amanita },
    { label: "Chlorophos Expanse", icon: "ui/icon_chlorophos", fog: TBEPDP.Fog_Chlorophos, sound: TBEPDP.AmbientSoundVolume_Chlorophos, particle: TBEPDP.Particles_Chlorophos },
    { label: "Cortinarius Grove", icon: "ui/icon_cortinarius", fog: TBEPDP.Fog_Cortinarius, sound: TBEPDP.AmbientSoundVolume_Cortinarius, particle: TBEPDP.Particles_Cortinarius },
    { label: "Lactarius Jungle", icon: "ui/icon_lactarius", fog: TBEPDP.Fog_Lactarius, sound: TBEPDP.AmbientSoundVolume_Lactarius, particle: TBEPDP.Particles_Lactarius },
    { label: "Russula Barrens", icon: "ui/icon_russula", fog: TBEPDP.Fog_Russula, sound: TBEPDP.AmbientSoundVolume_Russula, particle: TBEPDP.Particles_Russula },
    { label: "Umbromycelia Wastes", icon: "ui/icon_umbromycelia", fog: TBEPDP.Fog_Umbromycelia, sound: TBEPDP.AmbientSoundVolume_Umbromycelia, particle: TBEPDP.Particles_Umbromycelia },
    { label: "Vanilla", icon: "ui/icon_end", fog: TBEPDP.Fog_Vanilla, sound: TBEPDP.AmbientSoundVolume_Vanilla, particle: TBEPDP.Particles_Vanilla }
];
GFXButtons.misc = { label: "Miscellaneous", icon: "ui/icon_gear" };
class GFX {
    static initialize(event) {
        event.itemComponentRegistry.registerCustomComponent(this.componentName, new this());
    }
    onUse(event) {
        const player = event.source;
        GFX.openCategoryMenu(player);
    }
    static async openCategoryMenu(player) {
        const form = new ActionFormData()
            .title("GFX Configuration")
            .body("§cWarning: this Add-On is not yet optimized for Vibrant Visual Mode. You can disable this mode in your video settings.§r\nChoose a category to configure");
        for (const biome of GFXButtons.biomeCategories) {
            form.button(biome.label, 'textures/nps/tbe/' + biome.icon);
        }
        form.button(GFXButtons.misc.label, 'textures/nps/tbe/' + GFXButtons.misc.icon);
        const response = await form.show(player);
        if (response.canceled)
            return;
        const index = response.selection;
        if (index === GFXButtons.biomeCategories.length) {
            return this.openMiscConfig(player);
        }
        const biome = GFXButtons.biomeCategories[index];
        return this.openBiomeConfig(player, biome.label, biome.fog, biome.sound, biome.particle);
    }
    static async openBiomeConfig(player, label, modeKey, soundKey, particleKey) {
        const form = new ModalFormData().title(`${label}`);
        const currentMode = player.getDynamicProperty(modeKey) ?? 0;
        const soundVolume = player.getDynamicProperty(soundKey) ?? 100;
        const particlesEnabled = player.getDynamicProperty(particleKey) ?? true;
        const options = ["Disabled", "Light Fog", "Dark Fog"];
        form.dropdown("Fog Effect", options, currentMode);
        form.slider("Ambient Sound Volume", 0, 200, 1, soundVolume);
        form.toggle("Biome Particles", particlesEnabled);
        const response = await form.show(player);
        if (response.canceled)
            return;
        const selectedMode = response.formValues[0];
        const newSoundState = response.formValues[1];
        const newParticleState = response.formValues[2];
        if (selectedMode != currentMode) {
            player.setDynamicProperty(modeKey, selectedMode);
            PlayerBiomeTracker.reloadCurrentBiomeFog(player);
        }
        if (newSoundState != soundVolume) {
            player.setDynamicProperty(soundKey, newSoundState);
            PlayerBiomeTracker.reloadCurrentAmbientSound(player);
        }
        if (newParticleState != particlesEnabled) {
            player.setDynamicProperty(particleKey, newParticleState);
        }
    }
    static async openMiscConfig(player) {
        const form = new ModalFormData()
            .title("Other GFX Settings");
        const toggles = [
            { label: "Aurora Borealis", current: getBoolean(player, TBEPDP.GFX_BB_RANDOM), propertyKey: TBEPDP.GFX_BB_RANDOM },
            { label: "Nebulae", current: getBoolean(player, TBEPDP.GFX_E_C), propertyKey: TBEPDP.GFX_E_C },
            { label: "Starry Sky", current: getBoolean(player, TBEPDP.GFX_StarrySky), propertyKey: TBEPDP.GFX_StarrySky }
        ];
        for (const t of toggles) {
            form.toggle(t.label, t.current);
        }
        const displayMode = player.getDynamicProperty(TBEPDP.BiomeTextDisplayMode) ?? 2;
        form.dropdown("Biome Name Display", ["None", "Chat", "Action Bar", "Title"], displayMode);
        const response = await form.show(player);
        if (response.canceled)
            return;
        toggles.forEach((t, i) => {
            const newVal = response.formValues[i];
            if (newVal !== t.current) {
                player.setDynamicProperty(t.propertyKey, newVal);
            }
        });
        const selectedDisplay = response.formValues[toggles.length];
        player.setDynamicProperty(TBEPDP.BiomeTextDisplayMode, selectedDisplay);
    }
}
GFX.componentName = "nps_tbe:gfx_config";
export var PlayerBiomes;
(function (PlayerBiomes) {
    PlayerBiomes[PlayerBiomes["Vanilla"] = 0] = "Vanilla";
    PlayerBiomes[PlayerBiomes["Amanita"] = 1] = "Amanita";
    PlayerBiomes[PlayerBiomes["Chlorophos"] = 2] = "Chlorophos";
    PlayerBiomes[PlayerBiomes["Cortinarius"] = 3] = "Cortinarius";
    PlayerBiomes[PlayerBiomes["Lactarius"] = 4] = "Lactarius";
    PlayerBiomes[PlayerBiomes["Russula"] = 5] = "Russula";
    PlayerBiomes[PlayerBiomes["Umbromycelia"] = 6] = "Umbromycelia";
})(PlayerBiomes || (PlayerBiomes = {}));
var BiomeTextDisplayMode;
(function (BiomeTextDisplayMode) {
    BiomeTextDisplayMode[BiomeTextDisplayMode["None"] = 0] = "None";
    BiomeTextDisplayMode[BiomeTextDisplayMode["Chat"] = 1] = "Chat";
    BiomeTextDisplayMode[BiomeTextDisplayMode["ActionBar"] = 2] = "ActionBar";
    BiomeTextDisplayMode[BiomeTextDisplayMode["Title"] = 3] = "Title";
})(BiomeTextDisplayMode || (BiomeTextDisplayMode = {}));
export class PlayerBiomeTracker {
    static initialize() {
        system.runInterval(() => {
            this.trackBiomes();
        }, this.checkInterval);
        system.runInterval(() => {
            PlayerBiomeTracker.runTick();
        }, this.soundTicker);
    }
    static afterPlayerSpawn(event) {
        const player = event.player;
        player.setDynamicProperty(TBEPDP.BiomeSoundTimer, 20 * 5);
    }
    static afterPlayerDimensionChange(event) {
        if (event.fromDimension.id == MinecraftDimensionTypes.theEnd) {
            this.stopAllBiomeSounds(event.player);
            this.removeBiomeFogEffects(event.player);
        }
        if (event.toDimension.id == MinecraftDimensionTypes.theEnd) {
            this.reloadCurrentAmbientSound(event.player);
            this.reloadCurrentBiomeFog(event.player);
        }
    }
    static getTopmostBlockNearby(player, spread = 2) {
        const dim = player.dimension;
        const px = Math.floor(player.location.x);
        const pz = Math.floor(player.location.z);
        for (let dx = -spread; dx <= spread; dx++) {
            for (let dz = -spread; dz <= spread; dz++) {
                try {
                    const x = px + dx;
                    const z = pz + dz;
                    const top = dim.getTopmostBlock({ x, z });
                    // Optionnel : ignore les blocs "air" ou trop génériques
                    if (top && top.typeId !== "minecraft:air") {
                        return top;
                    }
                }
                catch {
                    // chunk pas encore chargé ou erreur -> on ignore
                }
            }
        }
        return undefined;
    }
    static trackBiomes() {
        const dim = world.getDimension(MinecraftDimensionTypes.theEnd);
        const players = dim.getPlayers();
        for (const player of players) {
            const oldBiome = player.getDynamicProperty(TBEPDP.LastVisitedBiome) ?? -1;
            const dist = getHorizontalDistance(player.location, { x: 0, y: 0, z: 0 });
            if (dist <= this.centralIslandRadius) {
                if (oldBiome !== PlayerBiomes.Vanilla) {
                    this.setPlayerBiome(player, PlayerBiomes.Vanilla, oldBiome);
                }
                continue;
            }
            try {
                const top = PlayerBiomeTracker.getTopmostBlockNearby(player, 4);
                if (!top)
                    continue;
                let newBiome = undefined;
                const scoreboard = getScoreboard(config.biomeTrackerObjectiveId);
                if (top.typeId.startsWith("nps_tbe:amanita_") || top.typeId == "nps_tbe:stellar_stone") {
                    newBiome = PlayerBiomes.Amanita;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId.startsWith("nps_tbe:cortinarius_")) {
                    newBiome = PlayerBiomes.Cortinarius;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId.startsWith("nps_tbe:chlorophos_")) {
                    newBiome = PlayerBiomes.Chlorophos;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId.startsWith("nps_tbe:lactarius_")) {
                    newBiome = PlayerBiomes.Lactarius;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId.startsWith("nps_tbe:russula_")) {
                    newBiome = PlayerBiomes.Russula;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId.startsWith("nps_tbe:umbromycelia") || top.typeId == "nps_tbe:umbrolith") {
                    newBiome = PlayerBiomes.Umbromycelia;
                    scoreboard.removeParticipant(player);
                }
                else if (top.typeId == "minecraft:end_stone") {
                    const score = scoreboard.hasParticipant(player) ? scoreboard.getScore(player) ?? 0 : 0;
                    scoreboard.setScore(player, score + 1);
                    if (score > 3) {
                        scoreboard.removeParticipant(player);
                        newBiome = PlayerBiomes.Vanilla;
                    }
                }
                if (newBiome !== undefined && newBiome !== oldBiome) {
                    this.setPlayerBiome(player, newBiome, oldBiome);
                }
            }
            catch { }
        }
    }
    static removeBiomeFogEffects(player) {
        player.runCommand('fog @s remove nps_tbe:dark_amanita_fog');
        player.runCommand('fog @s remove nps_tbe:dark_chlorophos_fog');
        player.runCommand('fog @s remove nps_tbe:dark_cortinarius_fog');
        player.runCommand('fog @s remove nps_tbe:dark_lactarius_fog');
        player.runCommand('fog @s remove nps_tbe:dark_russula_fog');
        player.runCommand('fog @s remove nps_tbe:dark_umbromycelia_fog');
        player.runCommand('fog @s remove nps_tbe:light_amanita_fog');
        player.runCommand('fog @s remove nps_tbe:light_chlorophos_fog');
        player.runCommand('fog @s remove nps_tbe:light_cortinarius_fog');
        player.runCommand('fog @s remove nps_tbe:light_lactarius_fog');
        player.runCommand('fog @s remove nps_tbe:light_russula_fog');
        player.runCommand('fog @s remove nps_tbe:light_umbromycelia_fog');
    }
    static setPlayerBiome(player, newBiome, oldBiome) {
        player.setDynamicProperty(TBEPDP.LastVisitedBiome, newBiome);
        this.onBiomeChange(player, newBiome, oldBiome);
    }
    static reloadCurrentAmbientSound(player) {
        const currentBiome = player.getDynamicProperty(TBEPDP.LastVisitedBiome);
        if (currentBiome === undefined)
            return;
        this.stopAllBiomeSounds(player);
        this.playBiomeEnterSound(player, currentBiome);
    }
    static reloadCurrentBiomeFog(player) {
        const currentBiome = player.getDynamicProperty(TBEPDP.LastVisitedBiome);
        if (currentBiome === undefined)
            return;
        this.removeBiomeFogEffects(player);
        this.applyBiomeFogEffect(player, currentBiome);
    }
    static onBiomeChange(player, newBiome, oldBiome) {
        this.removeBiomeFogEffects(player);
        this.stopAllBiomeSounds(player);
        this.playBiomeEnterSound(player, newBiome);
        this.applyBiomeFogEffect(player, newBiome);
        this.displayBiomeName(player, newBiome);
    }
    static playBiomeEnterSound(player, biome) {
        const sound = this.BiomeSoundSettings[biome];
        if (!sound)
            return;
        const propertyKey = this.AmbientSoundMap[biome];
        const volume = player.getDynamicProperty(propertyKey);
        if (volume != 0) {
            player.runCommand(`/playsound ${sound.id} @s ~~~ ${sound.volume * volume / 100.0} ${sound.pitch}`);
            player.setDynamicProperty(TBEPDP.BiomeSoundTimer, sound.duration);
        }
    }
    static stopAllBiomeSounds(player) {
        const allSounds = Object.values(this.BiomeSoundSettings);
        for (const sound of allSounds) {
            player.runCommand(`/stopsound @s ${sound.id}`);
        }
    }
    static displayBiomeName(player, biome) {
        //if (biome == PlayerBiomes.CentralIsland) return;
        const displayMode = player.getDynamicProperty(TBEPDP.BiomeTextDisplayMode) ?? BiomeTextDisplayMode.ActionBar;
        if (displayMode === BiomeTextDisplayMode.None)
            return;
        const biomeId = PlayerBiomes[biome].toLowerCase();
        const textKey = `nps_tbe.biome.enter.${biomeId}`;
        switch (displayMode) {
            case BiomeTextDisplayMode.ActionBar:
                player.onScreenDisplay.setActionBar({ translate: textKey });
                break;
            case BiomeTextDisplayMode.Title:
                player.onScreenDisplay.setTitle({ translate: textKey });
                break;
            case BiomeTextDisplayMode.Chat:
                player.sendMessage({ translate: textKey });
                break;
        }
    }
    static applyBiomeFogEffect(player, biome) {
        const playerBiome = PlayerBiomes[biome];
        if (playerBiome == undefined)
            return;
        const biomeId = playerBiome.toLowerCase();
        const modeKey = TBEPDP[`Fog_${PlayerBiomes[biome]}`];
        const modeValue = player.getDynamicProperty(modeKey);
        if (modeValue == 0)
            return;
        const mode = modeValue === 1 ? "light" : "dark";
        const fogId = `nps_tbe:${mode}_${biomeId}_fog`;
        const propertyKey = this.BiomeFogMap[biome];
        const isEnabled = player.getDynamicProperty(propertyKey);
        if (isEnabled === false)
            return;
        const command = `fog @s push ${fogId} ${fogId}`;
        player.runCommandAsync(command).catch(() => { });
    }
    static getCurrentBiome(player) {
        if (player == undefined)
            return undefined;
        const currentBiome = player.getDynamicProperty(TBEPDP.LastVisitedBiome);
        return currentBiome;
    }
    static getParticlesEnabled(player) {
        const currentBiome = PlayerBiomeTracker.getCurrentBiome(player);
        if (currentBiome === undefined)
            return false;
        const modeKey = TBEPDP[`Particles_${PlayerBiomes[currentBiome]}`];
        if (modeKey === undefined)
            return false;
        const modeValue = player.getDynamicProperty(modeKey);
        return modeValue;
    }
    static runTick() {
        for (const player of world.getDimension(MinecraftDimensionTypes.theEnd).getPlayers()) {
            const timer = player.getDynamicProperty(TBEPDP.BiomeSoundTimer);
            if (typeof timer !== "number")
                continue;
            if (timer > 0) {
                player.setDynamicProperty(TBEPDP.BiomeSoundTimer, timer - this.soundTicker);
            }
            else {
                const currentBiome = player.getDynamicProperty(TBEPDP.LastVisitedBiome);
                if (currentBiome === undefined)
                    continue;
                this.playBiomeEnterSound(player, currentBiome);
            }
        }
    }
}
PlayerBiomeTracker.checkInterval = 20;
PlayerBiomeTracker.centralIslandRadius = 256;
PlayerBiomeTracker.soundTicker = 10;
PlayerBiomeTracker.BiomeFogMap = {
    [PlayerBiomes.Vanilla]: TBEPDP.Fog_Vanilla,
    [PlayerBiomes.Amanita]: TBEPDP.Fog_Amanita,
    [PlayerBiomes.Chlorophos]: TBEPDP.Fog_Chlorophos,
    [PlayerBiomes.Cortinarius]: TBEPDP.Fog_Cortinarius,
    [PlayerBiomes.Lactarius]: TBEPDP.Fog_Lactarius,
    [PlayerBiomes.Russula]: TBEPDP.Fog_Russula,
    [PlayerBiomes.Umbromycelia]: TBEPDP.Fog_Umbromycelia,
};
PlayerBiomeTracker.AmbientSoundMap = {
    [PlayerBiomes.Vanilla]: TBEPDP.AmbientSoundVolume_Vanilla,
    [PlayerBiomes.Amanita]: TBEPDP.AmbientSoundVolume_Amanita,
    [PlayerBiomes.Chlorophos]: TBEPDP.AmbientSoundVolume_Chlorophos,
    [PlayerBiomes.Cortinarius]: TBEPDP.AmbientSoundVolume_Cortinarius,
    [PlayerBiomes.Lactarius]: TBEPDP.AmbientSoundVolume_Lactarius,
    [PlayerBiomes.Russula]: TBEPDP.AmbientSoundVolume_Russula,
    [PlayerBiomes.Umbromycelia]: TBEPDP.AmbientSoundVolume_Umbromycelia,
};
PlayerBiomeTracker.BiomeSoundSettings = {
    [PlayerBiomes.Amanita]: { id: "ambient.crimson_forest.loop", volume: 0.25, pitch: 0.5, duration: 20 * 75 },
    [PlayerBiomes.Cortinarius]: { id: "ambient.basalt_deltas.loop", volume: 0.075, pitch: 1.2, duration: 20 * 35 },
    [PlayerBiomes.Lactarius]: { id: "ambient.nether_wastes.loop", volume: 0.25, pitch: 0.5, duration: 20 * 55 },
    [PlayerBiomes.Chlorophos]: { id: "ambient.crimson_forest.loop", volume: 0.25, pitch: 1.25, duration: 20 * 30 },
    [PlayerBiomes.Russula]: { id: "ambient.warped_forest.loop", volume: 0.075, pitch: 1.35, duration: 20 * 35 },
    [PlayerBiomes.Umbromycelia]: { id: "ambient.warped_forest.loop", volume: 0.25, pitch: 0.7, duration: 20 * 65 },
    [PlayerBiomes.Vanilla]: { id: "ambient.crimson_forest.loop", volume: 0.25, pitch: 0.70, duration: 20 * 55 }
};
let spawnBaseChance = 1 / world.gameRules.randomTickSpeed;
world.afterEvents.gameRuleChange.subscribe(event => {
    if (event.rule === GameRule.RandomTickSpeed && typeof event.value === "number") {
        spawnBaseChance = 1 / world.gameRules.randomTickSpeed;
    }
});
class AmanitaSoil {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        AmanitaSoil.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.75)
            this.emitGroundFogParticles(event);
        if (Math.random() > 0.99)
            this.emitSoilBlossomParticles(event);
    }
    static emitSoilBlossomParticles(event) {
        event.dimension.spawnParticle("nps_tbe:amanita_spore_blossom", event.block.above().location);
    }
    static emitGroundFogParticles(event) {
        //event.dimension.spawnParticle('nps_tbe:epp', event.block.location);
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], event.block.above().bottomCenter());
    }
}
AmanitaSoil.componentName = "nps_tbe:a465dd28";
AmanitaSoil.particles = [
    "nps_tbe:amanita_fog_x1",
    "nps_tbe:amanita_fog_x2",
    "nps_tbe:amanita_fog_x3",
    "nps_tbe:amanita_fog_x4"
];
class CortinariusSoil {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        CortinariusSoil.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.75)
            this.emitGroundFogParticles(event);
        if (Math.random() > 0.99)
            this.emitSoilBlossomParticles(event);
    }
    static emitSoilBlossomParticles(event) {
        const blockAbove = event.block.above();
        event.dimension.spawnParticle("nps_tbe:cortinarius_spore_blossom", blockAbove.location);
    }
    static emitGroundFogParticles(event) {
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], event.block.above().bottomCenter());
    }
}
CortinariusSoil.componentName = "nps_tbe:a2ee5e21";
CortinariusSoil.particles = [
    "nps_tbe:cortinarius_fog_x1",
    "nps_tbe:cortinarius_fog_x2",
    "nps_tbe:cortinarius_fog_x3",
    "nps_tbe:cortinarius_fog_x4"
];
class ChlorophosSoil {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        ChlorophosSoil.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.75)
            this.emitGroundFogParticles(event);
        if (Math.random() > 0.99)
            this.emitSoilBlossomParticles(event);
    }
    static emitSoilBlossomParticles(event) {
        event.dimension.spawnParticle("nps_tbe:chlorophos_spore_blossom", event.block.above().location);
    }
    static emitGroundFogParticles(event) {
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], event.block.above().bottomCenter());
    }
}
ChlorophosSoil.componentName = "nps_tbe:ff8ffa70";
ChlorophosSoil.particles = [
    "nps_tbe:chlorophos_fog_x1",
    "nps_tbe:chlorophos_fog_x2",
    "nps_tbe:chlorophos_fog_x3",
    "nps_tbe:chlorophos_fog_x4"
];
class LactariusSoil {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        LactariusSoil.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.75)
            this.emitGroundFogParticles(event);
        if (Math.random() > 0.98)
            this.emitSoilBlossomParticles(event);
    }
    static emitSoilBlossomParticles(event) {
        //event.dimension.spawnParticle('nps_tbe:epp', event.block.location);
        const aboveLocation = event.block.above().location;
        const location = {
            x: aboveLocation.x,
            y: aboveLocation.y + 4,
            z: aboveLocation.z
        };
        event.dimension.spawnParticle("nps_tbe:lactarius_spore_blossom", location);
    }
    static emitGroundFogParticles(event) {
        //event.dimension.spawnParticle('nps_tbe:epp', event.block.location);
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], event.block.above().bottomCenter());
    }
}
LactariusSoil.componentName = "nps_tbe:8994271a";
LactariusSoil.particles = [
    "nps_tbe:lactarius_fog_x1",
    "nps_tbe:lactarius_fog_x2",
    "nps_tbe:lactarius_fog_x3",
    "nps_tbe:lactarius_fog_x4"
];
/*
const tickFunctionCalls: Record<number, number> = {};
function logFunctionCallThisTick(): void {
    const currentTick = system.currentTick;
    tickFunctionCalls[currentTick] = (tickFunctionCalls[currentTick] ?? 0) + 1;
}
function printFunctionCallStats(): void {
    for (const [tick, count] of Object.entries(tickFunctionCalls)) {
        console.warn(`Tick ${tick}: ${count} call(s)`);
    }
}
function resetTickFunctionCalls(): void {
    for (const key in tickFunctionCalls) {
        delete tickFunctionCalls[key];
    }
}
system.runInterval(() => {
    printFunctionCallStats();
    resetTickFunctionCalls();
},2);
*/
class Umbrolith {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        Umbrolith.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.75)
            this.emitGroundFogParticles(event);
    }
    static emitGroundFogParticles(event) {
        //event.dimension.spawnParticle('nps_tbe:epp', event.block.location);
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], blockAbove.bottomCenter());
    }
}
Umbrolith.componentName = "nps_tbe:9a157f4e";
Umbrolith.particles = [
    "nps_tbe:umbromycelia_fog_x1",
    "nps_tbe:umbromycelia_fog_x2",
    "nps_tbe:umbromycelia_fog_x3",
    "nps_tbe:umbromycelia_fog_x4"
];
class RussulaRock {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        if (Math.random() > spawnBaseChance)
            return;
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        const player = getClosestPlayer(event.dimension, event.block.location);
        const modeValue = PlayerBiomeTracker.getParticlesEnabled(player);
        if (modeValue == false)
            return;
        RussulaRock.emitParticles(event);
    }
    static emitParticles(event) {
        if (Math.random() > 0.92)
            this.emitGroundFogParticles(event);
    }
    static emitGroundFogParticles(event) {
        //event.dimension.spawnParticle('nps_tbe:epp', event.block.location);
        const blockAbove = event.block.above();
        if (blockAbove == undefined || !blockAbove.isAir)
            return;
        event.dimension.spawnParticle(this.particles[getRandomInt(0, this.particles.length - 1)], blockAbove.bottomCenter());
    }
}
RussulaRock.componentName = "nps_tbe:d5680160";
RussulaRock.particles = [
    "nps_tbe:russula_fog_x1",
    "nps_tbe:russula_fog_x2",
    "nps_tbe:russula_fog_x3",
    "nps_tbe:russula_fog_x4"
];
//..
world.afterEvents.playerInteractWithBlock.subscribe((event) => {
    const block = event.block;
    const item = event.beforeItemStack;
    if (block.typeId === "minecraft:end_portal_frame" &&
        item?.typeId === "minecraft:ender_eye") {
        const pos = block.above().bottomCenter();
        block.dimension.spawnParticle("nps_tbe:ender_eye_placement", pos);
    }
});
world.afterEvents.playerDimensionChange.subscribe((event) => {
    if (event.toDimension.id === MinecraftDimensionTypes.theEnd) {
        const player = event.player;
        player.dimension.spawnParticle("nps_tbe:enter_end_dimension_effect", player.location);
        player.runCommand(`/execute positioned ~ ~ ~ run function nps/tbe/bb_random`);
    }
    PlayerBiomeTracker.afterPlayerDimensionChange(event);
});
world.beforeEvents.worldInitialize.subscribe(event => {
    AmanitaSoil.initialize(event);
    CortinariusSoil.initialize(event);
    ChlorophosSoil.initialize(event);
    LactariusSoil.initialize(event);
    Umbrolith.initialize(event);
    RussulaRock.initialize(event);
    GFX.initialize(event);
});
world.afterEvents.worldInitialize.subscribe(event => {
    PlayerBiomeTracker.initialize();
    EndParticleFunctionManager.initialize();
});
world.afterEvents.playerSpawn.subscribe(event => {
    PlayerBiomeTracker.afterPlayerSpawn(event);
});
