import { BlockVolume, EntityComponentTypes, EntityDamageCause, EquipmentSlot, GameMode, ItemStack, MolangVariableMap, system, WeatherType, world } from "@minecraft/server";
import { BiomeTemps, getBiomeFromId } from "./BiomeQuery";
import { directionalLerp } from "./helperFunctions";
import { Limb, LimbDamagedThreshold, MAX_LIMB_HEALTH } from "./LimbDamage";
import { thirstDecimalAccuracy } from "./Thirst";
var MonitorState;
(function (MonitorState) {
    MonitorState["HEALTHY"] = "healthy";
    MonitorState["WARNING"] = "warning";
    MonitorState["CRITICAL"] = "critical";
})(MonitorState || (MonitorState = {}));
;
export const BrutalPlayerMethods = {
    // Health menu
    updateHealthMenuItem: function () {
        const invenComp = this.getComponent(EntityComponentTypes.Inventory);
        // Find item slot
        const healthMonitorItemSlots = [];
        for (let i = 0; i < invenComp.container.size; i++) {
            const item = invenComp.container.getItem(i);
            if (item?.typeId.startsWith("oct_db:health_monitor"))
                healthMonitorItemSlots.push(i);
        }
        // Check offhand
        const equippableComp = this.getComponent(EntityComponentTypes.Equippable);
        const offhand = equippableComp.getEquipment(EquipmentSlot.Offhand);
        if (offhand?.typeId.startsWith("oct_db:health_monitor"))
            healthMonitorItemSlots.push(EquipmentSlot.Offhand);
        // Check if player has health monitor item in inventory
        if (healthMonitorItemSlots.length === 0)
            return;
        //* Check what state the health monitor should be
        let monitorState = MonitorState.HEALTHY; // Default
        // Warning
        if (this.getRelativeTemp() >= 75.0 || this.getRelativeTemp() <= 25.0)
            monitorState = MonitorState.WARNING;
        for (const limb in Limb) {
            if (this.getLimbHealth(limb) <= 25)
                monitorState = MonitorState.WARNING;
        }
        ;
        if (this.getThirst() <= 0.25)
            monitorState = MonitorState.WARNING;
        // Critical
        if (this.getRelativeTemp() >= 100 || this.getRelativeTemp() <= 0)
            monitorState = MonitorState.CRITICAL;
        for (const limb in Limb) {
            if (this.getLimbHealth(limb) <= 0)
                monitorState = MonitorState.CRITICAL;
        }
        ;
        if (this.getThirst() <= 0)
            monitorState = MonitorState.CRITICAL;
        // Update health monitor item
        for (const slot of healthMonitorItemSlots) {
            // If in offhand (edge case)
            if (slot === EquipmentSlot.Offhand) {
                const healthMonitorItem = equippableComp.getEquipment(slot);
                const newItem = new ItemStack(`oct_db:health_monitor.${monitorState}`, 1);
                if (healthMonitorItem.typeId === newItem.typeId)
                    continue;
                equippableComp.setEquipment(slot, newItem);
                continue;
            }
            ;
            // If in inventory
            const healthMonitorItem = invenComp.container.getItem(slot);
            const newItem = new ItemStack(`oct_db:health_monitor.${monitorState}`, 1);
            if (healthMonitorItem.typeId === newItem.typeId)
                continue;
            invenComp.container.setItem(slot, newItem);
        }
    },
    // Thirst
    checkThirst: function () {
        const thirst = this.getThirst();
        if (thirst <= 0.0) {
            this.applyTickDamage();
        }
    },
    getThirst: function () {
        return Number((this.getDynamicProperty("oct:thirst") ?? 0.5).toFixed(thirstDecimalAccuracy));
    },
    setThirst: function (thirst) {
        const setThirst = Math.max(0, Math.min(1, thirst));
        this.setDynamicProperty("oct:thirst", setThirst);
        this.playAnimation(`animation.oct_db.health_menu.thirst_${(Number(setThirst) * 100).toFixed(0)}`, { controller: "oct:thirst" });
        // console.warn(`animation.oct_db.health_menu.thirst_${(Number(setThirst) * 100).toFixed(0)}`)
    },
    resetThirst: function () {
        this.setThirst(1);
    },
    applyExtremeWeatherDetriments: function () {
        const currentTemp = this.getRelativeTemp(); // 0 - 100, 0 is freezing, 100 is heatstroke
        // Cold effects
        if (currentTemp <= 25.0) {
            this.addEffect("minecraft:slowness", 60, { amplifier: 1, showParticles: false });
        }
        if (currentTemp <= 12.5) {
            // Find armour that isn't covered in insulated gear
            const limbsToDamage = [];
            const equippableComp = this.getComponent(EntityComponentTypes.Equippable);
            for (const equipment of [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet]) {
                const gear = equippableComp.getEquipment(equipment);
                if (gear?.hasTag("oct_db:insulated_armor"))
                    continue;
                // console.warn(`Damage to ${equipment}`);
                // Damage uninsulated limbs
                switch (equipment) {
                    case EquipmentSlot.Head:
                        limbsToDamage.push(Limb.Head);
                        break;
                    case EquipmentSlot.Chest:
                        limbsToDamage.push(Limb.Body, Limb.LeftArm, Limb.RightArm);
                        break;
                    case EquipmentSlot.Legs:
                        limbsToDamage.push(Limb.Legs);
                        break;
                    case EquipmentSlot.Feet:
                        limbsToDamage.push(Limb.Legs);
                        break;
                }
            }
            for (const limb of limbsToDamage) {
                this.damageSpecificLimb(limb, 1);
            }
        }
        if (currentTemp <= 1) {
            this.applyTickDamage(EntityDamageCause.freezing);
        }
        // Heat effects
        if (currentTemp >= 75.0) {
            // Already applied "warm" effects elsewhere, skip
        }
        if (currentTemp >= 87.5) {
            // Do every other tick because it's way too fast right now
            if (system.currentTick % 40 === 0)
                this.damageSpecificLimb(Limb.Head, 1); // Overheat limb damage
        }
        if (currentTemp >= 99) {
            this.addEffect("minecraft:nausea", 120, { amplifier: 1, showParticles: false });
        }
    },
    deteriorateThirst: function () {
        let baseDeteriorationRate = -0.0001;
        // Difficulty modifiers
        const difficulty = world.getDynamicProperty('oct_db:worldSetting');
        if (difficulty === 1)
            baseDeteriorationRate *= 0.5;
        if (difficulty === 2)
            baseDeteriorationRate *= 0.75;
        if (this.isSprinting)
            baseDeteriorationRate *= 2;
        // Moisturizing Talisman
        const talismanFactor = 0.5;
        const invenComp = this.getComponent(EntityComponentTypes.Inventory);
        const hasTalisman = Array.from({ length: invenComp.container.size }, (_, i) => invenComp.container.getItem(i)).some(item => item?.typeId === "oct_db:moisturizing_talisman");
        // Heat - Anything beyond 0.5 temp gradually increases thirst rate
        const heatRate = -Math.max(0, ((Number((this.getRelativeTemp() / 100).toFixed(2)) - 0.5) / 10000));
        // Set thirst
        const deteriorationRate = (heatRate + baseDeteriorationRate) * (hasTalisman ? talismanFactor : 1);
        const roundedDeteriorationRate = Math.round(deteriorationRate * (10 ** thirstDecimalAccuracy) * Math.sign(deteriorationRate)) / (10 ** thirstDecimalAccuracy) * Math.sign(deteriorationRate);
        const setThirst = this.getThirst() + roundedDeteriorationRate;
        this.setThirst(setThirst);
        // console.warn(`Thirst rate: ${roundedDeteriorationRate}, current thirst: ${this.getThirst()}`);
    },
    // Temperature
    getTemperature: function () {
        return Number((this.getDynamicProperty("oct:temperature") ?? 0.5).toFixed(4));
    },
    getOptimalTemp: function () {
        let optimalTemp = BiomeTemps.Optimal;
        const equipmentToCheck = [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet];
        // Don't affect creative or spectator player
        const playerGamemode = this.getGameMode();
        if (playerGamemode === GameMode.creative || playerGamemode === GameMode.spectator)
            return optimalTemp;
        // Decrease optimal temperature based on how many insulated gear 
        const equippableComp = this.getComponent(EntityComponentTypes.Equippable);
        // Get optimal temperature based on current environment
        const getInsulationLevel = (relativeTemperature) => {
            const optimalTemp = 0.5;
            const factor = 11;
            return Math.abs(relativeTemperature - optimalTemp) * factor;
        };
        const insulationLevel = getInsulationLevel(this.getTemperature()); // How much to reduce each
        for (const equipment of equipmentToCheck) {
            const gear = equippableComp.getEquipment(equipment);
            if (!gear)
                continue;
            if (!gear.hasTag("oct_db:insulated_armor"))
                continue;
            optimalTemp -= insulationLevel;
        }
        ;
        return optimalTemp;
    },
    getRelativeTemp: function () {
        const optimalTemp = this.getOptimalTemp();
        const extremeRangeDifference = 20; // Range between extreme hot and extreme cold
        const relativeTemp = Math.max(0, Math.min(100, (this.getTemperature() * 100 - optimalTemp) * (100 / extremeRangeDifference) / 2 + 50));
        return relativeTemp;
    },
    setTemperature: function (temperature) {
        this.setDynamicProperty("oct:temperature", temperature);
        // If the last animation is the same, return for performance 
        const setTemp = this.getRelativeTemp();
        const animationTemp = setTemp.toFixed(0);
        if (animationTemp === this.getDynamicProperty("oct:animation_temp"))
            return;
        this.setDynamicProperty("oct:animation_temp", animationTemp);
        this.playAnimation(`animation.oct_db.health_menu.temp_${animationTemp}`, { controller: "oct:temp" });
    },
    resetTemperature: function () {
        this.setTemperature(0.25);
    },
    setTemperatureFromEnvironment: function () {
        const temperature = this.getTemperature();
        const timeOfDay = (world.getTimeOfDay() >= 1000 && world.getTimeOfDay() < 13000) ? "day" : "night";
        const biomeTemp = this.getBiome().temperature[timeOfDay] / 100;
        const weatherTemp = this.getWeatherTemperature() / 100;
        const nearbyBlockTemp = this.getNearbyBlockTemperature() / 100;
        // console.warn(`temperature: ${temperature}, biomeTemp: ${biomeTemp}, weatherTemp: ${weatherTemp}, nearbyBlockTemp: ${nearbyBlockTemp}`)
        // Add environment and ease
        const goalTemp = biomeTemp + nearbyBlockTemp + weatherTemp;
        const setTemp = directionalLerp(temperature, goalTemp, 0.1);
        this.setTemperature(setTemp);
    },
    getWeatherTemperature: function () {
        const currentWeather = (world.getDynamicProperty(`oct_db:weather`) ?? WeatherType.Clear);
        switch (currentWeather) {
            case WeatherType.Clear:
                return 0;
            case WeatherType.Rain:
                return -3;
            case WeatherType.Thunder:
                return -5;
            default:
                return 0;
        }
    },
    getNearbyBlockTemperature: function () {
        const getInsulationLevel = (relativeTemperature) => {
            const optimalTemp = 0.5;
            const factor = 30;
            return Math.abs(relativeTemperature - optimalTemp) * factor;
        };
        let nearbyBlockTemperature = 0;
        const blockDetectionRange = 4;
        const blockVolume = new BlockVolume({ x: this.location.x - blockDetectionRange, y: this.location.y - blockDetectionRange, z: this.location.z - blockDetectionRange }, { x: this.location.x + blockDetectionRange, y: this.location.y + blockDetectionRange, z: this.location.z + blockDetectionRange });
        const temperatureBlocks = [{ typeId: "minecraft:campfire", temp: getInsulationLevel(this.getTemperature()) }, { typeId: "minecraft:torch", temp: 2 }];
        for (const temperatureBlock of temperatureBlocks) {
            if (!this.dimension.containsBlock(blockVolume, { includeTypes: [temperatureBlock.typeId] }, true))
                continue;
            nearbyBlockTemperature += temperatureBlock.temp;
        }
        ;
        // Edge cases
        // Swimming
        const getSwimmingTemperatureEffect = (relativeTemperature) => {
            const optimalTemp = 0.5;
            const optimalTempThreshold = 0.05;
            const tempFactor = 100; // Higher = more aggressive temperature changes
            if (Math.abs(relativeTemperature - optimalTemp) < optimalTempThreshold) {
                return 0; // No change if already optimal
            }
            else if (relativeTemperature > optimalTemp) {
                // If the player is too hot, swimming cools them down towards optimal
                return Math.min(-Math.abs(relativeTemperature - optimalTemp) * tempFactor, -2);
            }
            else if (relativeTemperature < optimalTemp) {
                // If the player is too cold, swimming cools them further
                return -Math.abs(relativeTemperature - optimalTemp);
            }
            return 0; // Should never get here but just in case
        };
        const swimmingTemp = getSwimmingTemperatureEffect(this.getRelativeTemp() / 100);
        if (this.isInWater) {
            nearbyBlockTemperature += swimmingTemp;
            // console.warn(swimmingTemp)
        }
        // Standing on snow
        const onSnowTemp = -5;
        const block = this.dimension.getBlock({ x: this.location.x, y: this.location.y - 0.3, z: this.location.z });
        const coldBlocks = ["minecraft:snow_layer", "minecraft:snow", "minecraft:powder_snow", "minecraft:ice", "minecraft:blue_ice", "minecraft:packed_ice"];
        if (coldBlocks.includes(block?.typeId))
            nearbyBlockTemperature += onSnowTemp;
        return nearbyBlockTemperature;
    },
    // Biome
    getBiome: function () {
        try {
            const biomeQueryEntity = this.dimension.spawnEntity("oct_db:biome_query", this.location);
            const biomeId = biomeQueryEntity.getProperty("oct:biome");
            biomeQueryEntity.remove();
            return getBiomeFromId(biomeId);
        }
        catch (e) {
            return { typeId: "unknown", id: 255, temperature: { day: BiomeTemps.Optimal, night: BiomeTemps.Cold } };
        }
    },
    // Particle warning effects
    checkParticleWarning: function () {
        const currentThirst = this.getThirst();
        const currentTemp = this.getTemperature() / 0.4; // I think it's 0 to 0.4
        const thirstThreshold = 0;
        const tempThreshold = [0.01, 0.125, 0.875, 0.99]; // Range
        // Thirst
        if (currentThirst <= thirstThreshold) {
            this.dimension.spawnParticle(`oct_db:thirst`, this.location);
        }
        // Heat
        const molang = new MolangVariableMap();
        if (currentTemp <= tempThreshold[0]) { // Hypothermia
            // console.warn(`1`);
            molang.setFloat(`variable.spawn_rate`, 20);
            this.dimension.spawnParticle(`oct_db:cold`, this.location, molang);
        }
        else if (currentTemp > tempThreshold[0] && currentTemp <= tempThreshold[1]) { // Frostbite
            // console.warn(`2`);
            molang.setFloat(`variable.spawn_rate`, 5);
            this.dimension.spawnParticle(`oct_db:cold`, this.location, molang);
        }
        else if (currentTemp >= tempThreshold[2] && currentTemp < tempThreshold[3]) { // Overheat
            // console.warn(`3`);
            molang.setFloat(`variable.spawn_rate`, 5);
            this.dimension.spawnParticle(`oct_db:hot`, this.location, molang);
        }
        else if (currentTemp >= tempThreshold[3]) { // Heatstroke
            // console.warn(`4`);
            molang.setFloat(`variable.spawn_rate`, 20);
            this.dimension.spawnParticle(`oct_db:hot`, this.location, molang);
        }
    },
    // Fog
    checkFog: function () {
        let lowestLimbHealth = MAX_LIMB_HEALTH;
        for (const limb in Limb) {
            lowestLimbHealth = Math.min(lowestLimbHealth, this.getLimbHealth(limb));
        }
        ;
        // Start from most critical fog to least
        if (lowestLimbHealth <= 0) {
            if (this.getDynamicProperty(`oct_db:last_fog`) === "oct_db:damage_fog_3")
                return;
            this.runCommand(`fog @s push oct_db:damage_fog_3 oct_db:damage_fog`);
            this.setDynamicProperty(`oct_db:last_fog`, "oct_db:damage_fog_3");
        }
        else if (lowestLimbHealth <= MAX_LIMB_HEALTH / 8) {
            if (this.getDynamicProperty(`oct_db:last_fog`) === "oct_db:damage_fog_2")
                return;
            this.runCommand(`fog @s push oct_db:damage_fog_2 oct_db:damage_fog`);
            this.setDynamicProperty(`oct_db:last_fog`, "oct_db:damage_fog_2");
        }
        else if (lowestLimbHealth <= MAX_LIMB_HEALTH / 4) {
            if (this.getDynamicProperty(`oct_db:last_fog`) === "oct_db:damage_fog_1")
                return;
            this.runCommand(`fog @s push oct_db:damage_fog_1 oct_db:damage_fog`);
            this.setDynamicProperty(`oct_db:last_fog`, "oct_db:damage_fog_1");
        }
        else { // Could be written cleaner but I cannot be bothered right now hahahha
            if (this.getDynamicProperty(`oct_db:last_fog`) === undefined && system.currentTick % 200 !== 0)
                return; // Always run every 10s just in case
            this.setDynamicProperty(`oct_db:last_fog`, undefined);
            this.runCommand(`fog @s remove oct_db:damage_fog`);
        }
    },
    // Notifications
    checkNotifications: function () {
        // Check if player has notifications turned on
        if (!(this.getDynamicProperty(`oct_db:setting_notifications`) ?? true))
            return;
        const notificationsArr = [
            { id: "thirsty", condition: this.getThirst() <= 0.5, message: { rawtext: [{ translate: "message.oct_db.notifications.thirsty" }] } },
            { id: "dehydrated", condition: this.getThirst() <= 0.0, message: { rawtext: [{ translate: "message.oct_db.notifications.dehydrated" }] } },
            { id: "warm", condition: this.getRelativeTemp() >= 75.0, message: { rawtext: [{ translate: "message.oct_db.notifications.warm" }] } },
            { id: "overheat", condition: this.getRelativeTemp() >= 87.5, message: { rawtext: [{ translate: "message.oct_db.notifications.overheat" }] } },
            { id: "heatstroke", condition: this.getRelativeTemp() >= 99.0, message: { rawtext: [{ translate: "message.oct_db.notifications.heatstroke" }] } },
            { id: "cold", condition: this.getRelativeTemp() <= 25.0, message: { rawtext: [{ translate: "message.oct_db.notifications.cold" }] } },
            { id: "frostbite", condition: this.getRelativeTemp() <= 12.5, message: { rawtext: [{ translate: "message.oct_db.notifications.frostbite" }] } },
            { id: "hypothermia", condition: this.getRelativeTemp() <= 1.0, message: { rawtext: [{ translate: "message.oct_db.notifications.hypothermia" }] } },
        ];
        for (const limb in Limb) {
            notificationsArr.push({ id: `${limb}_damaged`, condition: this.getLimbHealth(limb) <= LimbDamagedThreshold[limb], message: { rawtext: [{ translate: `message.oct_db.notifications.limb_damage.${limb.toLowerCase()}` }] } }, { id: `${limb}_broken`, condition: this.getLimbHealth(limb) <= 0.0, message: { rawtext: [{ translate: `message.oct_db.notifications.limb_broken.${limb.toLowerCase()}` }] } });
        }
        ;
        // Send notification ONCE, until the condition returns false
        for (const notification of notificationsArr) {
            const notificationDynamicProperty = `oct_db:notification_${notification.id}`;
            if (notification.condition) {
                if (this.getDynamicProperty(notificationDynamicProperty))
                    continue;
                this.sendMessage(notification.message);
                this.setDynamicProperty(notificationDynamicProperty, true);
            }
            else {
                if (!this.getDynamicProperty(notificationDynamicProperty))
                    continue;
                this.setDynamicProperty(notificationDynamicProperty, undefined);
            }
        }
    },
    // Sound effects
    checkSoundEffects: function () {
        const soundArr = [];
        for (const limb in Limb) {
            soundArr.push({ id: `${limb}_damaged`, condition: this.getLimbHealth(limb) <= LimbDamagedThreshold[limb], sound: "fall.egg", camerashake: "camerashake add @s 0.3 0.3 positional" }, { id: `${limb}_broken`, condition: this.getLimbHealth(limb) <= 0.0, sound: "block.turtle_egg.crack", camerashake: "camerashake add @s 0.5 0.5 positional" });
        }
        ;
        // Send notification ONCE, until the condition returns false
        for (const sound of soundArr) {
            const soundDynamicProperty = `oct_db:sound_${sound.id}`;
            if (sound.condition) {
                if (this.getDynamicProperty(soundDynamicProperty))
                    continue;
                this.playSound(sound.sound, { pitch: 0.75, volume: 0.75 });
                this.runCommand(sound.camerashake);
                this.setDynamicProperty(soundDynamicProperty, true);
            }
            else {
                if (!this.getDynamicProperty(soundDynamicProperty))
                    continue;
                this.setDynamicProperty(soundDynamicProperty, undefined);
            }
        }
    },
    checkActionbarStats: function () {
        // Don't show if setting is disabled
        if (!(this.getDynamicProperty(`oct_db:setting_actionbar_stats`) ?? false))
            return;
        // Don't show if player is holding health menu item in mainhand
        const equippableComp = this.getComponent(EntityComponentTypes.Equippable);
        const mainhandItem = equippableComp.getEquipment(EquipmentSlot.Mainhand);
        if (mainhandItem?.typeId.startsWith(`oct_db:health_monitor`))
            return;
        const temperature = (this.getTemperature() * 100).toFixed(1);
        const displayTemp = (this.getDynamicProperty(`oct_db:setting_use_metric`) ?? false) ? temperature + "°C" : ((Number(temperature) * 9 / 5) + 32).toFixed(1) + "°F";
        const thirst = (this.getThirst() * 100).toFixed(1);
        const text = `${displayTemp}, Thirst: ${thirst}%`;
        this.onScreenDisplay.setActionBar(text);
    },
    checkInsulatedFeet: function () {
        const equippableComp = this.getComponent(EntityComponentTypes.Equippable);
        const boots = equippableComp.getEquipment(EquipmentSlot.Feet);
        const lastPos = JSON.parse(this.getDynamicProperty(`oct_db:last_pos`) ?? JSON.stringify(this.location));
        const currentPos = this.location;
        const movementThreshold = 0.25;
        // Don't damage creative or spectator player
        const playerGamemode = this.getGameMode();
        if (playerGamemode === GameMode.creative || playerGamemode === GameMode.spectator)
            return;
        // Check if player has moved horizontally
        if (Math.abs(currentPos.x - lastPos.x) > movementThreshold || Math.abs(currentPos.z - lastPos.z) > movementThreshold) {
            // Check if player is wearing boots
            if (boots)
                return;
            // Check if block underneath is a cold block
            const coldBlocksArr = [
                "minecraft:ice",
                "minecraft:packed_ice",
                "minecraft:blue_ice",
                "minecraft:frosted_ice",
                "minecraft:snow",
                "minecraft:snow_layer",
                "minecraft:powdered_snow",
            ];
            const blockUnderneath = this.dimension.getBlock({ x: this.location.x, y: this.location.y - 0.1, z: this.location.z });
            if (!blockUnderneath)
                return;
            if (!coldBlocksArr.includes(blockUnderneath.typeId))
                return;
            // Damage player
            this.damageSpecificLimb(Limb.Legs, 1);
            // console.warn(`hi`)
        }
        ;
        // Set dp
        this.setDynamicProperty(`oct_db:last_pos`, JSON.stringify(currentPos));
    },
    applyTickDamage: function (damageType = EntityDamageCause.selfDestruct) {
        // Should prioritise none selfDestruct causes
        const currentDamageType = this.getDynamicProperty(`oct_db:should_tick_damage`);
        if (currentDamageType !== undefined && currentDamageType !== EntityDamageCause.selfDestruct)
            return;
        this.setDynamicProperty(`oct_db:should_tick_damage`, damageType);
    },
    checkShouldTickDamage: function () {
        // Don't damage creative or spectator player
        const playerGamemode = this.getGameMode();
        if (playerGamemode === GameMode.creative || playerGamemode === GameMode.spectator)
            return;
        // Apply tick damage
        if (this.getDynamicProperty(`oct_db:should_tick_damage`)) {
            const tickDamageType = EntityDamageCause[this.getDynamicProperty(`oct_db:should_tick_damage`)];
            this.applyDamage(1, { cause: tickDamageType });
            this.setDynamicProperty(`oct_db:should_tick_damage`, undefined);
        }
    },
};
export function initWeather() {
    world.afterEvents.weatherChange.subscribe(result => {
        world.setDynamicProperty(`oct_db:weather`, result.newWeather);
    });
}
