var CUNIHORDE_SPAWN_X = 0;
var CUNIHORDE_SPAWN_Z = 0;
var CUNIHORDE_SAFE_RADIUS = 450;
var CUNIHORDE_AUTO_COOLDOWN_MS = 75 * 60 * 1000;
var CUNIHORDE_PLAYER_COOLDOWN_MS = 90 * 60 * 1000;
var CUNIHORDE_ACTIVE_MAX_MS = 12 * 60 * 1000;
var CUNIHORDE_AUTO_CHECK_TICKS = 6000;
var CUNIMOB_NATURAL_SCAN_TICKS = 30;
var CUNIMOB_NATURAL_SCAN_RADIUS = 32;
var CUNIMOB_NATURAL_SCAN_LIMIT = 8;
var CUNIMOB_BLAZE_SCAN_RADIUS = 48;
var CUNIMOB_BLAZE_SCAN_LIMIT = 12;
var CUNIMOB_LEVEL_TAG = 'cuniculum_mob_level';
var CUNIMOB_SCAN_TAG = 'cuniculum_mob_scan';
var CUNIMOB_GEAR_TAG = 'cuniculum_mob_geared';
var CUNIMOB_GEAR_TARGET_TAG = 'cuniculum_mob_gear_target';
var CUNIMOB_HEAL_TARGET_TAG = 'cuniculum_mob_heal_target';
var CUNIMOB_MANUAL_SPAWN_TAG = 'cuniculum_manual_spawn';
var CUNIMOB_RARITY_TAG_PREFIX = 'cuniculum_rarity_';
var CUNIMOB_SPAWN_DIMENSION = 'cuniculum:spawn_void';
var CUNIMOB_OLD_LABEL_TAGS = ['cuniculum_mob_label', 'cuniculum_mob_label_name', 'cuniculum_mob_label_tags', 'cuniculum_mob_label_stats'];
var CUNIMOB_NATURAL_MAX_LEVEL = 1000000;
var CUNIMOB_HORDE_MAX_LEVEL = 1000000;
var CUNIMOB_LEVEL_MULTIPLIER = 1.30;
var CUNIMOB_PLAYER_PROGRESS_MEMORY_MARGIN = 4;
var CUNIMOB_PLAYER_SCALING_RADIUS = 96;
var CUNIMOB_ENCHANT_GATE_LEVEL = 30;
var CUNIMOB_CORRECT_ENCHANT_DAMAGE_MULTIPLIER = 1.50;
var CUNIMOB_WRONG_ENCHANT_MIN_REDUCTION = 0.10;
var CUNIMOB_WRONG_ENCHANT_MAX_REDUCTION = 0.90;
var CUNIMOB_WRONG_ENCHANT_REDUCTION_PER_LEVEL = 0.008;
var CUNIMOB_SET_HEALTH_BOOST_SECONDS = 8;
var CUNIMOB_DISTANCE_SUPPORT_STEP = 900;
var CUNIMOB_DISTANCE_SUPPORT_MAX = 0;
var CUNIMOB_IRON_GOLEM_LEVEL_BONUS = 8;
var CUNIMOB_IRON_GOLEM_FARM_RADIUS = 48;
var CUNIMOB_IRON_GOLEM_FARM_KEEP = 6;
var CUNIMOB_IRON_GOLEM_FARM_REMOVE = 4;
var CUNIMOB_IRON_GOLEM_KEEP_TAG = 'cuniculum_golem_keep';
var CUNIMOB_TAMED_WOLF_KEEP_TAG = 'cuniculum_tamed_wolf_keep';
var CUNIMOB_TAMED_WOLF_RADIUS = 96;
var CUNIMOB_TAMED_WOLF_MAX = 2;
var CUNIMOB_ELITE_MINION_TAG = 'cuniculum_elite_minion';
var CUNIMOB_ELITE_STARTED_TAG = 'cuniculum_elite_started';
var CUNIMOB_ELITE_BLINK_TAG = 'cuniculum_ability_blink';
var CUNIMOB_ELITE_REFLECT_TAG = 'cuniculum_ability_reflect';
var CUNIMOB_ELITE_SPELL_TAG = 'cuniculum_ability_spell';
var CUNIMOB_ELITE_PULL_TAG = 'cuniculum_ability_pull';
var CUNIMOB_ELITE_SUMMON_TAG = 'cuniculum_ability_summon';
var CUNIMOB_ELITE_DISPEL_TAG = 'cuniculum_ability_dispel';
var CUNIMOB_ELITE_SUNDER_TAG = 'cuniculum_ability_sunder';
var CUNIMOB_ELITE_DISARM_TAG = 'cuniculum_ability_disarm';
var CUNIMOB_ELITE_SHUFFLE_TAG = 'cuniculum_ability_shuffle_inventory';
var CUNIMOB_ELITE_CHAIN_TAG = 'cuniculum_ability_chain_arc';
var CUNIMOB_ELITE_WARCRY_TAG = 'cuniculum_ability_warcry';
var CUNIMOB_ELITE_SNARE_TAG = 'cuniculum_ability_snare';
var CUNIMOB_ELITE_METEOR_TAG = 'cuniculum_ability_meteor';
var CUNIMOB_AURA_TAG = 'cuniculum_ability_aura';
var CUNIMOB_BOSS_CALL_LEVEL = 1;
var CUNIMOB_BOSS_CALL_MIN_DISTANCE = 7;
var CUNIMOB_BOSS_CALL_MAX_DISTANCE = 42;
var CUNIMOB_BOSS_BLOCK_BREAK_COOLDOWN_MS = 850;
var CUNIMOB_REWARD_DROP_DONE_KEY = 'cuniculum_rewards_dropped';
var CUNIMOB_CATEGORY_TAG_PREFIX = 'cuniculum_category_';
var CUNIMOB_CATEGORY_NORMAL = 'normal';
var CUNIMOB_CATEGORY_ELITE = 'elite';
var CUNIMOB_CATEGORY_BOSS = 'boss';
var CUNIMOB_ELITE_TAG = CUNIMOB_CATEGORY_TAG_PREFIX + CUNIMOB_CATEGORY_ELITE;
var CUNIMOB_BOSS_TAG = CUNIMOB_CATEGORY_TAG_PREFIX + CUNIMOB_CATEGORY_BOSS;
var CUNIMOB_COMBAT_TAG = 'cuniculum_in_combat';
var CUNIMOB_ELITE_MINION_LEVEL = 45;
var CUNIMOB_ELITE_ABILITY_LEVEL = 35;
var CUNIMOB_ELITE_SPELL_LEVEL = 30;
var CUNIMOB_INVENTORY_SHUFFLE_COOLDOWN_MS = 26000;
var CUNIMOB_BOSS_INVENTORY_SHUFFLE_COOLDOWN_MS = 18000;
var CUNIMOB_ARMOR_GATE_LEVEL = 35;
var CUNIMOB_ARMOR_WRONG_DAMAGE_BASE = 1.28;
var CUNIMOB_ARMOR_WRONG_DAMAGE_CAP = 2.35;
var CUNIMOB_CREEPER_EXPLOSION_DAMAGE_LEVEL = 18;
var CUNIMOB_CREEPER_EXPLOSION_DAMAGE_CAP = 3.35;
var CUNIMOB_DEATH_POISON_LEVEL = 35;
var CUNIMOB_DEATH_POISON_MIN_RADIUS = 2;
var CUNIMOB_DEATH_POISON_MAX_RADIUS = 10;
var CUNIMOB_OUT_OF_COMBAT_REGEN_ENABLED = false;
var CUNIMOB_MOB_REGEN_TRAITS_ENABLED = false;
var CUNIMOB_OUT_OF_COMBAT_REGEN_RADIUS = 52;
var CUNIMOB_OUT_OF_COMBAT_REGEN_SECONDS = 5;
var CUNIMOB_COMBAT_MEMORY_TICKS = 120;
var CUNIMOB_BLOCK_BREAK_COOLDOWN_MS = 4800;
var CUNIMOB_BLOCK_BREAK_MIN_LEVEL = 35;
var CUNIMOB_BLEED_TAG = 'cuniculum_bleeding_now';
var CUNIMOB_AREA_MINE_COOLDOWN_MS = 650;
var CUNIMOB_EQUIPMENT_DROP_RATE_MULTIPLIER = 0.38;
var CUNIMOB_BOSS_EQUIPMENT_DROP_RATE_MULTIPLIER = 0.58;
var CUNIMOB_SPECIAL_DROP_RATE_MULTIPLIER = 0.34;
var CUNIMOB_MATERIAL_DROP_RATE_MULTIPLIER = 0.42;
var CUNIMOB_SPAWNER_MOB_TAG = 'cuniculum_spawner_limited';
var CUNIMOB_NO_RPG_REWARD_TAG = 'cuniculum_no_rpg_rewards';
var CUNIMOB_DROP_WORLD_TIER_KEY = 'cuniculum_drop_world_tier';
var CUNIMOB_EQUIPMENT_SLOT_CLASS = null;
var CUNIMOB_ITEM_STACK_CLASS = null;
var CUNIMOB_APOTHEOSIS_WORLD_TIER_CLASS = null;
var CUNIMOB_COMPONENT_CLASS = null;

try {
  CUNIMOB_EQUIPMENT_SLOT_CLASS = Java.loadClass('net.minecraft.world.entity.EquipmentSlot');
  CUNIMOB_ITEM_STACK_CLASS = Java.loadClass('net.minecraft.world.item.ItemStack');
  CUNIMOB_COMPONENT_CLASS = Java.loadClass('net.minecraft.network.chat.Component');
} catch (ignored) {
  CUNIMOB_EQUIPMENT_SLOT_CLASS = null;
  CUNIMOB_ITEM_STACK_CLASS = null;
  CUNIMOB_COMPONENT_CLASS = null;
}

try {
  CUNIMOB_APOTHEOSIS_WORLD_TIER_CLASS = Java.loadClass('dev.shadowsoffire.apotheosis.tiers.WorldTier');
} catch (ignoredWorldTier) {
  CUNIMOB_APOTHEOSIS_WORLD_TIER_CLASS = null;
}

var CUNIMOB_WEAPON_POOLS = [
  { min: 2, chance: 0.38, items: ['minecraft:wooden_sword', 'minecraft:stone_sword', 'minecraft:stone_axe', 'rogues:flint_dagger', 'berserker_rpg:flint_berserker_axe'] },
  { min: 8, chance: 0.52, items: ['minecraft:iron_sword', 'minecraft:iron_axe', 'minecraft:bow', 'minecraft:crossbow', 'rogues:iron_dagger', 'rogues:iron_double_axe', 'paladins:iron_mace', 'paladins:iron_great_hammer', 'archers:iron_spear', 'berserker_rpg:iron_berserker_axe'] },
  { min: 22, chance: 0.66, items: ['minecraft:diamond_sword', 'minecraft:diamond_axe', 'rogues:diamond_dagger', 'rogues:diamond_double_axe', 'paladins:diamond_mace', 'paladins:diamond_great_hammer', 'archers:diamond_spear', 'berserker_rpg:diamond_berserker_axe', 'wizards:staff_wizard'] },
  { min: 45, chance: 0.78, items: ['minecraft:netherite_sword', 'minecraft:netherite_axe', 'berserker_rpg:netherite_berserker_axe', 'rogues:netherite_dagger', 'rogues:netherite_double_axe', 'paladins:netherite_mace', 'paladins:netherite_great_hammer', 'archers:netherite_spear', 'wizards:staff_netherite_fire', 'wizards:staff_netherite_arcane', 'oritech:electric_mace'] },
  { min: 70, chance: 0.88, items: ['berserker_rpg:netherite_berserker_axe', 'rogues:netherite_dagger', 'rogues:netherite_double_axe', 'paladins:netherite_mace', 'paladins:netherite_great_hammer', 'archers:netherite_spear', 'archers:netherite_longbow', 'archers:netherite_rapid_crossbow', 'wizards:staff_netherite_arcane', 'elemental_wizards_rpg:staff_netherite_wind', 'forcemaster_rpg:netherite_knuckle', 'oritech:promethium_axe'] }
];

var CUNIMOB_ARMOR_POOLS = [
  { min: 2, chance: 0.34, sets: [
    ['minecraft:leather_helmet', 'minecraft:leather_chestplate', 'minecraft:leather_leggings', 'minecraft:leather_boots'],
    ['minecraft:golden_helmet', 'minecraft:golden_chestplate', 'minecraft:golden_leggings', 'minecraft:golden_boots'],
    ['bards_rpg:entertainer_garb_head', 'bards_rpg:entertainer_garb_chest', 'bards_rpg:entertainer_garb_legs', 'bards_rpg:entertainer_garb_feet'],
    ['berserker_rpg:wildling_head', 'berserker_rpg:wildling_chest', 'berserker_rpg:wildling_legs', 'berserker_rpg:wildling_feet']
  ] },
  { min: 8, chance: 0.48, sets: [
    ['minecraft:chainmail_helmet', 'minecraft:chainmail_chestplate', 'minecraft:chainmail_leggings', 'minecraft:chainmail_boots'],
    ['minecraft:iron_helmet', 'minecraft:iron_chestplate', 'minecraft:iron_leggings', 'minecraft:iron_boots'],
    ['archers:archer_armor_head', 'archers:archer_armor_chest', 'archers:archer_armor_legs', 'archers:archer_armor_feet'],
    ['rogues:rogue_armor_head', 'rogues:rogue_armor_chest', 'rogues:rogue_armor_legs', 'rogues:rogue_armor_feet'],
    ['wizards:wizard_robe_head', 'wizards:wizard_robe_chest', 'wizards:wizard_robe_legs', 'wizards:wizard_robe_feet'],
    ['paladins:priest_robe_head', 'paladins:priest_robe_chest', 'paladins:priest_robe_legs', 'paladins:priest_robe_feet']
  ] },
  { min: 22, chance: 0.62, sets: [
    ['minecraft:diamond_helmet', 'minecraft:diamond_chestplate', 'minecraft:diamond_leggings', 'minecraft:diamond_boots'],
    ['archers:ranger_armor_head', 'archers:ranger_armor_chest', 'archers:ranger_armor_legs', 'archers:ranger_armor_feet'],
    ['rogues:warrior_armor_head', 'rogues:warrior_armor_chest', 'rogues:warrior_armor_legs', 'rogues:warrior_armor_feet'],
    ['rogues:assassin_armor_head', 'rogues:assassin_armor_chest', 'rogues:assassin_armor_legs', 'rogues:assassin_armor_feet'],
    ['paladins:paladin_armor_head', 'paladins:paladin_armor_chest', 'paladins:paladin_armor_legs', 'paladins:paladin_armor_feet'],
    ['wizards:arcane_robe_head', 'wizards:arcane_robe_chest', 'wizards:arcane_robe_legs', 'wizards:arcane_robe_feet'],
    ['wizards:fire_robe_head', 'wizards:fire_robe_chest', 'wizards:fire_robe_legs', 'wizards:fire_robe_feet'],
    ['wizards:frost_robe_head', 'wizards:frost_robe_chest', 'wizards:frost_robe_legs', 'wizards:frost_robe_feet'],
    ['elemental_wizards_rpg:kelp_head', 'elemental_wizards_rpg:kelp_chest', 'elemental_wizards_rpg:kelp_legs', 'elemental_wizards_rpg:kelp_feet'],
    ['elemental_wizards_rpg:wind_head', 'elemental_wizards_rpg:wind_chest', 'elemental_wizards_rpg:wind_legs', 'elemental_wizards_rpg:wind_feet'],
    ['bards_rpg:storyteller_garb_head', 'bards_rpg:storyteller_garb_chest', 'bards_rpg:storyteller_garb_legs', 'bards_rpg:storyteller_garb_feet'],
    ['archers_expansion:deadeye_head', 'archers_expansion:deadeye_chest', 'archers_expansion:deadeye_legs', 'archers_expansion:deadeye_feet'],
    ['archers_expansion:tundra_hunter_head', 'archers_expansion:tundra_hunter_chest', 'archers_expansion:tundra_hunter_legs', 'archers_expansion:tundra_hunter_feet'],
    ['archers_expansion:war_archer_head', 'archers_expansion:war_archer_chest', 'archers_expansion:war_archer_legs', 'archers_expansion:war_archer_feet']
  ] },
  { min: 45, chance: 0.74, sets: [
    ['minecraft:netherite_helmet', 'minecraft:netherite_chestplate', 'minecraft:netherite_leggings', 'minecraft:netherite_boots'],
    ['paladins:crusader_armor_head', 'paladins:crusader_armor_chest', 'paladins:crusader_armor_legs', 'paladins:crusader_armor_feet'],
    ['paladins:prior_robe_head', 'paladins:prior_robe_chest', 'paladins:prior_robe_legs', 'paladins:prior_robe_feet'],
    ['rogues:berserker_armor_head', 'rogues:berserker_armor_chest', 'rogues:berserker_armor_legs', 'rogues:berserker_armor_feet'],
    ['bards_rpg:troubadour_garb_head', 'bards_rpg:troubadour_garb_chest', 'bards_rpg:troubadour_garb_legs', 'bards_rpg:troubadour_garb_feet'],
    ['berserker_rpg:northling_head', 'berserker_rpg:northling_chest', 'berserker_rpg:northling_legs', 'berserker_rpg:northling_feet'],
    ['berserker_rpg:warlord_head', 'berserker_rpg:warlord_chest', 'berserker_rpg:warlord_legs', 'berserker_rpg:warlord_feet'],
    ['elemental_wizards_rpg:elemental_head', 'elemental_wizards_rpg:elemental_chest', 'elemental_wizards_rpg:elemental_legs', 'elemental_wizards_rpg:elemental_feet'],
    ['elemental_wizards_rpg:hurricane_robe_head', 'elemental_wizards_rpg:hurricane_robe_chest', 'elemental_wizards_rpg:hurricane_robe_legs', 'elemental_wizards_rpg:hurricane_robe_feet'],
    ['forcemaster_rpg:oriene_head', 'forcemaster_rpg:oriene_chest', 'forcemaster_rpg:oriene_legs', 'forcemaster_rpg:oriene_feet'],
    ['archers_expansion:bounty_hunter_head', 'archers_expansion:bounty_hunter_chest', 'archers_expansion:bounty_hunter_legs', 'archers_expansion:bounty_hunter_feet'],
    ['archers_expansion:polar_stalker_head', 'archers_expansion:polar_stalker_chest', 'archers_expansion:polar_stalker_legs', 'archers_expansion:polar_stalker_feet'],
    ['archers_expansion:sentinel_archer_head', 'archers_expansion:sentinel_archer_chest', 'archers_expansion:sentinel_archer_legs', 'archers_expansion:sentinel_archer_feet'],
    ['oritech:exo_helmet', 'oritech:exo_chestplate', 'oritech:exo_leggings', 'oritech:exo_boots']
  ] },
  { min: 70, chance: 0.86, sets: [
    ['minecraft:netherite_helmet', 'minecraft:netherite_chestplate', 'minecraft:netherite_leggings', 'minecraft:netherite_boots'],
    ['minecraft:diamond_helmet', 'minecraft:diamond_chestplate', 'minecraft:diamond_leggings', 'minecraft:diamond_boots'],
    ['archers:netherite_ranger_armor_head', 'archers:netherite_ranger_armor_chest', 'archers:netherite_ranger_armor_legs', 'archers:netherite_ranger_armor_feet'],
    ['rogues:netherite_assassin_armor_head', 'rogues:netherite_assassin_armor_chest', 'rogues:netherite_assassin_armor_legs', 'rogues:netherite_assassin_armor_feet'],
    ['rogues:netherite_berserker_armor_head', 'rogues:netherite_berserker_armor_chest', 'rogues:netherite_berserker_armor_legs', 'rogues:netherite_berserker_armor_feet'],
    ['paladins:netherite_crusader_armor_head', 'paladins:netherite_crusader_armor_chest', 'paladins:netherite_crusader_armor_legs', 'paladins:netherite_crusader_armor_feet'],
    ['wizards:netherite_arcane_robe_head', 'wizards:netherite_arcane_robe_chest', 'wizards:netherite_arcane_robe_legs', 'wizards:netherite_arcane_robe_feet'],
    ['wizards:netherite_fire_robe_head', 'wizards:netherite_fire_robe_chest', 'wizards:netherite_fire_robe_legs', 'wizards:netherite_fire_robe_feet'],
    ['wizards:netherite_frost_robe_head', 'wizards:netherite_frost_robe_chest', 'wizards:netherite_frost_robe_legs', 'wizards:netherite_frost_robe_feet'],
    ['elemental_wizards_rpg:netherite_kelp_head', 'elemental_wizards_rpg:netherite_kelp_chest', 'elemental_wizards_rpg:netherite_kelp_legs', 'elemental_wizards_rpg:netherite_kelp_feet'],
    ['elemental_wizards_rpg:netherite_wind_head', 'elemental_wizards_rpg:netherite_wind_chest', 'elemental_wizards_rpg:netherite_wind_legs', 'elemental_wizards_rpg:netherite_wind_feet'],
    ['bards_rpg:netherite_troubadour_garb_head', 'bards_rpg:netherite_troubadour_garb_chest', 'bards_rpg:netherite_troubadour_garb_legs', 'bards_rpg:netherite_troubadour_garb_feet'],
    ['berserker_rpg:netherite_northling_head', 'berserker_rpg:netherite_northling_chest', 'berserker_rpg:netherite_northling_legs', 'berserker_rpg:netherite_northling_feet'],
    ['archers_expansion:netherite_deadeye_head', 'archers_expansion:netherite_deadeye_chest', 'archers_expansion:netherite_deadeye_legs', 'archers_expansion:netherite_deadeye_feet'],
    ['archers_expansion:netherite_tundra_hunter_head', 'archers_expansion:netherite_tundra_hunter_chest', 'archers_expansion:netherite_tundra_hunter_legs', 'archers_expansion:netherite_tundra_hunter_feet'],
    ['archers_expansion:netherite_war_archer_head', 'archers_expansion:netherite_war_archer_chest', 'archers_expansion:netherite_war_archer_legs', 'archers_expansion:netherite_war_archer_feet']
  ] }
];

var CUNIMOB_BREAKABLE_BLOCKS = [
  'minecraft:acacia_door', 'minecraft:acacia_fence', 'minecraft:acacia_fence_gate', 'minecraft:acacia_leaves', 'minecraft:acacia_log', 'minecraft:acacia_planks', 'minecraft:acacia_trapdoor', 'minecraft:acacia_wood',
  'minecraft:andesite', 'minecraft:bamboo_block', 'minecraft:bamboo_door', 'minecraft:bamboo_fence', 'minecraft:bamboo_fence_gate', 'minecraft:bamboo_mosaic', 'minecraft:bamboo_planks', 'minecraft:bamboo_trapdoor',
  'minecraft:basalt', 'minecraft:birch_door', 'minecraft:birch_fence', 'minecraft:birch_fence_gate', 'minecraft:birch_leaves', 'minecraft:birch_log', 'minecraft:birch_planks', 'minecraft:birch_trapdoor', 'minecraft:birch_wood',
  'minecraft:blackstone', 'minecraft:calcite', 'minecraft:cherry_door', 'minecraft:cherry_fence', 'minecraft:cherry_fence_gate', 'minecraft:cherry_leaves', 'minecraft:cherry_log', 'minecraft:cherry_planks', 'minecraft:cherry_trapdoor', 'minecraft:cherry_wood',
  'minecraft:clay', 'minecraft:cobbled_deepslate', 'minecraft:cobblestone', 'minecraft:coarse_dirt', 'minecraft:crimson_door', 'minecraft:crimson_fence', 'minecraft:crimson_fence_gate', 'minecraft:crimson_hyphae', 'minecraft:crimson_planks', 'minecraft:crimson_stem', 'minecraft:crimson_trapdoor',
  'minecraft:dark_oak_door', 'minecraft:dark_oak_fence', 'minecraft:dark_oak_fence_gate', 'minecraft:dark_oak_leaves', 'minecraft:dark_oak_log', 'minecraft:dark_oak_planks', 'minecraft:dark_oak_trapdoor', 'minecraft:dark_oak_wood',
  'minecraft:deepslate', 'minecraft:diorite', 'minecraft:dirt', 'minecraft:dripstone_block', 'minecraft:glass', 'minecraft:glass_pane', 'minecraft:granite', 'minecraft:grass_block', 'minecraft:gravel', 'minecraft:jungle_door', 'minecraft:jungle_fence', 'minecraft:jungle_fence_gate', 'minecraft:jungle_leaves', 'minecraft:jungle_log', 'minecraft:jungle_planks', 'minecraft:jungle_trapdoor', 'minecraft:jungle_wood',
  'minecraft:mangrove_door', 'minecraft:mangrove_fence', 'minecraft:mangrove_fence_gate', 'minecraft:mangrove_leaves', 'minecraft:mangrove_log', 'minecraft:mangrove_planks', 'minecraft:mangrove_roots', 'minecraft:mangrove_trapdoor', 'minecraft:mangrove_wood',
  'minecraft:mossy_cobblestone', 'minecraft:mud', 'minecraft:mud_bricks', 'minecraft:muddy_mangrove_roots', 'minecraft:netherrack', 'minecraft:obsidian', 'minecraft:crying_obsidian', 'minecraft:oak_door', 'minecraft:oak_fence', 'minecraft:oak_fence_gate', 'minecraft:oak_leaves', 'minecraft:oak_log', 'minecraft:oak_planks', 'minecraft:oak_trapdoor', 'minecraft:oak_wood',
  'minecraft:packed_mud', 'minecraft:red_sand', 'minecraft:rooted_dirt', 'minecraft:sand', 'minecraft:smooth_basalt', 'minecraft:spruce_door', 'minecraft:spruce_fence', 'minecraft:spruce_fence_gate', 'minecraft:spruce_leaves', 'minecraft:spruce_log', 'minecraft:spruce_planks', 'minecraft:spruce_trapdoor', 'minecraft:spruce_wood',
  'minecraft:stone', 'minecraft:tuff', 'minecraft:warped_door', 'minecraft:warped_fence', 'minecraft:warped_fence_gate', 'minecraft:warped_hyphae', 'minecraft:warped_planks', 'minecraft:warped_stem', 'minecraft:warped_trapdoor'
];

var CUNIMOB_RPG_CATEGORY_DROPS = [
  { min: 8, rarity: 'INCOMUN', apoth: 'uncommon', chance: 0.0120, cap: 0.0340, item: `minecraft:iron_hoe[custom_name='{"text":"Azada del Brote de Guardia","color":"green","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"guardia",cuniculum_kind:"tool",cuniculum_tool:"farm",cuniculum_trait:"cosechador"},enchantments={levels:{"minecraft:fortune":1,"minecraft:unbreaking":2},show_in_tooltip:true}]` },
  { min: 12, rarity: 'INCOMUN', apoth: 'uncommon', chance: 0.0100, cap: 0.0300, item: `minecraft:fishing_rod[custom_name='{"text":"Cana del Arroyo de Madriguera","color":"green","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"guardia",cuniculum_kind:"tool",cuniculum_tool:"fish",cuniculum_trait:"prospero",cuniculum_trait2:"pescador"},enchantments={levels:{"minecraft:luck_of_the_sea":2,"minecraft:lure":1,"minecraft:unbreaking":2},show_in_tooltip:true}]` },
  { min: 14, rarity: 'INCOMUN', apoth: 'uncommon', chance: 0.0038, cap: 0.0100, item: `artifacts:bunny_hoppers[custom_name='{"text":"Botas de Brinco Cunicular","color":"green","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"guardia",cuniculum_kind:"artifact",cuniculum_artifact:"movement",cuniculum_trait:"salto"},lore=['{"text":"Reliquia menor: ideal para escapar de una mala pelea.","color":"gray","italic":false}']]` },
  { min: 18, rarity: 'RARO', apoth: 'rare', chance: 0.0032, cap: 0.0085, item: `artifacts:feral_claws[custom_name='{"text":"Garras de Conejo del Prado","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"artifact",cuniculum_artifact:"combat",cuniculum_trait:"velocidad"},lore=['{"text":"Cada golpe despierta el instinto de la madriguera.","color":"gray","italic":false}']]` },
  { min: 18, rarity: 'RARO', apoth: 'rare', chance: 0.0100, cap: 0.0300, item: `minecraft:iron_pickaxe[custom_name='{"text":"Pico de Tunel Despierto","color":"green","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"guardia",cuniculum_kind:"tool",cuniculum_tool:"miner"},enchantments={levels:{"minecraft:efficiency":3,"minecraft:fortune":1,"minecraft:unbreaking":2},show_in_tooltip:true}]` },
  { min: 18, rarity: 'RARO', apoth: 'rare', chance: 0.0090, cap: 0.0280, item: `archers:iron_spear[custom_name='{"text":"Lanza del Guardia Orejudo","color":"green","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"guardia",cuniculum_kind:"weapon",cuniculum_family:"spear"},enchantments={levels:{"minecraft:sharpness":3,"minecraft:unbreaking":2},show_in_tooltip:true}]` },
  { min: 22, rarity: 'RARO', apoth: 'rare', chance: 0.0085, cap: 0.0240, item: `minecraft:diamond_shovel[custom_name='{"text":"Pala del Camino Bajo","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"tool",cuniculum_tool:"dig",cuniculum_mining_shape:"1x3",cuniculum_trait:"excavador",cuniculum_trait2:"fundidor"},enchantments={levels:{"minecraft:efficiency":4,"minecraft:fortune":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 24, rarity: 'RARO', apoth: 'rare', chance: 0.0028, cap: 0.0075, item: `artifacts:digging_claws[custom_name='{"text":"Garras Excavadoras de Madriguera","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"artifact",cuniculum_artifact:"utility",cuniculum_trait:"tunelero"},lore=['{"text":"Un premio para quienes viven abriendo senderos bajo tierra.","color":"gray","italic":false}']]` },
  { min: 25, rarity: 'AZUL', apoth: 'rare', chance: 0.0075, cap: 0.0220, item: `minecraft:bow[custom_name='{"text":"Arco de Orejas Ligeras","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"weapon",cuniculum_family:"bow"},enchantments={levels:{"minecraft:power":4,"minecraft:unbreaking":3,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 25, rarity: 'AZUL', apoth: 'rare', chance: 0.0065, cap: 0.0200, item: `rogues:diamond_dagger[custom_name='{"text":"Daga del Salto Bajo","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"weapon",cuniculum_family:"dagger"},enchantments={levels:{"minecraft:sharpness":4,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 26, rarity: 'RARO', apoth: 'rare', chance: 0.0055, cap: 0.0160, item: `archers:ranger_armor_head[custom_name='{"text":"Capucha del Vigia de Arroyo","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"armor",cuniculum_set:"explorador",cuniculum_trait:"vigia",cuniculum_trait2:"respirador"},enchantments={levels:{"minecraft:protection":3,"minecraft:respiration":3,"minecraft:aqua_affinity":1,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 28, rarity: 'RARO', apoth: 'rare', chance: 0.0050, cap: 0.0150, item: `rogues:rogue_armor_legs[custom_name='{"text":"Pantalones de Sombra Ligera","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"armor",cuniculum_set:"explorador",cuniculum_trait:"ligero",cuniculum_trait2:"zancada"},enchantments={levels:{"minecraft:protection":3,"minecraft:swift_sneak":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 30, rarity: 'RARO', apoth: 'rare', chance: 0.0024, cap: 0.0065, item: `artifacts:panic_necklace[custom_name='{"text":"Collar de Huida Cunicular","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"artifact",cuniculum_artifact:"survival",cuniculum_trait:"huida"},lore=['{"text":"Para sobrevivir cuando la cueva decide cerrar la salida.","color":"gray","italic":false}']]` },
  { min: 34, rarity: 'RARO', apoth: 'rare', chance: 0.0022, cap: 0.0060, item: `artifacts:running_shoes[custom_name='{"text":"Zapatillas de Carrera Cunicular","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"artifact",cuniculum_artifact:"movement",cuniculum_trait:"zancada"},lore=['{"text":"La pradera premia al que sabe correr antes de pelear.","color":"gray","italic":false}']]` },
  { min: 32, rarity: 'RARO', apoth: 'rare', chance: 0.0045, cap: 0.0130, item: `wizards:wizard_robe_chest[custom_name='{"text":"Tunica de Bruma Cunicular","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"armor",cuniculum_set:"explorador",cuniculum_trait:"arcano",cuniculum_trait2:"termico"},enchantments={levels:{"minecraft:protection":3,"extraspellattributes:warding":3,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 35, rarity: 'EPICO', apoth: 'epic', chance: 0.0040, cap: 0.0120, item: `minecraft:diamond_pickaxe[custom_name='{"text":"Pico de Botin Profundo","color":"aqua","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"tool",cuniculum_tool:"miner",cuniculum_trait:"fundidor"},enchantments={levels:{"minecraft:efficiency":5,"minecraft:fortune":3,"minecraft:unbreaking":3,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 35, rarity: 'EPICO', apoth: 'epic', chance: 0.0038, cap: 0.0110, item: `minecraft:diamond_axe[custom_name='{"text":"Hacha del Bosque de Cristal","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"tool",cuniculum_tool:"wood",cuniculum_mining_shape:"1x3",cuniculum_trait:"lenador",cuniculum_trait2:"devastador"},enchantments={levels:{"minecraft:efficiency":5,"minecraft:sharpness":4,"minecraft:unbreaking":3,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 38, rarity: 'EPICO', apoth: 'epic', chance: 0.0018, cap: 0.0048, item: `artifacts:crystal_heart[custom_name='{"text":"Corazón de Cristal de Madriguera","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"survival",cuniculum_trait:"vida"},lore=['{"text":"Un núcleo de refugio para quienes vuelven heridos.","color":"gray","italic":false}']]` },
  { min: 40, rarity: 'EPICO', apoth: 'epic', chance: 0.0017, cap: 0.0046, item: `artifacts:lucky_scarf[custom_name='{"text":"Bufanda de la Suerte del Prado","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"fortune",cuniculum_trait:"prospero"},lore=['{"text":"El botin siempre parece caer del lado del que la porta.","color":"gray","italic":false}']]` },
  { min: 42, rarity: 'EPICO', apoth: 'epic', chance: 0.0015, cap: 0.0040, item: `artifacts:vampiric_glove[custom_name='{"text":"Guante Vampirico del Refugio","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"combat",cuniculum_trait:"sangre"},lore=['{"text":"No todo salto vuelve limpio de la batalla.","color":"gray","italic":false}']]` },
  { min: 35, rarity: 'EPICO', apoth: 'epic', chance: 0.0034, cap: 0.0100, item: `archers:royal_longbow[custom_name='{"text":"Arco Largo del Vigia Lunar","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"weapon",cuniculum_family:"bow"},enchantments={levels:{"minecraft:power":5,"minecraft:infinity":1,"minecraft:mending":1,"minecraft:punch":1,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 35, rarity: 'EPICO', apoth: 'epic', chance: 0.0030, cap: 0.0090, item: `elemental_wizards_rpg:staff_aqua[custom_name='{"text":"Baston de Agua de Madriguera","color":"aqua","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"weapon",cuniculum_family:"staff"},enchantments={levels:{"minecraft:unbreaking":3,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 45, rarity: 'EPICO', apoth: 'epic', chance: 0.0024, cap: 0.0070, item: `minecraft:trident[custom_name='{"text":"Tridente del Arroyo Profundo","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"weapon",cuniculum_family:"spear",cuniculum_trait:"pescador",cuniculum_trait2:"devastador"},enchantments={levels:{"minecraft:impaling":5,"minecraft:loyalty":3,"minecraft:unbreaking":3,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 45, rarity: 'EPICO', apoth: 'epic', chance: 0.0027, cap: 0.0080, item: `archers:archer_armor_feet[custom_name='{"text":"Botas del Salto de Flecha","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"armor",cuniculum_set:"vigia",cuniculum_trait:"pluma",cuniculum_trait2:"salto"},enchantments={levels:{"minecraft:protection":3,"minecraft:feather_falling":3,"minecraft:depth_strider":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 48, rarity: 'EPICO', apoth: 'epic', chance: 0.0023, cap: 0.0070, item: `paladins:paladin_armor_chest[custom_name='{"text":"Pechera del Refugio Solar","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"armor",cuniculum_set:"vigia",cuniculum_trait:"baluarte",cuniculum_trait2:"ignifugo"},enchantments={levels:{"minecraft:protection":3,"minecraft:fire_protection":3,"extraspellattributes:warding":3,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 50, rarity: 'EPICO', apoth: 'epic', chance: 0.0012, cap: 0.0034, item: `artifacts:fire_gauntlet[custom_name='{"text":"Guantelete de Brasa Cunicular","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"combat",cuniculum_trait:"ignifugo"},lore=['{"text":"La brasa tambien sabe proteger una madriguera.","color":"gray","italic":false}']]` },
  { min: 52, rarity: 'EPICO', apoth: 'epic', chance: 0.0011, cap: 0.0032, item: `artifacts:shock_pendant[custom_name='{"text":"Colgante de Trueno del Prado","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"retaliation",cuniculum_trait:"trueno"},lore=['{"text":"Cada golpe recibido puede responder con cielo roto.","color":"gray","italic":false}']]` },
  { min: 52, rarity: 'EPICO', apoth: 'epic', chance: 0.0019, cap: 0.0060, item: `wizards:frost_robe_chest[custom_name='{"text":"Tunica de Escarcha del Prado","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"armor",cuniculum_set:"vigia",cuniculum_trait:"escarcha",cuniculum_trait2:"termico"},enchantments={levels:{"minecraft:protection":3,"minecraft:blast_protection":2,"extraspellattributes:warding":3,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 54, rarity: 'EPICO', apoth: 'epic', chance: 0.0010, cap: 0.0030, item: `artifacts:thorn_pendant[custom_name='{"text":"Colgante de Zarzas de Madriguera","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"artifact",cuniculum_artifact:"retaliation",cuniculum_trait:"veneno"},lore=['{"text":"Quien muerde la pradera aprende de sus espinas.","color":"gray","italic":false}']]` },
  { min: 56, rarity: 'MITICO', apoth: 'mythic', chance: 0.00070, cap: 0.0020, item: `artifacts:obsidian_skull[custom_name='{"text":"Cráneo de Obsidiana del Refugio","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"artifact",cuniculum_artifact:"defense",cuniculum_trait:"ignifugo"},lore=['{"text":"La madriguera negra no teme al fuego.","color":"gray","italic":false}']]` },
  { min: 55, rarity: 'MITICO', apoth: 'mythic', chance: 0.0016, cap: 0.0050, item: `archers:netherite_rapid_crossbow[custom_name='{"text":"Ballesta del Tunel Negro","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"weapon",cuniculum_family:"crossbow"},enchantments={levels:{"minecraft:quick_charge":4,"minecraft:piercing":5,"minecraft:mending":1,"minecraft:unbreaking":4},show_in_tooltip:true}]` },
  { min: 55, rarity: 'MITICO', apoth: 'mythic', chance: 0.0014, cap: 0.0045, item: `paladins:netherite_great_hammer[custom_name='{"text":"Martillo del Conejo Negro","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"weapon",cuniculum_family:"heavy"},enchantments={levels:{"minecraft:sharpness":5,"minecraft:knockback":2,"minecraft:unbreaking":4,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 55, rarity: 'MITICO', apoth: 'mythic', chance: 0.0012, cap: 0.0040, item: `minecraft:netherite_boots[custom_name='{"text":"Botas del Salto Jurado","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"armor",cuniculum_set:"juramento"},enchantments={levels:{"minecraft:protection":4,"minecraft:thorns":2,"minecraft:feather_falling":3,"extraspellattributes:warding":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 65, rarity: 'MITICO', apoth: 'mythic', chance: 0.00090, cap: 0.0028, item: `minecraft:netherite_axe[custom_name='{"text":"Hacha del Roble Sepultado","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"tool",cuniculum_tool:"wood",cuniculum_mining_shape:"2x2",cuniculum_trait:"lenador",cuniculum_trait2:"baluarte",cuniculum_trait3:"fundidor"},enchantments={levels:{"minecraft:efficiency":6,"minecraft:sharpness":5,"minecraft:unbreaking":4,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 68, rarity: 'MITICO', apoth: 'mythic', chance: 0.00062, cap: 0.0020, item: `rogues:netherite_assassin_armor_feet[custom_name='{"text":"Botas del Paso Sin Luna","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"armor",cuniculum_set:"juramento",cuniculum_trait:"bruma",cuniculum_trait2:"pluma",cuniculum_trait3:"salto"},enchantments={levels:{"minecraft:protection":4,"minecraft:feather_falling":4,"minecraft:soul_speed":2,"minecraft:unbreaking":3,"extraspellattributes:warding":3},show_in_tooltip:true}]` },
  { min: 70, rarity: 'MITICO', apoth: 'mythic', chance: 0.00070, cap: 0.0022, item: `wizards:staff_netherite_arcane[custom_name='{"text":"Baston Arcano del Refugio Negro","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"weapon",cuniculum_family:"staff",cuniculum_trait:"arcano",cuniculum_trait2:"prismal"},enchantments={levels:{"minecraft:unbreaking":4,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 72, rarity: 'MITICO', apoth: 'mythic', chance: 0.00055, cap: 0.0018, item: `paladins:netherite_crusader_armor_chest[custom_name='{"text":"Coraza del Santuario de Raices","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"armor",cuniculum_set:"juramento",cuniculum_trait:"baluarte",cuniculum_trait2:"ignifugo",cuniculum_trait3:"prismal"},enchantments={levels:{"minecraft:protection":4,"minecraft:fire_protection":4,"minecraft:thorns":3,"extraspellattributes:warding":4,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 76, rarity: 'MITICO', apoth: 'mythic', chance: 0.00045, cap: 0.0015, item: `wizards:netherite_frost_robe_head[custom_name='{"text":"Capucha de Nieve Subterranea","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"armor",cuniculum_set:"juramento",cuniculum_trait:"vigia",cuniculum_trait2:"respirador",cuniculum_trait3:"escarcha"},enchantments={levels:{"minecraft:protection":4,"minecraft:respiration":3,"minecraft:aqua_affinity":1,"extraspellattributes:warding":4,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 78, rarity: 'MITICO', apoth: 'mythic', chance: 0.00020, cap: 0.00070, item: `artifacts:warp_drive[custom_name='{"text":"Impulsor Ender Cunicular","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"artifact",cuniculum_artifact:"mobility",cuniculum_trait:"ender"},lore=['{"text":"Un salto tan profundo que parece romper el mundo.","color":"gray","italic":false}']]` },
  { min: 82, rarity: 'MITICO', apoth: 'mythic', chance: 0.00018, cap: 0.00062, item: `artifacts:chorus_totem[custom_name='{"text":"Tótem del Salto de Coro","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"artifact",cuniculum_artifact:"survival",cuniculum_trait:"tiempo"},lore=['{"text":"Cuando todo sale mal, la madriguera intenta devolverte.","color":"gray","italic":false}']]` },
  { min: 80, rarity: 'MITICO', apoth: 'mythic', chance: 0.00012, cap: 0.00042, item: `archers:netherite_longbow[custom_name='{"text":"Reliquia Cunicular: Arco del Salto Eterno","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"weapon",cuniculum_family:"bow"},enchantments={levels:{"minecraft:power":7,"minecraft:infinity":1,"minecraft:mending":1,"minecraft:punch":2,"minecraft:flame":1,"minecraft:unbreaking":5},show_in_tooltip:true}]` },
  { min: 80, rarity: 'MITICO', apoth: 'mythic', chance: 0.00011, cap: 0.00038, item: `elemental_wizards_rpg:staff_netherite_wind[custom_name='{"text":"Reliquia Cunicular: Viento del Refugio Alto","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"weapon",cuniculum_family:"staff",cuniculum_trait:"aereo",cuniculum_trait2:"arcano"},enchantments={levels:{"minecraft:unbreaking":5,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 80, rarity: 'MITICO', apoth: 'mythic', chance: 0.00011, cap: 0.00038, item: `forcemaster_rpg:netherite_knuckle[custom_name='{"text":"Reliquia Cunicular: Nudillos del Salto","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"weapon",cuniculum_family:"knuckle",cuniculum_trait:"salto",cuniculum_trait2:"cazador"},enchantments={levels:{"minecraft:sharpness":7,"minecraft:knockback":3,"minecraft:unbreaking":5,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 90, rarity: 'MITICO', apoth: 'mythic', chance: 0.00010, cap: 0.00035, item: `minecraft:netherite_pickaxe[custom_name='{"text":"Pico Mitico del Subsuelo Vivo","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"tool",cuniculum_tool:"miner",cuniculum_mining_shape:"3x3",cuniculum_trait:"tunelero",cuniculum_trait2:"prospero",cuniculum_trait3:"fundidor"},enchantments={levels:{"minecraft:efficiency":7,"minecraft:fortune":4,"minecraft:unbreaking":5,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 95, rarity: 'MITICO', apoth: 'mythic', chance: 0.00008, cap: 0.00025, item: `minecraft:netherite_hoe[custom_name='{"text":"Reliquia Cunicular: Azada de Luna Viva","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"tool",cuniculum_tool:"farm",cuniculum_trait:"cosechador",cuniculum_trait2:"prospero",cuniculum_trait3:"eco_pradera"},enchantments={levels:{"minecraft:efficiency":7,"minecraft:fortune":4,"minecraft:unbreaking":5,"minecraft:mending":1},show_in_tooltip:true}]` }
];

CUNIMOB_RPG_CATEGORY_DROPS.push(
  { min: 32, rarity: 'RARO', apoth: 'rare', chance: 0.0022, cap: 0.0060, item: `archers_expansion:deadeye_chest[custom_name='{"text":"Tunica de Ojo de Madriguera","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"armor",cuniculum_set:"deadeye",cuniculum_trait:"cazador",cuniculum_trait2:"zancada"},enchantments={levels:{"minecraft:projectile_protection":3,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 38, rarity: 'EPICO', apoth: 'epic', chance: 0.0016, cap: 0.0048, item: `archers_expansion:tundra_hunter_head[custom_name='{"text":"Capucha del Cazador Nevado","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"armor",cuniculum_set:"tundra",cuniculum_trait:"escarcha",cuniculum_trait2:"vigia"},enchantments={levels:{"minecraft:protection":3,"minecraft:respiration":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 48, rarity: 'EPICO', apoth: 'epic', chance: 0.0013, cap: 0.0040, item: `oritech:electric_mace[custom_name='{"text":"Maza Electrica del Nido","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"weapon",cuniculum_family:"heavy",cuniculum_trait:"trueno"},enchantments={levels:{"minecraft:sharpness":4,"minecraft:knockback":2,"minecraft:unbreaking":3},show_in_tooltip:true}]` },
  { min: 58, rarity: 'MITICO', apoth: 'mythic', chance: 0.00042, cap: 0.0014, item: `oritech:hand_drill[custom_name='{"text":"Taladro del Corazon Bajo","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"tool",cuniculum_tool:"miner",cuniculum_mining_shape:"2x3",cuniculum_trait:"tunelero",cuniculum_trait2:"fundidor"},enchantments={levels:{"minecraft:efficiency":5,"minecraft:fortune":3,"minecraft:unbreaking":4,"minecraft:mending":1},show_in_tooltip:true}]` },
  { min: 68, rarity: 'MITICO', apoth: 'mythic', chance: 0.00034, cap: 0.0011, item: `archers_expansion:netherite_war_archer_chest[custom_name='{"text":"Coraza Abisal del Arquero de Guardia","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"armor",cuniculum_set:"war_archer",cuniculum_trait:"baluarte",cuniculum_trait2:"cazador"},enchantments={levels:{"minecraft:protection":4,"minecraft:projectile_protection":4,"minecraft:thorns":3,"minecraft:unbreaking":4},show_in_tooltip:true}]` },
  { min: 86, rarity: 'MITICO', apoth: 'mythic', chance: 0.00007, cap: 0.00022, item: `oritech:promethium_pickaxe[custom_name='{"text":"Reliquia Cunicular: Pico Promethium del Alba","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"tool",cuniculum_tool:"miner",cuniculum_mining_shape:"3x3",cuniculum_trait:"tunelero",cuniculum_trait2:"prospero",cuniculum_trait3:"fundidor"},enchantments={levels:{"minecraft:efficiency":7,"minecraft:fortune":4,"minecraft:unbreaking":5,"minecraft:mending":1},show_in_tooltip:true}]` }
);

var CUNIMOB_RPG_LOOT_TIERS = [
  {
    min: 1, key: 'madriguera', label: 'Madriguera', color: 'gray',
    armorChance: 0.018, weaponChance: 0.018, toolChance: 0.014, enchantChance: 0.10, maxEnchant: 1,
    armor: [
      { id: 'minecraft:leather_helmet', name: 'Capucha de Madriguera' },
      { id: 'minecraft:leather_chestplate', name: 'Chaleco de Madriguera' },
      { id: 'minecraft:leather_leggings', name: 'Pantalones de Madriguera' },
      { id: 'minecraft:leather_boots', name: 'Botas de Madriguera' },
      { id: 'bards_rpg:entertainer_garb_head', name: 'Sombrero de Cuentacantos Bajo' },
      { id: 'bards_rpg:entertainer_garb_chest', name: 'Chaqueta de Cuentacantos Bajo' },
      { id: 'bards_rpg:entertainer_garb_legs', name: 'Pantalones de Cuentacantos Bajo' },
      { id: 'bards_rpg:entertainer_garb_feet', name: 'Zapatos de Cuentacantos Bajo' },
      { id: 'berserker_rpg:wildling_head', name: 'Capucha Salvaje de Raiz' },
      { id: 'berserker_rpg:wildling_chest', name: 'Abrigo Salvaje de Raiz' },
      { id: 'berserker_rpg:wildling_legs', name: 'Grebas Salvajes de Raiz' },
      { id: 'berserker_rpg:wildling_feet', name: 'Botas Salvajes de Raiz' }
    ],
    tools: [
      { id: 'minecraft:stone_pickaxe', name: 'Pico de Primer Tunel', role: 'miner' },
      { id: 'minecraft:stone_axe', name: 'Hacha de Rama Vieja', role: 'wood' },
      { id: 'minecraft:stone_shovel', name: 'Pala de Tierra Suelta', role: 'dig' },
      { id: 'minecraft:stone_hoe', name: 'Azada de Brote Bajo', role: 'farm' }
    ],
    weapons: [
      { id: 'minecraft:stone_sword', name: 'Colmillo de Madriguera Baja' },
      { id: 'minecraft:stone_axe', name: 'Garrita de Guardia Baja' },
      { id: 'rogues:flint_dagger', name: 'Daga de Zanahoria Astillada' },
      { id: 'berserker_rpg:stone_berserker_axe', name: 'Hacha de Oreja Pétrea' }
    ]
  },
  {
    min: 8, key: 'guardia', label: 'Guardia del Tunel', color: 'green',
    armorChance: 0.026, weaponChance: 0.026, toolChance: 0.020, enchantChance: 0.22, maxEnchant: 2,
    armor: [
      { id: 'minecraft:chainmail_helmet', name: 'Yelmo del Guardia del Tunel' },
      { id: 'minecraft:chainmail_chestplate', name: 'Cota del Guardia del Tunel' },
      { id: 'minecraft:chainmail_leggings', name: 'Grebas del Guardia del Tunel' },
      { id: 'minecraft:chainmail_boots', name: 'Botas del Guardia del Tunel' },
      { id: 'archers:archer_armor_head', name: 'Capucha del Arquero de Prado' },
      { id: 'archers:archer_armor_chest', name: 'Jubón del Arquero de Prado' },
      { id: 'archers:archer_armor_legs', name: 'Pantalones del Arquero de Prado' },
      { id: 'archers:archer_armor_feet', name: 'Botas del Arquero de Prado' },
      { id: 'rogues:rogue_armor_head', name: 'Capucha del Salto Sigiloso' },
      { id: 'rogues:rogue_armor_chest', name: 'Chaleco del Salto Sigiloso' },
      { id: 'rogues:rogue_armor_legs', name: 'Pantalones del Salto Sigiloso' },
      { id: 'rogues:rogue_armor_feet', name: 'Botas del Salto Sigiloso' },
      { id: 'wizards:wizard_robe_head', name: 'Capucha de Polvo Arcano' },
      { id: 'wizards:wizard_robe_chest', name: 'Túnica de Polvo Arcano' },
      { id: 'wizards:wizard_robe_legs', name: 'Falda de Polvo Arcano' },
      { id: 'wizards:wizard_robe_feet', name: 'Sandalias de Polvo Arcano' }
    ],
    tools: [
      { id: 'minecraft:iron_pickaxe', name: 'Pico de Veta Tibia', role: 'miner' },
      { id: 'minecraft:iron_axe', name: 'Hacha de Lena Rapida', role: 'wood' },
      { id: 'minecraft:iron_shovel', name: 'Pala de Zanja Firme', role: 'dig' },
      { id: 'minecraft:iron_hoe', name: 'Azada de Guardia Verde', role: 'farm' },
      { id: 'minecraft:fishing_rod', name: 'Cana del Arroyo Bajo', role: 'fish' }
    ],
    weapons: [
      { id: 'minecraft:iron_sword', name: 'Espada de Guardia Orejuda' },
      { id: 'minecraft:iron_axe', name: 'Hacha del Tunel Verde' },
      { id: 'minecraft:bow', name: 'Arco de Salto Corto' },
      { id: 'archers:iron_spear', name: 'Lanza del Centinela de Madriguera' },
      { id: 'paladins:iron_mace', name: 'Maza de la Puerta Baja' },
      { id: 'rogues:iron_double_axe', name: 'Doble Hoja del Conejo Vigía' },
      { id: 'forcemaster_rpg:iron_knuckle', name: 'Nudillos del Túnel Cerrado' }
    ]
  },
  {
    min: 18, key: 'explorador', label: 'Explorador Profundo', color: 'blue',
    armorChance: 0.036, weaponChance: 0.036, toolChance: 0.028, enchantChance: 0.36, maxEnchant: 3,
    armor: [
      { id: 'minecraft:iron_helmet', name: 'Casco de Explorador Profundo' },
      { id: 'minecraft:iron_chestplate', name: 'Coraza de Explorador Profundo' },
      { id: 'minecraft:iron_leggings', name: 'Grebas de Explorador Profundo' },
      { id: 'minecraft:iron_boots', name: 'Botas de Explorador Profundo' },
      { id: 'archers:ranger_armor_head', name: 'Capucha del Vigía de Arroyo' },
      { id: 'archers:ranger_armor_chest', name: 'Chaleco del Vigía de Arroyo' },
      { id: 'archers:ranger_armor_legs', name: 'Pantalones del Vigía de Arroyo' },
      { id: 'archers:ranger_armor_feet', name: 'Botas del Vigía de Arroyo' },
      { id: 'paladins:paladin_armor_head', name: 'Yelmo del Refugio Solar' },
      { id: 'paladins:paladin_armor_chest', name: 'Pechera del Refugio Solar' },
      { id: 'paladins:paladin_armor_legs', name: 'Grebas del Refugio Solar' },
      { id: 'paladins:paladin_armor_feet', name: 'Botas del Refugio Solar' },
      { id: 'wizards:fire_robe_head', name: 'Capucha de Brasa Serena' },
      { id: 'wizards:fire_robe_chest', name: 'Túnica de Brasa Serena' },
      { id: 'wizards:frost_robe_head', name: 'Capucha de Escarcha Mansa' },
      { id: 'wizards:frost_robe_chest', name: 'Túnica de Escarcha Mansa' },
      { id: 'elemental_wizards_rpg:kelp_head', name: 'Capucha de Marea Oculta' },
      { id: 'elemental_wizards_rpg:kelp_chest', name: 'Capa de Marea Oculta' },
      { id: 'bards_rpg:storyteller_garb_chest', name: 'Chaqueta del Relato de Pradera' },
      { id: 'bards_rpg:storyteller_garb_feet', name: 'Botas del Relato de Pradera' }
    ],
    tools: [
      { id: 'minecraft:diamond_pickaxe', name: 'Pico de Mina Hambrienta', role: 'miner' },
      { id: 'minecraft:diamond_axe', name: 'Hacha de Raiz Partida', role: 'wood' },
      { id: 'minecraft:diamond_shovel', name: 'Pala de Camino Oculto', role: 'dig' },
      { id: 'minecraft:diamond_hoe', name: 'Azada de Pradera Profunda', role: 'farm' },
      { id: 'minecraft:fishing_rod', name: 'Cana de Lago Oculto', role: 'fish' }
    ],
    weapons: [
      { id: 'minecraft:diamond_sword', name: 'Filo del Saltador Azul' },
      { id: 'minecraft:bow', name: 'Arco de Brisa de Madriguera' },
      { id: 'rogues:diamond_dagger', name: 'Daga de Paso Silencioso' },
      { id: 'paladins:diamond_mace', name: 'Maza del Madriguero Errante' },
      { id: 'paladins:diamond_great_hammer', name: 'Gran Martillo de Galería' },
      { id: 'archers:diamond_spear', name: 'Lanza del Vigía Bajo' },
      { id: 'archers:composite_longbow', name: 'Arco Compuesto de Orejas Largas' },
      { id: 'wizards:staff_wizard', name: 'Bastón de Polvo Azul' },
      { id: 'forcemaster_rpg:diamond_knuckle', name: 'Nudillos del Explorador' }
    ]
  },
  {
    min: 35, key: 'vigia', label: 'Vigia de Cristal', color: 'dark_purple',
    armorChance: 0.050, weaponChance: 0.050, toolChance: 0.038, enchantChance: 0.56, maxEnchant: 4,
    armor: [
      { id: 'minecraft:diamond_helmet', name: 'Casco del Vigia de Cristal' },
      { id: 'minecraft:diamond_chestplate', name: 'Coraza del Vigia de Cristal' },
      { id: 'minecraft:diamond_leggings', name: 'Grebas del Vigia de Cristal' },
      { id: 'minecraft:diamond_boots', name: 'Botas del Vigia de Cristal' },
      { id: 'rogues:assassin_armor_head', name: 'Capucha de Bruma Baja' },
      { id: 'rogues:assassin_armor_chest', name: 'Chaleco de Bruma Baja' },
      { id: 'rogues:assassin_armor_legs', name: 'Pantalones de Bruma Baja' },
      { id: 'rogues:assassin_armor_feet', name: 'Botas de Bruma Baja' },
      { id: 'paladins:crusader_armor_head', name: 'Yelmo del Santuario de Cristal' },
      { id: 'paladins:crusader_armor_chest', name: 'Coraza del Santuario de Cristal' },
      { id: 'paladins:prior_robe_chest', name: 'Túnica del Prior de Galería' },
      { id: 'bards_rpg:troubadour_garb_chest', name: 'Chaqueta del Trovador Lunar' },
      { id: 'elemental_wizards_rpg:hurricane_robe_chest', name: 'Túnica de Brisa Alta' },
      { id: 'elemental_wizards_rpg:ocean_robe_chest', name: 'Túnica del Arroyo Profundo' },
      { id: 'forcemaster_rpg:oriene_chest', name: 'Pechera de Pulso Oculto' },
      { id: 'berserker_rpg:northling_chest', name: 'Abrigo del Norte Bajo' }
    ],
    tools: [
      { id: 'minecraft:diamond_pickaxe', name: 'Pico de Coccion Profunda', role: 'miner' },
      { id: 'minecraft:diamond_axe', name: 'Hacha de Bosque Claro', role: 'wood' },
      { id: 'minecraft:diamond_hoe', name: 'Azada de Cosecha Serena', role: 'farm' }
    ],
    weapons: [
      { id: 'minecraft:diamond_sword', name: 'Filo del Vigía de Cristal' },
      { id: 'minecraft:crossbow', name: 'Ballesta del Vigía de Cristal' },
      { id: 'rogues:diamond_double_axe', name: 'Doble Hacha del Vigía' },
      { id: 'paladins:diamond_great_hammer', name: 'Gran Martillo del Vigía' },
      { id: 'archers:royal_longbow', name: 'Arco Largo de Cristal Lunar' },
      { id: 'archers:netherite_spear', name: 'Lanza Rubí del Vigía' },
      { id: 'wizards:staff_arcane', name: 'Bastón Arcano de Galería' },
      { id: 'elemental_wizards_rpg:staff_aqua', name: 'Bastón de Agua Bajo Tierra' },
      { id: 'forcemaster_rpg:diamond_knuckle', name: 'Nudillos Rubí del Vigía' }
    ]
  },
  {
    min: 55, key: 'juramento', label: 'Juramento de Sombra', color: 'gold',
    armorChance: 0.066, weaponChance: 0.064, toolChance: 0.050, enchantChance: 0.72, maxEnchant: 5,
    armor: [
      { id: 'minecraft:netherite_helmet', name: 'Yelmo del Juramento de Sombra' },
      { id: 'minecraft:netherite_chestplate', name: 'Coraza del Juramento de Sombra' },
      { id: 'minecraft:netherite_leggings', name: 'Grebas del Juramento de Sombra' },
      { id: 'minecraft:netherite_boots', name: 'Botas del Juramento de Sombra' },
      { id: 'archers:netherite_ranger_armor_head', name: 'Capucha del Juramento del Vigía' },
      { id: 'archers:netherite_ranger_armor_chest', name: 'Chaleco del Juramento del Vigía' },
      { id: 'rogues:netherite_assassin_armor_feet', name: 'Botas del Paso Sin Luna' },
      { id: 'rogues:netherite_assassin_armor_chest', name: 'Chaleco del Paso Sin Luna' },
      { id: 'paladins:netherite_crusader_armor_chest', name: 'Coraza del Santuario de Raíces' },
      { id: 'wizards:netherite_fire_robe_chest', name: 'Túnica de Brasa Jurada' },
      { id: 'wizards:netherite_frost_robe_head', name: 'Capucha de Nieve Subterránea' },
      { id: 'elemental_wizards_rpg:netherite_wind_chest', name: 'Túnica del Viento del Refugio' },
      { id: 'bards_rpg:netherite_troubadour_garb_chest', name: 'Chaqueta del Canto Eterno' },
      { id: 'berserker_rpg:netherite_northling_chest', name: 'Abrigo del Juramento Norte' }
    ],
    tools: [
      { id: 'minecraft:netherite_pickaxe', name: 'Pico del Horno Abisal', role: 'miner' },
      { id: 'minecraft:netherite_axe', name: 'Hacha de Corte Real', role: 'wood' },
      { id: 'minecraft:netherite_shovel', name: 'Pala del Camino Negro', role: 'dig' }
    ],
    weapons: [
      { id: 'minecraft:netherite_sword', name: 'Hoja del Juramento de Sombra' },
      { id: 'archers:netherite_longbow', name: 'Arco Largo del Juramento' },
      { id: 'archers:netherite_rapid_crossbow', name: 'Ballesta Rápida del Túnel Negro' },
      { id: 'berserker_rpg:netherite_berserker_axe', name: 'Hacha Berserker del Juramento' },
      { id: 'rogues:netherite_dagger', name: 'Daga del Juramento Silencioso' },
      { id: 'rogues:netherite_double_axe', name: 'Doble Hacha del Juramento' },
      { id: 'paladins:netherite_mace', name: 'Maza del Juramento Dorado' },
      { id: 'paladins:netherite_great_hammer', name: 'Gran Martillo del Conejo Negro' },
      { id: 'wizards:staff_netherite_arcane', name: 'Bastón Arcano del Juramento' },
      { id: 'elemental_wizards_rpg:staff_netherite_wind', name: 'Bastón de Viento Subterráneo' },
      { id: 'forcemaster_rpg:netherite_knuckle', name: 'Nudillos del Juramento' }
    ]
  },
  {
    min: 80, key: 'mitico', label: 'Mitico de CUNICULUM', color: 'gold',
    armorChance: 0.085, weaponChance: 0.082, toolChance: 0.064, enchantChance: 0.88, maxEnchant: 7,
    armor: [
      { id: 'minecraft:netherite_helmet', name: 'Corona Mitica de CUNICULUM' },
      { id: 'minecraft:netherite_chestplate', name: 'Peto Mitico de CUNICULUM' },
      { id: 'minecraft:netherite_leggings', name: 'Grebas Miticas de CUNICULUM' },
      { id: 'minecraft:netherite_boots', name: 'Botas Miticas de CUNICULUM' },
      { id: 'paladins:netherite_crusader_armor_head', name: 'Corona del Santuario Cunicular' },
      { id: 'paladins:netherite_crusader_armor_chest', name: 'Coraza del Santuario Cunicular' },
      { id: 'wizards:netherite_arcane_robe_chest', name: 'Túnica Arcana de CUNICULUM' },
      { id: 'wizards:netherite_frost_robe_chest', name: 'Túnica Glacial de CUNICULUM' },
      { id: 'rogues:netherite_berserker_armor_chest', name: 'Pechera de Sombra del Conejo Rojo' },
      { id: 'archers:netherite_ranger_armor_chest', name: 'Chaleco del Salto Eterno' },
      { id: 'elemental_wizards_rpg:netherite_kelp_chest', name: 'Capa de Marea Eterna' },
      { id: 'elemental_wizards_rpg:netherite_dripstone_chest', name: 'Pechera de Estalactita Viva' }
    ],
    tools: [
      { id: 'minecraft:netherite_pickaxe', name: 'Reliquia: Pico del Subsuelo Vivo', role: 'miner' },
      { id: 'minecraft:netherite_axe', name: 'Reliquia: Hacha de Raices Rojas', role: 'wood' },
      { id: 'minecraft:netherite_hoe', name: 'Reliquia: Azada de Luna Enterrada', role: 'farm' }
    ],
    weapons: [
      { id: 'archers:netherite_longbow', name: 'Reliquia Cunicular: Arco del Salto Eterno' },
      { id: 'archers:netherite_spear', name: 'Reliquia Cunicular: Lanza de Aeternium' },
      { id: 'archers:netherite_rapid_crossbow', name: 'Reliquia Cunicular: Ballesta del Alba' },
      { id: 'berserker_rpg:netherite_berserker_axe', name: 'Reliquia Cunicular: Hacha del Conejo Rojo' },
      { id: 'rogues:netherite_dagger', name: 'Reliquia Cunicular: Daga del Salto Ciego' },
      { id: 'rogues:netherite_double_axe', name: 'Reliquia Cunicular: Doble Hoja de Madriguera' },
      { id: 'paladins:netherite_mace', name: 'Reliquia Cunicular: Maza del Alba' },
      { id: 'paladins:netherite_great_hammer', name: 'Reliquia Cunicular: Martillo de la Reina Coneja' },
      { id: 'wizards:staff_netherite_arcane', name: 'Reliquia Cunicular: Bastón del Alba Eterna' },
      { id: 'elemental_wizards_rpg:staff_netherite_wind', name: 'Reliquia Cunicular: Bastón de Viento Aeternium' },
      { id: 'forcemaster_rpg:netherite_knuckle', name: 'Reliquia Cunicular: Nudillos del Salto' }
    ]
  }
];

function cunimobExtendLootTier(key, additions) {
  for (var i = 0; i < CUNIMOB_RPG_LOOT_TIERS.length; i++) {
    var tier = CUNIMOB_RPG_LOOT_TIERS[i];
    if (!tier || tier.key !== key) {
      continue;
    }
    if (additions.armor) {
      for (var a = 0; a < additions.armor.length; a++) tier.armor.push(additions.armor[a]);
    }
    if (additions.tools) {
      for (var t = 0; t < additions.tools.length; t++) tier.tools.push(additions.tools[t]);
    }
    if (additions.weapons) {
      for (var w = 0; w < additions.weapons.length; w++) tier.weapons.push(additions.weapons[w]);
    }
    return;
  }
}

cunimobExtendLootTier('explorador', {
  armor: [
    { id: 'archers_expansion:deadeye_head', name: 'Capucha de Ojo de Madriguera' },
    { id: 'archers_expansion:deadeye_chest', name: 'Tunica de Ojo de Madriguera' },
    { id: 'archers_expansion:tundra_hunter_head', name: 'Capucha del Cazador Nevado' },
    { id: 'archers_expansion:tundra_hunter_chest', name: 'Tunica del Cazador Nevado' },
    { id: 'archers_expansion:war_archer_chest', name: 'Coraza del Arquero de Guardia' }
  ],
  tools: [
    { id: 'oritech:hand_drill', name: 'Taladro de Galeria Viva', role: 'miner' },
    { id: 'oritech:chainsaw', name: 'Sierra de Rama Energizada', role: 'wood' }
  ],
  weapons: [
    { id: 'oritech:electric_mace', name: 'Maza Electrica del Nido' }
  ]
});

cunimobExtendLootTier('vigia', {
  armor: [
    { id: 'archers_expansion:bounty_hunter_head', name: 'Capucha del Cobrador de Madriguera' },
    { id: 'archers_expansion:bounty_hunter_chest', name: 'Tunica del Cobrador de Madriguera' },
    { id: 'archers_expansion:polar_stalker_chest', name: 'Abrigo del Acechador Polar' },
    { id: 'archers_expansion:sentinel_archer_chest', name: 'Coraza del Centinela Flechado' },
    { id: 'oritech:exo_chestplate', name: 'Peto Exo de Galeria' }
  ],
  tools: [
    { id: 'oritech:hand_drill', name: 'Taladro del Vigia de Cristal', role: 'miner' },
    { id: 'oritech:chainsaw', name: 'Sierra de Bosque Claro', role: 'wood' }
  ],
  weapons: [
    { id: 'oritech:electric_mace', name: 'Maza de Pulso Cunicular' }
  ]
});

cunimobExtendLootTier('juramento', {
  armor: [
    { id: 'archers_expansion:netherite_deadeye_chest', name: 'Tunica Abisal de Ojo de Madriguera' },
    { id: 'archers_expansion:netherite_tundra_hunter_chest', name: 'Tunica Abisal del Cazador Nevado' },
    { id: 'archers_expansion:netherite_war_archer_chest', name: 'Coraza Abisal del Arquero de Guardia' },
    { id: 'oritech:exo_chestplate', name: 'Peto Exo del Juramento' }
  ],
  tools: [
    { id: 'oritech:promethium_pickaxe', name: 'Pico de Promethium del Tunel Rojo', role: 'miner' },
    { id: 'oritech:chainsaw', name: 'Sierra del Juramento Verde', role: 'wood' }
  ],
  weapons: [
    { id: 'oritech:promethium_axe', name: 'Hacha Promethium del Conejo Rojo' },
    { id: 'oritech:electric_mace', name: 'Maza de Relampago de Madriguera' }
  ]
});

cunimobExtendLootTier('mitico', {
  armor: [
    { id: 'archers_expansion:netherite_deadeye_head', name: 'Capucha del Salto Imposible' },
    { id: 'archers_expansion:netherite_war_archer_chest', name: 'Coraza del Vigia Eterno' },
    { id: 'oritech:exo_chestplate', name: 'Reliquia Exo de CUNICULUM' }
  ],
  tools: [
    { id: 'oritech:promethium_pickaxe', name: 'Reliquia: Pico Promethium del Corazon Bajo', role: 'miner' },
    { id: 'oritech:chainsaw', name: 'Reliquia: Sierra del Bosque de Madriguera', role: 'wood' }
  ],
  weapons: [
    { id: 'oritech:promethium_axe', name: 'Reliquia Cunicular: Hacha Promethium del Alba' },
    { id: 'oritech:electric_mace', name: 'Reliquia Cunicular: Trueno de la Reina' }
  ]
});

CUNIMOB_RPG_CATEGORY_DROPS.push(
  { min: 24, rarity: 'RARO', apoth: 'rare', chance: 0.0028, cap: 0.0075, item: `more_jewels:nature_ring[custom_name='{"text":"Anillo de Brotes de Madriguera","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"jewel",cuniculum_trait:"naturaleza"},lore=['{"text":"Una joya viva para quienes pelean junto a la pradera.","color":"gray","italic":false}']]` },
  { min: 32, rarity: 'RARO', apoth: 'rare', chance: 0.0022, cap: 0.0060, item: `more_jewels:water_necklace[custom_name='{"text":"Collar del Arroyo Oculto","color":"blue","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"explorador",cuniculum_kind:"jewel",cuniculum_trait:"arroyo"},lore=['{"text":"El agua encuentra camino incluso bajo la madriguera.","color":"gray","italic":false}']]` },
  { min: 45, rarity: 'EPICO', apoth: 'epic', chance: 0.0014, cap: 0.0040, item: `more_jewels:wind_ring[custom_name='{"text":"Anillo del Salto del Cefiro","color":"dark_purple","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"vigia",cuniculum_kind:"jewel",cuniculum_trait:"viento"},lore=['{"text":"Ligero como orejas al viento, peligroso como una caida mal calculada.","color":"gray","italic":false}']]` },
  { min: 70, rarity: 'MITICO', apoth: 'mythic', chance: 0.00038, cap: 0.0012, item: `more_jewels:nature_necklace[custom_name='{"text":"Reliquia Cunicular: Abrazo Verde de Netherita","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"juramento",cuniculum_kind:"jewel",cuniculum_trait:"naturaleza",cuniculum_trait2:"baluarte"},lore=['{"text":"Un juramento de raices vivas sellado bajo tierra.","color":"gray","italic":false}']]` },
  { min: 82, rarity: 'MITICO', apoth: 'mythic', chance: 0.00018, cap: 0.00055, item: `more_jewels:wind_necklace[custom_name='{"text":"Reliquia Cunicular: Collar del Viento Estelar","color":"gold","italic":false}',custom_data={cuniculum_loot:1b,cuniculum_tier:"mitico",cuniculum_kind:"jewel",cuniculum_trait:"viento",cuniculum_trait2:"estelar"},lore=['{"text":"El salto perfecto empieza antes de tocar el suelo.","color":"gray","italic":false}']]` }
);

var CUNIHORDE_TYPES = {
  small: {
    label: 'pequena',
    count: 6,
    bonus: 2,
    mobs: ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:husk'],
    radius: 18,
    color: 'dark_red'
  },
  medium: {
    label: 'media',
    count: 10,
    bonus: 3,
    mobs: ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:husk', 'minecraft:spider'],
    radius: 24,
    color: 'red'
  },
  advanced: {
    label: 'avanzada',
    count: 16,
    bonus: 5,
    mobs: ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:husk', 'minecraft:stray', 'minecraft:spider'],
    radius: 30,
    color: 'gold'
  }
};

var CUNIMOB_NATURAL_TYPES = [
  { id: 'minecraft:zombie', name: 'Zombi del Prado' },
  { id: 'minecraft:zombie_villager', name: 'Aldeano Marchito' },
  { id: 'minecraft:skeleton', name: 'Esqueleto de Galeria' },
  { id: 'minecraft:creeper', name: 'Raiz Explosiva' },
  { id: 'minecraft:spider', name: 'Aracnido de Tunel' },
  { id: 'minecraft:cave_spider', name: 'Aracnido de Cueva' },
  { id: 'minecraft:husk', name: 'Seco del Camino' },
  { id: 'minecraft:stray', name: 'Errante Helado' },
  { id: 'minecraft:drowned', name: 'Ahogado de Charca' },
  { id: 'minecraft:witch', name: 'Bruja de Brebaje' },
  { id: 'minecraft:enderman', name: 'Sombra del Sendero' },
  { id: 'minecraft:vex', name: 'Eco Maldito' },
  { id: 'minecraft:pillager', name: 'Saqueador de Prado' },
  { id: 'minecraft:vindicator', name: 'Verdugo de Valle' },
  { id: 'minecraft:evoker', name: 'Conjurador de Raices' },
  { id: 'minecraft:ravager', name: 'Bestia de Asalto' },
  { id: 'minecraft:illusioner', name: 'Ilusionista de Bruma' },
  { id: 'minecraft:slime', name: 'Baba de Charca' },
  { id: 'minecraft:phantom', name: 'Sombra de Insomnio' },
  { id: 'minecraft:wither_skeleton', name: 'Hueso Abisal' },
  { id: 'minecraft:wither', name: 'Lider de Ceniza' },
  { id: 'minecraft:hoglin', name: 'Jabali Abisal' },
  { id: 'minecraft:zombified_piglin', name: 'Piglin Marchito' },
  { id: 'minecraft:piglin', name: 'Piglin Carmesi' },
  { id: 'minecraft:piglin_brute', name: 'Bruto Carmesi' },
  { id: 'minecraft:zoglin', name: 'Jabali Corrupto' },
  { id: 'minecraft:blaze', name: 'Llama de Galeria' },
  { id: 'minecraft:ghast', name: 'Lamento del Nether' },
  { id: 'minecraft:magma_cube', name: 'Nucleo de Magma' },
  { id: 'minecraft:guardian', name: 'Centinela de Ruina' },
  { id: 'minecraft:elder_guardian', name: 'Anciano de Ruina' },
  { id: 'minecraft:shulker', name: 'Caja Acechante' },
  { id: 'minecraft:silverfish', name: 'Lepisma de Grieta' },
  { id: 'minecraft:endermite', name: 'Mito del End' },
  { id: 'minecraft:breeze', name: 'Brisa de Meseta' },
  { id: 'minecraft:bogged', name: 'Pantano Marchito' },
  { id: 'minecraft:polar_bear', name: 'Oso de Nieve' },
  { id: 'minecraft:wolf', name: 'Lobo de Prado' },
  { id: 'minecraft:iron_golem', name: 'Guardian de Hierro' },
  { id: 'minecraft:warden', name: 'Custodio Profundo' },
  { id: 'minecraft:ender_dragon', name: 'Dragon del Fin' },
  { id: 'quark:forgotten', name: 'Olvidado del Tunel' },
  { id: 'quark:wraith', name: 'Aparicion del Prado' },
  { id: 'quark:foxhound', name: 'Sabueso de Brasas' },
  { id: '#minecraft:raiders', name: 'Asaltante de Pradera' },
  { id: '#minecraft:undead', name: 'Marchito Errante' },
  { id: '#minecraft:arthropod', name: 'Aracnido Salvaje' },
  { id: '#c:bosses', name: 'Lider de Caceria' },
  { id: '#cataclysm:elemental', name: 'Elemental de Ruina' },
  { id: '#cataclysm:lava_monster', name: 'Bestia de Lava' }
];

function cunihordeSafePlayer(name) {
  var value = String(name || '').trim();
  return /^[A-Za-z0-9_]{1,16}$/.test(value) ? value : '';
}

function cunihordeJson(text, color) {
  return JSON.stringify({ text: text, color: color || 'gold', italic: false });
}

function cunihordeFeedback(server, text, color) {
  if (server) {
    server.runCommandSilent('tellraw @a ' + cunihordeJson('[Horda] ' + text, color || 'gold'));
  }
}

function cunimobDimension(event) {
  var values = [];
  try { values.push(event.level.dimension); } catch (ignored) { }
  try { values.push(event.level.dimension()); } catch (ignored) { }
  try { values.push(event.level.getDimension()); } catch (ignored) { }
  try { values.push(event.entity.level.dimension); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '');
    var matches = text.match(/[a-z0-9_.-]+:[a-z0-9_./-]+/ig);
    if (matches && matches.length) {
      return matches[matches.length - 1].toLowerCase();
    }
  }

  return '';
}

function cunimobDistanceFromSpawn(entity) {
  try {
    return cunimobDistanceFromCoords(entity.x, entity.z);
  } catch (ignored) {
    return 0;
  }
}

function cunimobDistanceFromCoords(x, z) {
  var dx = Number(x || 0) - CUNIHORDE_SPAWN_X;
  var dz = Number(z || 0) - CUNIHORDE_SPAWN_Z;
  return Math.sqrt(dx * dx + dz * dz);
}

function cunimobDay(level) {
  try {
    var time = 0;
    if (typeof level.getDayTime === 'function') {
      time = Number(level.getDayTime());
    } else if (typeof level.dayTime === 'function') {
      time = Number(level.dayTime());
    } else {
      time = Number(level.dayTime || 0);
    }
    return Math.max(0, Math.floor(time / 24000));
  } catch (ignored) {
    return 0;
  }
}

function cunihordeIsNight(level) {
  try {
    var time = 0;
    if (typeof level.getDayTime === 'function') {
      time = Number(level.getDayTime());
    } else if (typeof level.dayTime === 'function') {
      time = Number(level.dayTime());
    } else {
      time = Number(level.dayTime || 0);
    }
    var dayTime = ((time % 24000) + 24000) % 24000;
    return dayTime >= 12500 && dayTime <= 23000;
  } catch (ignored) {
    return false;
  }
}

function cunimobDayBonus(day) {
  if (day >= 90) {
    return 22;
  }
  if (day >= 60) {
    return 16;
  }
  if (day >= 35) {
    return 11;
  }
  if (day >= 20) {
    return 7;
  }
  if (day >= 10) {
    return 4;
  }
  if (day >= 3) {
    return 2;
  }
  return 0;
}

function cunimobSafeNumber(value, fallback) {
  var number = Number(value);
  return isFinite(number) ? number : Number(fallback || 0);
}

function cunimobReadNumber(target, names) {
  if (!target) {
    return 0;
  }

  for (var i = 0; i < names.length; i++) {
    try {
      var value = target[names[i]];
      if (typeof value === 'function') {
        value = value.call(target);
      }
      var number = cunimobSafeNumber(value, 0);
      if (isFinite(number) && number > 0) {
        return number;
      }
    } catch (ignored) {
    }
  }

  return 0;
}

function cunimobReadStack(target, names) {
  if (!target) {
    return null;
  }

  for (var i = 0; i < names.length; i++) {
    try {
      var value = target[names[i]];
      if (typeof value === 'function') {
        value = value.call(target);
      }
      if (value && String(value) !== 'empty' && String(value) !== 'minecraft:air' && String(value) !== 'Item.empty') {
        return value;
      }
    } catch (ignored) {
    }
  }

  return null;
}

function cunimobStackId(stack) {
  if (!stack) {
    return '';
  }

  var values = [];
  try { values.push(stack.id); } catch (ignored) { }
  try { values.push(stack.item); } catch (ignored) { }
  try { values.push(stack.getId()); } catch (ignored) { }
  try { values.push(stack.getItem()); } catch (ignored) { }
  try { values.push(stack.toString()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '').toLowerCase();
    var match = text.match(/[a-z0-9_.-]+:[a-z0-9_./-]+/i);
    if (match && match[0] !== 'minecraft:air') {
      return match[0];
    }
  }

  return '';
}

function cunimobStackText(stack) {
  try {
    return String(stack || '').toLowerCase();
  } catch (ignored) {
    return '';
  }
}

function cunimobEquipmentTier(itemId) {
  if (!itemId || itemId === 'minecraft:air') {
    return 0;
  }

  var id = String(itemId).toLowerCase();
  if (id.indexOf('oritech:promethium') === 0 || id.indexOf('oritech:portable_laser') === 0 || id.indexOf('oritech:exo_') === 0) {
    return 5;
  }
  if (id.indexOf('oritech:electric_mace') === 0 || id.indexOf('oritech:hand_drill') === 0 || id.indexOf('oritech:chainsaw') === 0 || id.indexOf('archers_expansion:netherite_') === 0) {
    return 4;
  }
  if (id.indexOf('archers_expansion:') === 0) {
    return 3;
  }
  if (id.indexOf('netherite') >= 0 || id.indexOf('aeternium') >= 0 || id.indexOf('aether') >= 0 || id.indexOf('unique_') >= 0 || id.indexOf('cataclysm:') === 0 || id.indexOf('armory_rpgs:') === 0) {
    return 5;
  }
  if (id.indexOf('diamond') >= 0 || id.indexOf('ruby') >= 0 || id.indexOf('crusader') >= 0 || id.indexOf('assassin') >= 0 || id.indexOf('ranger') >= 0 || id.indexOf('arcane_robe') >= 0) {
    return 4;
  }
  if (id.indexOf('iron') >= 0 || id.indexOf('chainmail') >= 0 || id.indexOf('paladin') >= 0 || id.indexOf('rogue_armor') >= 0 || id.indexOf('archer_armor') >= 0 || id.indexOf('wizard_robe') >= 0) {
    return 3;
  }
  if (id.indexOf('gold') >= 0 || id.indexOf('stone') >= 0 || id.indexOf('leather') >= 0) {
    return 2;
  }
  if (id.indexOf('wood') >= 0 || id.indexOf('flint') >= 0) {
    return 1;
  }

  if (id.indexOf('rogues:') === 0 || id.indexOf('archers:') === 0 || id.indexOf('paladins:') === 0 || id.indexOf('berserker_rpg:') === 0 || id.indexOf('wizards:') === 0 || id.indexOf('elemental_wizards_rpg:') === 0 || id.indexOf('forcemaster_rpg:') === 0 || id.indexOf('bards_rpg:') === 0 || id.indexOf('arsenal:') === 0) {
    return 3;
  }

  return 0;
}

function cunimobEnchantTier(stack) {
  var text = cunimobStackText(stack);
  if (!text || (text.indexOf('enchant') < 0 && text.indexOf('stored_enchantments') < 0)) {
    return 0;
  }

  var lowered = String(text).toLowerCase();
  var total = 0;
  var count = 0;
  var max = 0;
  var match = null;
  var explicitLevels = /(:minecraft|extraspellattributes|spell_power|ranged_weapon|critical_strike):[a-z0-9_./-]+["']\s*[:=]\s*([0-9]+)/g;
  while ((match = explicitLevels.exec(lowered)) !== null) {
    var level = Math.max(1, Math.min(10, Math.floor(Number(match[1] || 1))));
    total += level;
    count++;
    max = Math.max(max, level);
  }

  var namedLevels = /(:level|lvl)["']\s*[:=]\s*([0-9]+)/g;
  while ((match = namedLevels.exec(lowered)) !== null) {
    var namedLevel = Math.max(1, Math.min(10, Math.floor(Number(match[1] || 1))));
    total += namedLevel;
    count++;
    max = Math.max(max, namedLevel);
  }

  if (count > 0) {
    return Math.min(24, 1 + count + max + Math.floor(total / 3));
  }

  if (lowered.indexOf('level:5') >= 0 || lowered.indexOf('lvl:5') >= 0 || lowered.indexOf(':5') >= 0) {
    return 4;
  }
  return 2;
}

function cunimobPlayerEquipmentScore(player) {
  var score = 0;
  var armorSlots = cunimobArmorSlotNames();
  var weaponSlots = [
    ['mainHandItem', 'getMainHandItem', 'heldItem'],
    ['offHandItem', 'getOffHandItem']
  ];

  for (var i = 0; i < armorSlots.length; i++) {
    var armor = cunimobReadStack(player, armorSlots[i]);
    var armorId = cunimobStackId(armor);
    score += cunimobEquipmentTier(armorId);
    score += cunimobEnchantTier(armor);
  }

  for (var j = 0; j < weaponSlots.length; j++) {
    var weapon = cunimobReadStack(player, weaponSlots[j]);
    var weaponId = cunimobStackId(weapon);
    var weaponTier = cunimobEquipmentTier(weaponId);
    if (weaponTier > 0) {
      score += Math.max(1, weaponTier - 1);
    }
    score += cunimobEnchantTier(weapon);
  }

  return Math.max(0, score);
}

function cunimobArmorSlotNames() {
  return [
    ['headArmorItem', 'getHeadArmorItem', 'helmetItem'],
    ['chestArmorItem', 'getChestArmorItem', 'chestplateItem'],
    ['legsArmorItem', 'getLegsArmorItem', 'leggingsItem'],
    ['feetArmorItem', 'getFeetArmorItem', 'bootsItem']
  ];
}

function cunimobPlayerAgeTicks(player) {
  return cunimobReadNumber(player, ['age', 'tickCount']);
}

function cunimobPlayerLevelCap(player, dimension, source, progress, equipment) {
  if (source === 'horde') {
    return CUNIMOB_HORDE_MAX_LEVEL;
  }

  var xp = cunimobReadNumber(player, ['experienceLevel', 'xpLevel', 'getXpLevel', 'experienceLevels']);
  var maxHealth = cunimobReadNumber(player, ['maxHealth', 'getMaxHealth']);
  var armor = cunimobReadNumber(player, ['armorValue', 'getArmorValue']);
  var age = cunimobPlayerAgeTicks(player);
  var safeProgress = cunimobSafeNumber(progress, 0);
  var safeEquipment = cunimobSafeNumber(equipment, 0);
  var dimensionBonus = dimension === 'minecraft:the_nether' ? 6 : 0;

  if (age > 0 && age < 20 * 60 * 45 && xp < 8 && safeEquipment <= 12 && maxHealth <= 24 && armor <= 10) {
    return 10 + dimensionBonus;
  }
  if (xp < 15 && safeProgress <= 7 && safeEquipment <= 9 && maxHealth <= 28 && armor <= 14) {
    return 24 + dimensionBonus;
  }
  if (xp < 30 && safeProgress <= 14 && safeEquipment <= 18 && maxHealth <= 34) {
    return 40 + dimensionBonus;
  }
  if (xp < 45 && safeProgress <= 22 && safeEquipment <= 28) {
    return 60 + dimensionBonus;
  }

  return CUNIMOB_NATURAL_MAX_LEVEL;
}

function cunimobPlayerProgressScore(player) {
  var xp = cunimobReadNumber(player, ['experienceLevel', 'xpLevel', 'getXpLevel', 'experienceLevels']);
  var maxHealth = cunimobReadNumber(player, ['maxHealth', 'getMaxHealth']);
  var armor = cunimobReadNumber(player, ['armorValue', 'getArmorValue']);
  var age = cunimobReadNumber(player, ['age', 'tickCount']);
  var equipment = cunimobPlayerEquipmentScore(player);

  var score = 0;

  if (xp >= 100) {
    score += 18;
  } else if (xp >= 75) {
    score += 14;
  } else if (xp >= 50) {
    score += 10;
  } else if (xp >= 35) {
    score += 7;
  } else if (xp >= 20) {
    score += 4;
  } else if (xp >= 10) {
    score += 2;
  }

  if (maxHealth >= 60) {
    score += 8;
  } else if (maxHealth >= 44) {
    score += 6;
  } else if (maxHealth >= 34) {
    score += 4;
  } else if (maxHealth >= 28) {
    score += 3;
  } else if (maxHealth > 20) {
    score += 2;
  }

  if (armor >= 24) {
    score += 8;
  } else if (armor >= 20) {
    score += 6;
  } else if (armor >= 16) {
    score += 4;
  } else if (armor >= 10) {
    score += 3;
  } else if (armor >= 5) {
    score += 2;
  }

  if (equipment >= 32) {
    score += 14;
  } else if (equipment >= 26) {
    score += 11;
  } else if (equipment >= 22) {
    score += 9;
  } else if (equipment >= 16) {
    score += 7;
  } else if (equipment >= 11) {
    score += 5;
  } else if (equipment >= 7) {
    score += 3;
  } else if (equipment >= 4) {
    score += 2;
  } else if (equipment >= 2) {
    score += 1;
  }

  if (age >= 240000) {
    score += 8;
  } else if (age >= 144000) {
    score += 5;
  } else if (age >= 72000) {
    score += 3;
  } else if (age >= 24000) {
    score += 2;
  }

  try {
    var stored = cunimobSafeNumber(player.persistentData.cuniculum_progress_score || 0, 0);
    if (stored < 0) {
      stored = 0;
    }
    var manualProgress = false;
    try { manualProgress = !!player.persistentData.cuniculum_progress_manual; } catch (ignoredManual) { }
    if (score > stored) {
      player.persistentData.cuniculum_progress_score = score;
      stored = score;
    } else if (!isFinite(Number(player.persistentData.cuniculum_progress_score || 0))) {
      player.persistentData.cuniculum_progress_score = stored;
    }
    score = manualProgress ? Math.max(score, stored) : Math.max(score, Math.min(stored, score + CUNIMOB_PLAYER_PROGRESS_MEMORY_MARGIN));
  } catch (ignored) {
  }

  return Math.max(0, score);
}

function cunimobDimensionBonus(dimension) {
  return cunimobDimensionProfile(dimension).levelBonus;
}

function cunimobDimensionProfile(dimension) {
  if (dimension === 'minecraft:the_nether') {
    return {
      key: 'nether',
      label: 'Nether',
      levelBonus: 4,
      minLevel: 4,
      healthMultiplier: 1.12,
      outgoingDamageMultiplier: 1.18,
      incomingDamageMultiplier: 0.90
    };
  }
  if (dimension === 'minecraft:the_end') {
    return {
      key: 'end',
      label: 'End',
      levelBonus: 7,
      minLevel: 8,
      healthMultiplier: 1.22,
      outgoingDamageMultiplier: 1.32,
      incomingDamageMultiplier: 0.82
    };
  }
  if (dimension && dimension !== 'minecraft:overworld' && dimension !== CUNIMOB_SPAWN_DIMENSION) {
    return {
      key: 'other',
      label: 'Dimension peligrosa',
      levelBonus: 3,
      minLevel: 3,
      healthMultiplier: 1.08,
      outgoingDamageMultiplier: 1.10,
      incomingDamageMultiplier: 0.94
    };
  }
  return {
    key: 'overworld',
    label: 'Overworld',
    levelBonus: 0,
    minLevel: 1,
    healthMultiplier: 1.0,
    outgoingDamageMultiplier: 1.0,
    incomingDamageMultiplier: 1.0
  };
}

function cunimobDimensionMinimumLevel(dimension) {
  return cunimobDimensionProfile(dimension).minLevel || 1;
}

function cunimobDimensionHealthMultiplier(dimension) {
  return cunimobDimensionProfile(dimension).healthMultiplier || 1.0;
}

function cunimobDimensionOutgoingDamageMultiplier(dimension) {
  return cunimobDimensionProfile(dimension).outgoingDamageMultiplier || 1.0;
}

function cunimobDimensionIncomingDamageMultiplier(dimension) {
  return cunimobDimensionProfile(dimension).incomingDamageMultiplier || 1.0;
}

function cunimobIsCombatDimension(dimension) {
  return !!dimension && dimension !== CUNIMOB_SPAWN_DIMENSION;
}

function cunimobIsNaturalSpawnReason(event) {
  var text = cunimobSpawnReasonText(event);
  if (!text) {
    return false;
  }
  return text.indexOf('natural') >= 0
    || text.indexOf('chunk') >= 0
    || text.indexOf('patrol') >= 0
    || text.indexOf('reinforcement') >= 0;
}

function cunimobInList(value, list) {
  for (var i = 0; i < list.length; i++) {
    if (list[i] === value) {
      return true;
    }
  }
  return false;
}

function cunimobDimensionAllowsNaturalSpawn(mobId, dimension) {
  var id = String(mobId || '').toLowerCase();
  if (!id || id.indexOf('#') === 0) {
    return true;
  }

  var netherOnly = [
    'minecraft:wither_skeleton', 'minecraft:hoglin', 'minecraft:zoglin', 'minecraft:zombified_piglin',
    'minecraft:piglin', 'minecraft:piglin_brute', 'minecraft:blaze', 'minecraft:ghast',
    'minecraft:magma_cube', 'quark:foxhound'
  ];
  var endOnly = ['minecraft:shulker', 'minecraft:endermite', 'minecraft:ender_dragon'];

  if (dimension === 'minecraft:overworld') {
    return !cunimobInList(id, netherOnly) && !cunimobInList(id, endOnly);
  }
  if (dimension === 'minecraft:the_nether') {
    return !cunimobInList(id, endOnly);
  }
  if (dimension === 'minecraft:the_end') {
    var endAllowed = [
      'minecraft:enderman', 'minecraft:shulker', 'minecraft:endermite', 'minecraft:ender_dragon',
      'minecraft:warden', 'quark:forgotten', 'quark:wraith'
    ];
    return cunimobInList(id, endAllowed) || id.indexOf('cataclysm:') === 0;
  }
  return true;
}

function cunimobProgressCap(progress, dimension, source) {
  if (source === 'horde') {
    return CUNIMOB_HORDE_MAX_LEVEL;
  }
  return CUNIMOB_NATURAL_MAX_LEVEL;
}

function cunimobDistanceCap(distance, dimension, source) {
  if (source === 'horde') {
    return CUNIMOB_HORDE_MAX_LEVEL;
  }
  return CUNIMOB_NATURAL_MAX_LEVEL;
}

function cunimobDistanceBand(distance) {
  return Math.floor(Math.max(0, Number(distance || 0)) / 300);
}

function cunimobLevelForDistance(levelObj, dimension, source, bonus, distance) {
  var randomBump = source === 'horde' ? Math.floor(Math.random() * 2) : 0;
  var value = 1 + cunimobDimensionBonus(dimension) + Number(bonus || 0) + randomBump;
  var minimum = cunimobDimensionMinimumLevel(dimension);
  return cunimobApplyLevelMultiplier(value, minimum);
}

function cunimobApplyLevelMultiplier(value, minimum) {
  var base = cunimobSafeNumber(value, 1);
  var floorValue = cunimobSafeNumber(minimum, 1);
  if (base <= floorValue) {
    return Math.max(1, Math.floor(floorValue));
  }
  return Math.max(floorValue, Math.ceil(floorValue + (base - floorValue) * CUNIMOB_LEVEL_MULTIPLIER));
}

function cunimobLevelRandomBump(source) {
  var spread = source === 'horde' ? 6 : 3;
  return Math.floor((Math.random() + Math.random()) * (spread + 1) / 2);
}

function cunimobLevelForPlayer(player, levelObj, dimension, source, bonus) {
  var progress = cunimobPlayerProgressScore(player);
  var equipment = cunimobPlayerEquipmentScore(player);
  var day = cunimobDay(levelObj);
  var safeProgress = cunimobSafeNumber(progress, 0);
  var safeEquipment = cunimobSafeNumber(equipment, 0);
  var dimensionBonus = cunimobDimensionBonus(dimension);
  var safeBonus = Number(bonus || 0);
  var starterGrace = source !== 'horde'
    && dimensionBonus <= 0
    && safeBonus <= 0
    && cunimobReadNumber(player, ['experienceLevel', 'xpLevel', 'getXpLevel', 'experienceLevels']) <= 2
    && safeProgress <= 9
    && safeEquipment <= 24
    && cunimobReadNumber(player, ['maxHealth', 'getMaxHealth']) <= 24
    && cunimobPlayerAgeTicks(player) < 20 * 60 * 45;
  var randomBump = starterGrace ? 0 : cunimobLevelRandomBump(source);
  var progressWeight = source === 'horde' ? 1.75 : 1.35;
  var equipmentWeight = source === 'horde' ? 0.42 : 0.28;
  var value = 1
    + (starterGrace ? 0 : Math.floor(safeProgress * progressWeight))
    + (starterGrace ? 0 : Math.floor(safeEquipment * equipmentWeight))
    + (starterGrace ? 0 : cunimobDayBonus(day))
    + dimensionBonus
    + safeBonus
    + randomBump;

  var minimum = cunimobDimensionMinimumLevel(dimension);
  var result = cunimobApplyLevelMultiplier(value, minimum);
  var cap = cunimobPlayerLevelCap(player, dimension, source, safeProgress, safeEquipment);
  return Math.min(result, cap);
}

function cunimobPlayerCap(player, dimension, source, progress, equipment) {
  if (source === 'horde') {
    return CUNIMOB_HORDE_MAX_LEVEL;
  }
  return CUNIMOB_NATURAL_MAX_LEVEL;
}

function cunimobWorldLevelFor(levelObj, dimension, source, bonus) {
  return cunimobLevelForDistance(levelObj, dimension, source, bonus, 0);
}

var CUNIMOB_RARITY_PROFILES = [
  { key: 'common', tag: 'COMUN', color: 'green', weight: 1, roll: 1000, complexity: 0, lootBonus: 0.0000, enchantBonus: 0.00, effectBonus: 0 },
  { key: 'uncommon', tag: 'INCOMUN', color: 'aqua', weight: 2, roll: 120, complexity: 2, lootBonus: 0.0008, enchantBonus: 0.02, effectBonus: 0 },
  { key: 'rare', tag: 'RARO', color: 'blue', weight: 3, roll: 28, complexity: 6, lootBonus: 0.0018, enchantBonus: 0.04, effectBonus: 1 },
  { key: 'epic', tag: 'EPICO', color: 'dark_purple', weight: 4, roll: 3, complexity: 12, lootBonus: 0.0035, enchantBonus: 0.07, effectBonus: 1 },
  { key: 'legendary', tag: 'LEGENDARIO', color: 'yellow', weight: 5, roll: 0.55, complexity: 20, lootBonus: 0.0055, enchantBonus: 0.11, effectBonus: 2 },
  { key: 'mythic', tag: 'MITICO', color: 'gold', weight: 6, roll: 0.08, complexity: 28, lootBonus: 0.0080, enchantBonus: 0.16, effectBonus: 2 }
];

var CUNIMOB_APOTHEOSIS_ITEM_RARITIES = [
  { key: 'common', label: 'Comun', apoth: 'apotheosis:common', color: 'gray', weight: 1 },
  { key: 'uncommon', label: 'Incomun', apoth: 'apotheosis:uncommon', color: 'green', weight: 2 },
  { key: 'rare', label: 'Raro', apoth: 'apotheosis:rare', color: 'blue', weight: 3 },
  { key: 'epic', label: 'Epico', apoth: 'apotheosis:epic', color: 'dark_purple', weight: 4 },
  { key: 'mythic', label: 'Mitico', apoth: 'apotheosis:mythic', color: 'gold', weight: 5 }
];

var CUNIMOB_APOTHEOSIS_WORLD_TIERS = [
  { key: 'haven', label: 'Haven', maxLootTier: 'guardia', maxApoth: 'uncommon', minBossLootTier: 'madriguera' },
  { key: 'frontier', label: 'Frontier', maxLootTier: 'explorador', maxApoth: 'rare', minBossLootTier: 'guardia' },
  { key: 'ascent', label: 'Ascent', maxLootTier: 'vigia', maxApoth: 'epic', minBossLootTier: 'explorador' },
  { key: 'summit', label: 'Summit', maxLootTier: 'juramento', maxApoth: 'epic', minBossLootTier: 'vigia' },
  { key: 'pinnacle', label: 'Pinnacle', maxLootTier: 'mitico', maxApoth: 'mythic', minBossLootTier: 'juramento' }
];

function cunimobApothItemRarityByKey(key) {
  var safeKey = String(key || '').toLowerCase();
  var aliases = {
    comun: 'common',
    common: 'common',
    uncommon: 'uncommon',
    inusual: 'uncommon',
    unusual: 'uncommon',
    incomun: 'uncommon',
    rare: 'rare',
    raro: 'rare',
    epic: 'epic',
    epico: 'epic',
    mythic: 'mythic',
    mitico: 'mythic',
    mitico: 'mythic'
  };
  if (aliases[safeKey]) {
    safeKey = aliases[safeKey];
  }
  for (var i = 0; i < CUNIMOB_APOTHEOSIS_ITEM_RARITIES.length; i++) {
    if (CUNIMOB_APOTHEOSIS_ITEM_RARITIES[i].key === safeKey || CUNIMOB_APOTHEOSIS_ITEM_RARITIES[i].apoth === safeKey) {
      return CUNIMOB_APOTHEOSIS_ITEM_RARITIES[i];
    }
  }
  return CUNIMOB_APOTHEOSIS_ITEM_RARITIES[0];
}

function cunimobApothItemRarityAtLeast(rarity, minimumKey) {
  var selected = rarity || cunimobApothItemRarityByKey('common');
  var minimum = cunimobApothItemRarityByKey(minimumKey || 'common');
  if (Number(selected.weight || 1) < Number(minimum.weight || 1)) {
    return minimum;
  }
  return selected;
}

function cunimobApothItemRarityAtMost(rarity, maximumKey) {
  var selected = rarity || cunimobApothItemRarityByKey('common');
  var maximum = cunimobApothItemRarityByKey(maximumKey || 'common');
  if (Number(selected.weight || 1) > Number(maximum.weight || 1)) {
    return maximum;
  }
  return selected;
}

function cunimobRarityProfileByKey(key) {
  var safeKey = String(key || '').toLowerCase();
  var aliases = {
    comun: 'common',
    comun_: 'common',
    normal: 'common',
    inusual: 'uncommon',
    unusual: 'uncommon',
    incomun: 'uncommon',
    raro: 'rare',
    azul: 'rare',
    epico: 'epic',
    legendary: 'legendary',
    legendario: 'legendary',
    mitico: 'mythic',
    mistico: 'mythic'
  };
  if (aliases[safeKey]) {
    safeKey = aliases[safeKey];
  }
  for (var i = 0; i < CUNIMOB_RARITY_PROFILES.length; i++) {
    if (CUNIMOB_RARITY_PROFILES[i].key === safeKey || CUNIMOB_RARITY_PROFILES[i].tag.toLowerCase() === safeKey) {
      return CUNIMOB_RARITY_PROFILES[i];
    }
  }
  return CUNIMOB_RARITY_PROFILES[0];
}

function cunimobRarityProfileAtLeast(rarity, minimumKey) {
  var selected = rarity || cunimobRarityProfileByKey('common');
  var minimum = cunimobRarityProfileByKey(minimumKey || 'common');
  if (Number(selected.weight || 1) < Number(minimum.weight || 1)) {
    return minimum;
  }
  return selected;
}

function cunimobBossMinimumRarity(mobId, rarity, category) {
  var profile = rarity || cunimobRarityProfileByKey('common');
  if (cunimobIsBossMob(mobId) || cunimobCategoryKey(category) === CUNIMOB_CATEGORY_BOSS) {
    return cunimobRarityProfileAtLeast(profile, 'epic');
  }
  return profile;
}

function cunimobRarityProfile(level) {
  return CUNIMOB_RARITY_PROFILES[0];
}

function cunimobCategoryKey(value) {
  var text = String(value || '').trim().toLowerCase();
  if (text === 'jefe' || text === 'boss') {
    return CUNIMOB_CATEGORY_BOSS;
  }
  if (text === 'elite' || text === 'elites') {
    return CUNIMOB_CATEGORY_ELITE;
  }
  return CUNIMOB_CATEGORY_NORMAL;
}

function cunimobCategoryLabel(category) {
  var key = cunimobCategoryKey(category);
  if (key === CUNIMOB_CATEGORY_BOSS) {
    return 'Lider';
  }
  if (key === CUNIMOB_CATEGORY_ELITE) {
    return 'Elite';
  }
  return '';
}

function cunimobClearCategoryTags(server, positioned) {
  if (!server || !positioned) {
    return;
  }
  server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_CATEGORY_TAG_PREFIX + CUNIMOB_CATEGORY_NORMAL);
  server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_CATEGORY_TAG_PREFIX + CUNIMOB_CATEGORY_ELITE);
  server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_CATEGORY_TAG_PREFIX + CUNIMOB_CATEGORY_BOSS);
}

function cunimobCategoryFromEntity(entity) {
  try {
    var tags = entity.getTags ? entity.getTags() : entity.tags;
    var array = tags && tags.toArray ? tags.toArray() : tags;
    if (array && array.length) {
      for (var i = 0; i < array.length; i++) {
        var text = String(array[i] || '').toLowerCase();
        if (text.indexOf(CUNIMOB_CATEGORY_TAG_PREFIX) === 0) {
          return cunimobCategoryKey(text.substring(CUNIMOB_CATEGORY_TAG_PREFIX.length));
        }
      }
    }
  } catch (ignored) {
  }
  return CUNIMOB_CATEGORY_NORMAL;
}

function cunimobRarityProfileFromEntity(entity) {
  try {
    var tags = entity.getTags ? entity.getTags() : entity.tags;
    var array = tags && tags.toArray ? tags.toArray() : tags;
    if (array && array.length) {
      for (var i = 0; i < array.length; i++) {
        var text = String(array[i] || '').toLowerCase();
        if (text.indexOf(CUNIMOB_RARITY_TAG_PREFIX) === 0) {
          return cunimobRarityProfileByKey(text.substring(CUNIMOB_RARITY_TAG_PREFIX.length));
        }
      }
    }
  } catch (ignored) {
  }
  return cunimobRarityProfile(1);
}

function cunimobRollCategory(level, mobId, source, rarity, forcedCategory) {
  if (cunimobIsBossMob(mobId)) {
    return CUNIMOB_CATEGORY_BOSS;
  }
  if (forcedCategory) {
    return cunimobCategoryKey(forcedCategory);
  }
  if (!cunimobIsCustomRewardMob(mobId) || source === 'minion') {
    return CUNIMOB_CATEGORY_NORMAL;
  }

  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfileByKey('common');
  var rarityWeight = Math.max(1, Number(profile.weight || 1));
  var complexity = cunimobComplexityLevel(safeLevel, profile);

  var bossChance = 0;
  if (complexity >= 35) {
    bossChance = Math.min(0.018, 0.0006 + (complexity - 35) * 0.00010 + Math.max(0, rarityWeight - 1) * 0.0009);
    if (source === 'horde') {
      bossChance *= 1.20;
    }
  }
  if (Math.random() < bossChance) {
    return CUNIMOB_CATEGORY_BOSS;
  }

  var eliteChance = 0;
  if (complexity >= 18) {
    eliteChance = Math.min(0.12, 0.012 + (complexity - 18) * 0.00065 + Math.max(0, rarityWeight - 1) * 0.0045);
    if (source === 'horde') {
      eliteChance *= 1.15;
    }
  }
  if (Math.random() < eliteChance) {
    return CUNIMOB_CATEGORY_ELITE;
  }

  return CUNIMOB_CATEGORY_NORMAL;
}

function cunimobRollRarityProfile(level, mobId, source) {
  if (!cunimobIsCustomRewardMob(mobId)) {
    return cunimobRarityProfileByKey('common');
  }

  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var total = 0;
  var weighted = [];
  for (var i = 0; i < CUNIMOB_RARITY_PROFILES.length; i++) {
    var profile = CUNIMOB_RARITY_PROFILES[i];
    var value = Number(profile.roll || 0);
    if (profile.weight >= 3) {
      var levelFactor = Math.min(1, safeLevel / 180);
      var bonusFactor = profile.weight === 3 ? 0.55 : (profile.weight === 4 ? 0.35 : (profile.weight === 5 ? 0.22 : (profile.weight === 6 ? 0.14 : 0.10)));
      value *= 1 + levelFactor * bonusFactor;
    }
    if (source === 'horde' && profile.weight >= 3) {
      value *= profile.weight >= 5 ? 1.08 : 1.15;
    }
    if (source === 'minion' && profile.weight >= 4) {
      value *= 0.35;
    }
    total += value;
    weighted.push({ profile: profile, value: value });
  }

  var roll = Math.random() * total;
  for (var j = 0; j < weighted.length; j++) {
    roll -= weighted[j].value;
    if (roll <= 0) {
      return weighted[j].profile;
    }
  }
  return CUNIMOB_RARITY_PROFILES[0];
}

function cunimobComplexityLevel(level, rarity) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfile(1);
  return Math.max(1, safeLevel + Math.floor(Number(profile.complexity || 0)));
}

function cunimobSecondaryTags(level, rarity) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfile(1);
  if (safeLevel < 5) {
    return ['SIN EQ'];
  }

  var complexityLevel = cunimobComplexityLevel(safeLevel, profile);
  var equipmentTag = complexityLevel >= 9 ? 'ARM' : 'EQ';
  var enchantTag = null;
  var effectTag = null;

  if (complexityLevel >= 14) {
    enchantTag = complexityLevel >= 55 ? 'ENC++' : (complexityLevel >= 30 ? 'ENC+' : 'ENC');
  }
  if (complexityLevel >= 20) {
    effectTag = complexityLevel >= 70 ? 'EFX++' : (complexityLevel >= 40 ? 'EFX+' : 'EFX');
  }

  if (effectTag && enchantTag) {
    return [enchantTag, effectTag];
  }
  if (enchantTag) {
    return [equipmentTag, enchantTag];
  }
  return [equipmentTag];
}

function cunimobColorForLevel(level, source, rarity) {
  if (rarity) {
    return rarity.color;
  }
  if (source === 'horde') {
    return 'dark_red';
  }
  return (rarity || cunimobRarityProfile(level)).color;
}

var CUNIMOB_DIMENSION_MOB_NAMES = {
  'minecraft:overworld': {
    'minecraft:zombie': 'Zombi',
    'minecraft:skeleton': 'Esqueleto',
    'minecraft:creeper': 'Raiz Explosiva',
    'minecraft:spider': 'Aracnido',
    'minecraft:enderman': 'Sombra',
    'minecraft:pillager': 'Saqueador',
    'minecraft:witch': 'Bruja',
    'minecraft:wolf': 'Can',
    'minecraft:polar_bear': 'Oso Polar',
    'minecraft:bee': 'Abeja',
    'minecraft:panda': 'Panda',
    'minecraft:goat': 'Cabra',
    'minecraft:llama': 'Llama',
    'minecraft:trader_llama': 'Llama Mercante',
    'quark:wraith': 'Aparicion'
  },
  'minecraft:the_nether': {
    'minecraft:zombie': 'Zombi de Ceniza',
    'minecraft:zombie_villager': 'Aldeano de Basalto',
    'minecraft:skeleton': 'Esqueleto de Ceniza',
    'minecraft:creeper': 'Raiz de Azufre',
    'minecraft:spider': 'Aracnido de Basalto',
    'minecraft:enderman': 'Sombra Carmesi',
    'minecraft:wither_skeleton': 'Hueso Abisal',
    'minecraft:wither': 'Lider de Ceniza',
    'minecraft:hoglin': 'Jabali Abisal',
    'minecraft:zoglin': 'Jabali Corrupto',
    'minecraft:zombified_piglin': 'Piglin Marchito',
    'minecraft:piglin': 'Piglin Carmesi',
    'minecraft:piglin_brute': 'Bruto Carmesi',
    'minecraft:blaze': 'Llama de Azufre',
    'minecraft:ghast': 'Lamento Abisal',
    'minecraft:magma_cube': 'Nucleo de Magma',
    'quark:foxhound': 'Sabueso de Brasas',
    'quark:wraith': 'Aparicion de Ceniza'
  },
  'minecraft:the_end': {
    'minecraft:zombie': 'Eco Desplazado',
    'minecraft:zombie_villager': 'Eco de Aldea Rota',
    'minecraft:skeleton': 'Arquero del Vacio',
    'minecraft:creeper': 'Semilla Inestable',
    'minecraft:spider': 'Aracnido del Vacio',
    'minecraft:enderman': 'Vigia del End',
    'minecraft:shulker': 'Caja del Vacio',
    'minecraft:endermite': 'Mito del End',
    'minecraft:ender_dragon': 'Dragon del Fin',
    'minecraft:warden': 'Custodio del Silencio',
    'quark:forgotten': 'Olvidado del Vacio',
    'quark:wraith': 'Aparicion del End'
  }
};

function cunimobMobName(mobId, dimension) {
  var dimensionKey = String(dimension || 'minecraft:overworld').toLowerCase();
  var id = String(mobId || '').toLowerCase();
  if (CUNIMOB_DIMENSION_MOB_NAMES[dimensionKey] && CUNIMOB_DIMENSION_MOB_NAMES[dimensionKey][id]) {
    return CUNIMOB_DIMENSION_MOB_NAMES[dimensionKey][id];
  }
  if (dimensionKey === 'minecraft:the_nether') {
    if (id.indexOf('cataclysm:') === 0) {
      return 'Bestia Abisal';
    }
    if (id.indexOf('quark:') === 0) {
      return 'Eco de Basalto';
    }
  }
  if (dimensionKey === 'minecraft:the_end') {
    if (id.indexOf('cataclysm:') === 0) {
      return 'Heraldo del Vacio';
    }
    if (id.indexOf('quark:') === 0) {
      return 'Eco del Vacio';
    }
  }
  for (var i = 0; i < CUNIMOB_NATURAL_TYPES.length; i++) {
    if (CUNIMOB_NATURAL_TYPES[i].id === mobId && CUNIMOB_NATURAL_TYPES[i].name) {
      return CUNIMOB_NATURAL_TYPES[i].name;
    }
  }
  var raw = String(mobId).split(':')[1] || 'mob';
  return raw.split('_').map(part => part.length ? part.substring(0, 1).toUpperCase() + part.substring(1) : part).join(' ');
}

var CUNIMOB_NAME_RARITY_PREFIXES = {
  common: ['', 'Joven', 'Errante', 'Menor'],
  uncommon: ['Astuto', 'Curtido', 'Inquieto', 'Acechante'],
  rare: ['Marcado', 'Feroz', 'Sombrio', 'Vigiante'],
  epic: ['Juramentado', 'Antiguo', 'Cruel', 'Abisal'],
  legendary: ['Legendario', 'Corona Rota', 'Señor de Madriguera', 'Heraldo'],
  mythic: ['Mitico', 'Primordial', 'Eco Eterno', 'Avatar']
};

var CUNIMOB_NAME_DIMENSION_SUFFIXES = {
  'minecraft:overworld': ['del Prado', 'de Galeria', 'del Sendero', 'de la Madriguera'],
  'minecraft:the_nether': ['de Ceniza', 'de Basalto', 'del Azufre', 'del Abismo'],
  'minecraft:the_end': ['del Vacio', 'del End', 'del Eclipse', 'de la Grieta']
};

function cunimobNameHash(value) {
  var text = String(value || '');
  var hash = 0;
  for (var i = 0; i < text.length; i++) {
    hash = ((hash << 5) - hash + text.charCodeAt(i)) | 0;
  }
  return Math.abs(hash);
}

function cunimobPickNamePart(list, seed) {
  if (!list || !list.length) {
    return '';
  }
  return list[cunimobNameHash(seed) % list.length];
}

function cunimobNameHasDimensionFlavor(baseName, suffix) {
  var base = String(baseName || '').toLowerCase();
  var suff = String(suffix || '').toLowerCase();
  var tokens = ['prado', 'galeria', 'sendero', 'madriguera', 'ceniza', 'basalto', 'azufre', 'abismo', 'vacio', 'end', 'eclipse', 'grieta'];
  for (var i = 0; i < tokens.length; i++) {
    var token = tokens[i];
    if (base.indexOf(token) >= 0 && suff.indexOf(token) >= 0) {
      return true;
    }
  }
  return false;
}

function cunimobVariantMobName(mobId, dimension, rarity, category) {
  var baseName = cunimobMobName(mobId, dimension);
  var rarityKey = (rarity && rarity.key) ? rarity.key : cunimobRarityProfileByKey(rarity || 'common').key;
  var categoryKey = cunimobCategoryKey(category);
  var seed = [mobId, dimension, rarityKey, categoryKey].join('|');
  var prefix = cunimobPickNamePart(CUNIMOB_NAME_RARITY_PREFIXES[rarityKey] || CUNIMOB_NAME_RARITY_PREFIXES.common, seed + ':p');
  var suffix = cunimobPickNamePart(CUNIMOB_NAME_DIMENSION_SUFFIXES[String(dimension || 'minecraft:overworld').toLowerCase()] || CUNIMOB_NAME_DIMENSION_SUFFIXES['minecraft:overworld'], seed + ':s');

  if (categoryKey === CUNIMOB_CATEGORY_BOSS) {
    prefix = cunimobPickNamePart(['Lider', 'Caudillo', 'Alfa', 'Comandante'], seed + ':boss');
  } else if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    prefix = cunimobPickNamePart(['Elite', 'Veterano', 'Campeon', 'Guardia'], seed + ':elite');
  }

  var parts = [];
  if (prefix) {
    parts.push(prefix);
  }
  parts.push(baseName);
  if (suffix && baseName.indexOf(suffix) < 0 && !cunimobNameHasDimensionFlavor(baseName, suffix)) {
    parts.push(suffix);
  }
  return parts.join(' ');
}

function cunimobNormalizeMobId(rawMobId) {
  var raw = String(rawMobId || '').trim().toLowerCase();
  if (!raw) {
    return '';
  }
  if (/^[a-z0-9_.-]+:[a-z0-9_./-]+$/.test(raw)) {
    return raw;
  }
  if (/^[a-z0-9_./-]+$/.test(raw)) {
    return 'minecraft:' + raw;
  }
  return '';
}

function cunimobDimensionFromLevel(levelObj) {
  var values = [];
  try { values.push(levelObj.dimension); } catch (ignored) { }
  try { values.push(levelObj.dimension()); } catch (ignored) { }
  try { values.push(levelObj.getDimension()); } catch (ignored) { }
  try { values.push(levelObj.dimension().location()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '');
    var matches = text.match(/[a-z0-9_.-]+:[a-z0-9_./-]+/ig);
    if (matches && matches.length) {
      return matches[matches.length - 1].toLowerCase();
    }
  }

  return '';
}

function cunimobDimensionFromEntity(entity) {
  var values = [];
  try { values.push(entity.level); } catch (ignored) { }
  try { values.push(entity.getLevel()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var dimension = cunimobDimensionFromLevel(values[i]);
    if (dimension) {
      return dimension;
    }
  }

  return '';
}

function cunimobSameDimension(entity, dimension) {
  return String(cunimobDimensionFromEntity(entity) || '').toLowerCase() === String(dimension || '').toLowerCase();
}

function cunimobDimensionFromEvent(event, entity) {
  var fromEvent = cunimobDimension(event);
  if (fromEvent) {
    return fromEvent;
  }
  return cunimobDimensionFromEntity(entity);
}

function cunimobServerPlayerAt(players, index) {
  try {
    if (players.get) {
      return players.get(index);
    }
  } catch (ignored) {
  }
  try {
    return players[index];
  } catch (ignored) {
    return null;
  }
}

function cunimobServerPlayerCount(players) {
  try {
    if (players.size) {
      return Number(players.size());
    }
  } catch (ignored) {
  }
  try {
    return Number(players.length || 0);
  } catch (ignored) {
    return 0;
  }
}

function cunimobNearestPlayer(server, dimension, x, y, z, radius) {
  if (!server || !dimension) {
    return null;
  }

  var players = null;
  try { players = server.players; } catch (ignored) { }
  if (!players) {
    return null;
  }

  var best = null;
  var bestDistance = Number(radius || 96) * Number(radius || 96);
  var count = cunimobServerPlayerCount(players);
  for (var i = 0; i < count; i++) {
    var player = cunimobServerPlayerAt(players, i);
    if (!player) {
      continue;
    }
    var playerDimension = '';
    try { playerDimension = cunimobDimensionFromLevel(player.level); } catch (ignored) { }
    if (playerDimension !== dimension) {
      continue;
    }
    try {
      var dx = Number(player.x) - Number(x);
      var dy = Number(player.y) - Number(y);
      var dz = Number(player.z) - Number(z);
      var distance = dx * dx + dy * dy + dz * dz;
      if (distance <= bestDistance) {
        bestDistance = distance;
        best = player;
      }
    } catch (ignored) {
    }
  }

  return best;
}

function cunimobEntityTypeId(entity) {
  var values = [];
  try { values.push(entity.type); } catch (ignored) { }
  try { values.push(entity.getType()); } catch (ignored) { }
  try { values.push(entity.type.toString()); } catch (ignored) { }
  try { values.push(entity.getType().toString()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '');
    var match = text.match(/[a-z0-9_.-]+:[a-z0-9_./-]+/i);
    if (match) {
      return match[0].toLowerCase();
    }
  }

  return '';
}

function cunimobEntityHasTag(entity, tag) {
  if (!entity || !tag) {
    return false;
  }

  try { if (entity.tags && entity.tags.contains && entity.tags.contains(tag)) { return true; } } catch (ignored) { }
  try { if (entity.getTags && entity.getTags().contains && entity.getTags().contains(tag)) { return true; } } catch (ignored) { }
  try {
    var tags = entity.getTags ? entity.getTags() : entity.tags;
    var array = tags && tags.toArray ? tags.toArray() : tags;
    if (array && array.length) {
      for (var i = 0; i < array.length; i++) {
        if (String(array[i] || '') === tag) {
          return true;
        }
      }
    }
  } catch (ignored) {
  }

  return false;
}

function cunimobEntityPosition(entity) {
  return {
    x: Math.round(Number(entity && entity.x || 0) * 100) / 100,
    y: Math.round(Number(entity && entity.y || 0) * 100) / 100,
    z: Math.round(Number(entity && entity.z || 0) * 100) / 100
  };
}

function cunimobSetEntityData(entity, key, value) {
  try { entity.persistentData[key] = value; } catch (ignored) { }
}

function cunimobGetEntityDataNumber(entity, key) {
  try {
    var value = Number(entity.persistentData[key] || 0);
    return isFinite(value) ? value : 0;
  } catch (ignored) {
    return 0;
  }
}

function cunimobRollEntityCooldown(entity, key, cooldownMs, chance) {
  var now = Date.now();
  var last = cunimobGetEntityDataNumber(entity, key);
  if (now - last < cooldownMs) {
    return false;
  }
  if (Math.random() > Math.max(0, Math.min(1, Number(chance || 0)))) {
    return false;
  }
  cunimobSetEntityData(entity, key, now);
  return true;
}

function cunimobMarkEntityTag(entity, tag) {
  try { entity.addTag(tag); } catch (ignored) { }
  try { entity.tags.add(tag); } catch (ignored) { }
}

function cunimobUnmarkEntityTag(entity, tag) {
  try { entity.removeTag(tag); } catch (ignored) { }
  try { entity.tags.remove(tag); } catch (ignored) { }
}

function cunimobServerFromEvent(event, entity, fallback) {
  var values = [];
  try { values.push(event.server); } catch (ignored) { }
  try { values.push(event.getServer()); } catch (ignored) { }
  try { values.push(entity.server); } catch (ignored) { }
  try { values.push(entity.getServer()); } catch (ignored) { }
  try { values.push(fallback.server); } catch (ignored) { }
  try { values.push(fallback.getServer()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    if (values[i]) {
      return values[i];
    }
  }
  return null;
}

function cunimobMarkCombatEntity(server, entity) {
  if (!entity) {
    return;
  }
  var stamp = Date.now();
  cunimobMarkEntityTag(entity, CUNIMOB_COMBAT_TAG);
  cunimobSetEntityData(entity, 'cuniculum_last_combat_ms', stamp);
  if (!server) {
    return;
  }
  server.scheduleInTicks(CUNIMOB_COMBAT_MEMORY_TICKS, function () {
    var last = cunimobGetEntityDataNumber(entity, 'cuniculum_last_combat_ms');
    if (Date.now() - last >= 5000) {
      cunimobUnmarkEntityTag(entity, CUNIMOB_COMBAT_TAG);
    }
  });
}

function cunimobBreakableBlockPredicates() {
  return CUNIMOB_BREAKABLE_BLOCKS;
}

function cunimobTryBreakBlockAt(server, dimension, x, y, z) {
  if (!server || !dimension) {
    return;
  }
  var bx = Math.floor(Number(x || 0));
  var by = Math.floor(Number(y || 0));
  var bz = Math.floor(Number(z || 0));
  if (by < -64 || by > 319) {
    return;
  }
  var blocks = cunimobBreakableBlockPredicates();
  for (var i = 0; i < blocks.length; i++) {
    server.runCommandSilent('execute in ' + dimension + ' if block ' + bx + ' ' + by + ' ' + bz + ' ' + blocks[i] + ' run setblock ' + bx + ' ' + by + ' ' + bz + ' minecraft:air destroy');
  }
}

function cunimobTryBossBreakBlockAt(server, dimension, x, y, z) {
  if (!server || !dimension) {
    return;
  }
  var bx = Math.floor(Number(x || 0));
  var by = Math.floor(Number(y || 0));
  var bz = Math.floor(Number(z || 0));
  if (by < -64 || by > 319) {
    return;
  }

  var protectedBlocks = [
    'minecraft:air',
    'minecraft:cave_air',
    'minecraft:void_air',
    'minecraft:bedrock',
    'minecraft:barrier',
    'minecraft:command_block',
    'minecraft:chain_command_block',
    'minecraft:repeating_command_block',
    'minecraft:structure_block',
    'minecraft:jigsaw',
    'minecraft:end_portal',
    'minecraft:end_gateway',
    'minecraft:nether_portal'
  ];
  var checks = [];
  for (var i = 0; i < protectedBlocks.length; i++) {
    checks.push('unless block ' + bx + ' ' + by + ' ' + bz + ' ' + protectedBlocks[i]);
  }
  server.runCommandSilent('execute in ' + dimension + ' ' + checks.join(' ') + ' run setblock ' + bx + ' ' + by + ' ' + bz + ' minecraft:air destroy');
}

function cunimobTryBreakObstruction(server, entity, target, dimension, mobId, level) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var bossLikeEarly = cunimobIsBossMob(mobId) || cunimobEntityHasTag(entity, CUNIMOB_BOSS_TAG);
  if (!server || !entity || !target || !cunimobIsCombatDimension(dimension) || (!bossLikeEarly && safeLevel < CUNIMOB_BLOCK_BREAK_MIN_LEVEL)) {
    return;
  }
  if (cunimobEntityHasTag(entity, CUNIMOB_ELITE_MINION_TAG)) {
    return;
  }
  var rarity = cunimobRarityProfileFromEntity(entity);
  var category = cunimobCategoryFromEntity(entity);
  var bossCategory = cunimobIsBossMob(mobId) || category === CUNIMOB_CATEGORY_BOSS;
  var eliteCategory = category === CUNIMOB_CATEGORY_ELITE;
  var chance = bossCategory
    ? Math.min(0.98, 0.70 + safeLevel * 0.0030)
    : (eliteCategory ? Math.min(0.66, 0.24 + safeLevel * 0.0020 + Number(rarity.weight || 1) * 0.020) : Math.min(0.48, 0.10 + safeLevel * 0.0014 + Number(rarity.weight || 1) * 0.018));
  var cooldown = bossCategory ? CUNIMOB_BOSS_BLOCK_BREAK_COOLDOWN_MS : (eliteCategory ? 2600 : CUNIMOB_BLOCK_BREAK_COOLDOWN_MS);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_block_break_ms', cooldown, chance)) {
    return;
  }

  var pos = cunimobEntityPosition(entity);
  var tx = Number(target.x || pos.x);
  var ty = Number(target.y || pos.y);
  var tz = Number(target.z || pos.z);
  var dx = tx > pos.x ? 1 : (tx < pos.x ? -1 : 0);
  var dz = tz > pos.z ? 1 : (tz < pos.z ? -1 : 0);
  if (dx === 0 && dz === 0) {
    dz = 1;
  }
  var baseY = Math.floor(pos.y);
  var targetHigh = ty > pos.y + 1.2 ? 1 : 0;
  var candidates = [
    [pos.x + dx, baseY, pos.z + dz],
    [pos.x + dx, baseY + 1, pos.z + dz],
    [pos.x, baseY + 1 + targetHigh, pos.z],
    [pos.x + dx, baseY + 2, pos.z + dz]
  ];
  var pick = candidates[Math.floor(Math.random() * candidates.length)];
  if (bossCategory) {
    cunimobTryBossBreakBlockAt(server, dimension, pick[0], pick[1], pick[2]);
    if (Math.random() < 0.45) {
      cunimobTryBossBreakBlockAt(server, dimension, pick[0], pick[1] + 1, pick[2]);
    }
  } else {
    cunimobTryBreakBlockAt(server, dimension, pick[0], pick[1], pick[2]);
  }
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run playsound minecraft:block.stone.break hostile @a[distance=..18] ~ ~ ~ 0.45 0.80');
}

function cunimobRegenerateOutOfCombat(server, playerName) {
  if (!CUNIMOB_OUT_OF_COMBAT_REGEN_ENABLED || !server || !playerName) {
    return;
  }
  var selector = '@e[tag=' + CUNIMOB_LEVEL_TAG + ',tag=!' + CUNIMOB_COMBAT_TAG + ',distance=..' + CUNIMOB_OUT_OF_COMBAT_REGEN_RADIUS + ']';
  server.runCommandSilent('execute at ' + playerName + ' as ' + selector + ' run effect give @s minecraft:regeneration 2 30 true');
  server.runCommandSilent('execute at ' + playerName + ' as @e[tag=' + CUNIMOB_HEAL_TARGET_TAG + ',distance=..' + CUNIMOB_OUT_OF_COMBAT_REGEN_RADIUS + '] run effect give @s minecraft:regeneration 2 40 true');
}

function cunimobIsVisualTarget(mobId) {
  if (!mobId || mobId === 'minecraft:player') {
    return false;
  }

  for (var i = 0; i < CUNIMOB_NATURAL_TYPES.length; i++) {
    if (CUNIMOB_NATURAL_TYPES[i].id === mobId) {
      return true;
    }
  }

  var namespaces = [
    'cataclysm:',
    'graveyard:',
    'born_in_chaos_v1:',
    'mutantmonsters:',
    'mowziesmobs:',
    'undead_unleashed:',
    'deeperdarker:',
    'dungeons_mobs:',
    'quark:'
  ];

  for (var i = 0; i < namespaces.length; i++) {
    if (mobId.indexOf(namespaces[i]) === 0) {
      return true;
    }
  }

  return false;
}

function cunimobLevelBonusForMob(mobId) {
  if (mobId === 'minecraft:iron_golem') {
    return CUNIMOB_IRON_GOLEM_LEVEL_BONUS;
  }
  return 0;
}

function cunimobAdjustLevelForMob(mobId, level) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (cunimobIsPassivePeacefulMob(mobId)) {
    return 0;
  }
  var animalScale = cunimobAnimalScaleProfile(mobId);
  if (animalScale) {
    return Math.max(1, Math.min(animalScale.cap, Math.ceil(safeLevel * animalScale.scale)));
  }
  if (mobId === 'minecraft:wolf') {
    return Math.max(1, Math.min(18, Math.ceil(safeLevel * 0.22)));
  }
  if (mobId === 'minecraft:polar_bear') {
    return Math.max(1, Math.min(45, Math.ceil(safeLevel * 0.45)));
  }
  if (mobId === 'minecraft:iron_golem') {
    return Math.max(1, Math.min(80, safeLevel));
  }
  if (mobId === 'minecraft:creeper') {
    return Math.max(1, Math.ceil(safeLevel * 0.78));
  }
  if (mobId === 'minecraft:silverfish' || mobId === 'minecraft:endermite' || mobId === 'minecraft:vex') {
    return Math.max(1, Math.ceil(safeLevel * 0.70));
  }
  if (mobId === 'minecraft:slime' || mobId === 'minecraft:magma_cube') {
    return Math.max(1, Math.ceil(safeLevel * 0.78));
  }
  if (mobId === 'minecraft:ravager' || mobId === 'minecraft:hoglin' || mobId === 'minecraft:zoglin') {
    return Math.max(1, Math.ceil(safeLevel * 0.92));
  }
  return safeLevel;
}

function cunimobAnimalScaleProfile(mobId) {
  var id = String(mobId || '').toLowerCase();
  var profiles = {
    'minecraft:wolf': { scale: 0.18, cap: 16 },
    'minecraft:polar_bear': { scale: 0.36, cap: 38 },
    'minecraft:panda': { scale: 0.26, cap: 22 },
    'minecraft:goat': { scale: 0.22, cap: 18 },
    'minecraft:llama': { scale: 0.20, cap: 16 },
    'minecraft:trader_llama': { scale: 0.20, cap: 16 },
    'minecraft:bee': { scale: 0.20, cap: 14 }
  };
  if (profiles[id]) {
    return profiles[id];
  }
  if (id.indexOf('spider') >= 0 || id.indexOf('silverfish') >= 0 || id.indexOf('endermite') >= 0) {
    return null;
  }
  if (id.indexOf('wolf') >= 0 || id.indexOf('bear') >= 0 || id.indexOf('bee') >= 0
    || id.indexOf('llama') >= 0 || id.indexOf('panda') >= 0 || id.indexOf('goat') >= 0) {
    return { scale: 0.24, cap: 22 };
  }
  return null;
}

function cunimobIsPassivePeacefulMob(mobId) {
  var id = String(mobId || '').toLowerCase();
  if (!id) {
    return false;
  }
  var passives = {
    'minecraft:allay': true,
    'minecraft:armadillo': true,
    'minecraft:axolotl': true,
    'minecraft:bat': true,
    'minecraft:camel': true,
    'minecraft:cat': true,
    'minecraft:chicken': true,
    'minecraft:cod': true,
    'minecraft:cow': true,
    'minecraft:dolphin': true,
    'minecraft:donkey': true,
    'minecraft:fox': true,
    'minecraft:frog': true,
    'minecraft:glow_squid': true,
    'minecraft:horse': true,
    'minecraft:mooshroom': true,
    'minecraft:mule': true,
    'minecraft:ocelot': true,
    'minecraft:parrot': true,
    'minecraft:pig': true,
    'minecraft:pufferfish': true,
    'minecraft:rabbit': true,
    'minecraft:salmon': true,
    'minecraft:sheep': true,
    'minecraft:sniffer': true,
    'minecraft:squid': true,
    'minecraft:strider': true,
    'minecraft:tadpole': true,
    'minecraft:tropical_fish': true,
    'minecraft:turtle': true,
    'minecraft:villager': true,
    'minecraft:wandering_trader': true
  };
  if (passives[id]) {
    return true;
  }
  return id.indexOf('villager') >= 0
    || id.indexOf('_fish') >= 0
    || id.indexOf('squid') >= 0
    || id.indexOf('horse') >= 0
    || id.indexOf('cow') >= 0
    || id.indexOf('pig') >= 0
    || id.indexOf('sheep') >= 0
    || id.indexOf('chicken') >= 0
    || id.indexOf('rabbit') >= 0
    || id.indexOf('parrot') >= 0
    || id.indexOf('cat') >= 0
    || id.indexOf('frog') >= 0
    || id.indexOf('turtle') >= 0
    || id.indexOf('sniffer') >= 0
    || id.indexOf('armadillo') >= 0;
}

function cunimobIsCustomRewardMob(mobId) {
  var id = String(mobId || '').toLowerCase();
  if (!id || id === 'minecraft:iron_golem' || id === 'minecraft:wolf' || id === 'minecraft:polar_bear') {
    return false;
  }
  if (id.indexOf('villager') >= 0 || id.indexOf('golem') >= 0) {
    return false;
  }
  return cunimobIsVisualTarget(id);
}

function cunimobUsesEquipmentPools(mobId) {
  return mobId !== 'minecraft:iron_golem'
    && mobId !== 'minecraft:polar_bear'
    && mobId !== 'minecraft:wolf';
}

function cunimobIsBossMob(mobId) {
  if (!mobId) {
    return false;
  }
  var id = String(mobId || '').toLowerCase();
  if (id.indexOf('cataclysm:') === 0) {
    return id.indexOf('ignis') >= 0
      || id.indexOf('ender_guardian') >= 0
      || id.indexOf('netherite_monstrosity') >= 0
      || id.indexOf('harbinger') >= 0
      || id.indexOf('leviathan') >= 0
      || id.indexOf('ancient_remnant') >= 0
      || id.indexOf('maledictus') >= 0
      || id.indexOf('scylla') >= 0
      || id.indexOf('coralssus') >= 0;
  }
  return id === 'minecraft:wither'
    || mobId === 'minecraft:ender_dragon'
    || id === 'minecraft:warden'
    || id === 'minecraft:elder_guardian';
}

function cunimobRandomChoice(list) {
  if (!list || list.length === 0) {
    return null;
  }
  return list[Math.floor(Math.random() * list.length)];
}

var CUNIMOB_CLASS_AFFINITY_PATTERNS = [
  { key: 'archer', words: ['archers:', 'archers_expansion:', 'bow', 'crossbow', 'deadeye', 'tundra', 'war_archer', 'ranger', 'sentinel', 'bounty'] },
  { key: 'rogue', words: ['rogues:', 'dagger', 'assassin', 'rogue', 'shadow', 'bruma', 'picar', 'picaro'] },
  { key: 'paladin', words: ['paladins:', 'cleric', 'priest', 'paladin', 'crusader', 'hammer', 'mace', 'shield', 'baluarte', 'santuario'] },
  { key: 'wizard', words: ['wizards:', 'elemental_wizards_rpg:', 'spell_book/wizard', 'staff_', '_staff', 'robe', 'arcane', 'frost', 'fire', 'aqua', 'terra', 'wind', 'hechic', 'mago'] },
  { key: 'berserker', words: ['berserker_rpg:', 'berserker', 'wildling', 'warlord', 'raid_axe', 'hacha', 'furia'] },
  { key: 'forcemaster', words: ['forcemaster_rpg:', 'knuckle', 'phasleb', 'oriene', 'force', 'fuerza', 'nudillo'] },
  { key: 'bard', words: ['bards_rpg:', 'bard', 'entertainer', 'harp', 'lyre', 'music', 'canto', 'melodia'] },
  { key: 'witcher', words: ['witcher', 'silver', 'monster_hunter', 'cazador'] }
];

function cunimobClassFromText(text) {
  var value = String(text || '').toLowerCase();
  if (!value) {
    return '';
  }
  for (var i = 0; i < CUNIMOB_CLASS_AFFINITY_PATTERNS.length; i++) {
    var rule = CUNIMOB_CLASS_AFFINITY_PATTERNS[i];
    for (var j = 0; j < rule.words.length; j++) {
      if (value.indexOf(rule.words[j]) >= 0) {
        return rule.key;
      }
    }
  }
  return '';
}

function cunimobEntryClass(entry) {
  if (!entry) {
    return '';
  }
  return cunimobClassFromText(String(entry.id || '') + ' ' + String(entry.name || '') + ' ' + String(entry.role || '') + ' ' + String(entry.family || ''));
}

function cunimobPlayerClassText(player) {
  if (!player) {
    return '';
  }
  var parts = [];
  try { parts.push(String(player.nbt)); } catch (ignoredNbt) { }
  try { parts.push(String(player.persistentData)); } catch (ignoredData) { }
  try { parts.push(String(player.mainHandItem)); } catch (ignoredMain) { }
  try { parts.push(String(player.offHandItem)); } catch (ignoredOff) { }
  try {
    var slots = ['headArmorItem', 'chestArmorItem', 'legsArmorItem', 'feetArmorItem'];
    for (var i = 0; i < slots.length; i++) {
      try { parts.push(String(player[slots[i]])); } catch (ignoredSlot) { }
    }
  } catch (ignoredArmor) { }
  return parts.join(' ').toLowerCase();
}

function cunimobPlayerClassAffinity(player) {
  return cunimobClassFromText(cunimobPlayerClassText(player));
}

function cunimobClassWeightForEntry(entry, playerClass) {
  var entryClass = cunimobEntryClass(entry);
  if (!playerClass) {
    return 1;
  }
  if (!entryClass) {
    return 1.35;
  }
  return entryClass === playerClass ? 5.5 : 0.80;
}

function cunimobWeightedChoiceByClass(list, playerClass) {
  if (!list || list.length === 0) {
    return null;
  }
  if (!playerClass) {
    return cunimobRandomChoice(list);
  }
  var total = 0;
  var weights = [];
  for (var i = 0; i < list.length; i++) {
    var weight = Math.max(0.05, cunimobClassWeightForEntry(list[i], playerClass));
    weights.push(weight);
    total += weight;
  }
  var roll = Math.random() * total;
  for (var j = 0; j < list.length; j++) {
    roll -= weights[j];
    if (roll <= 0) {
      return list[j];
    }
  }
  return list[list.length - 1];
}

function cunimobDropKiller(event, entity) {
  var source = null;
  try { source = event.source; } catch (ignored) { }
  try { if (!source) { source = event.getSource(); } } catch (ignored) { }
  var values = [];
  if (source) {
    try { values.push(source.player); } catch (ignoredPlayer) { }
    try { values.push(source.entity); } catch (ignoredEntity) { }
    try { values.push(source.actual); } catch (ignoredActual) { }
    try { values.push(source.getPlayer && source.getPlayer()); } catch (ignoredGetPlayer) { }
    try { values.push(source.getEntity && source.getEntity()); } catch (ignoredGetEntity) { }
    try { values.push(source.getActual && source.getActual()); } catch (ignoredGetActual) { }
  }
  try { values.push(entity.lastHurtByPlayer); } catch (ignoredLastPlayer) { }
  try { values.push(entity.getLastHurtByPlayer && entity.getLastHurtByPlayer()); } catch (ignoredGetLastPlayer) { }
  for (var i = 0; i < values.length; i++) {
    if (cunimobIsPlayerEntity(values[i])) {
      return values[i];
    }
  }
  return null;
}

function cunimobChanceForLevel(pool, level, rarity) {
  var base = Number(pool.chance || 0);
  var growth = Math.max(0, Number(level || 1) - Number(pool.min || 1)) * 0.010;
  var rarityBonus = rarity ? Math.max(0, Number(rarity.weight || 1) - 1) * 0.025 : 0;
  return Math.max(0, Math.min(0.82, base + growth + rarityBonus));
}

function cunimobPickPool(pools, level, rarity) {
  var candidates = [];
  for (var i = 0; i < pools.length; i++) {
    var pool = pools[i];
    if (level >= pool.min && Math.random() < cunimobChanceForLevel(pool, level, rarity)) {
      candidates.push(pool);
    }
  }
  return cunimobRandomChoice(candidates);
}

function cunimobShuffledIndexes(count) {
  var indexes = [];
  for (var i = 0; i < count; i++) {
    indexes.push(i);
  }
  for (var j = indexes.length - 1; j > 0; j--) {
    var swap = Math.floor(Math.random() * (j + 1));
    var temp = indexes[j];
    indexes[j] = indexes[swap];
    indexes[swap] = temp;
  }
  return indexes;
}

function cunimobArmorPieceCountForLevel(level, rarity) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var complexityLevel = cunimobComplexityLevel(safeLevel, rarity);
  var rarityWeight = rarity ? Number(rarity.weight || 1) : 1;
  var roll = Math.random();
  if (complexityLevel >= 80) {
    return roll < 0.70 ? 4 : 3;
  }
  if (complexityLevel >= 55) {
    return roll < 0.45 ? 4 : (roll < 0.82 ? 3 : 2);
  }
  if (complexityLevel >= 35) {
    return roll < 0.25 ? 4 : (roll < 0.65 ? 3 : 2);
  }
  if (complexityLevel >= 18) {
    return roll < 0.20 ? 3 : (roll < 0.70 ? 2 : 1);
  }
  if (complexityLevel >= 8) {
    if (rarityWeight >= 5 && roll < 0.20) {
      return 3;
    }
    return roll < 0.25 ? 2 : 1;
  }
  if (rarityWeight >= 5 && roll < 0.08) {
    return 2;
  }
  if (rarityWeight >= 4 && roll < 0.12) {
    return 1;
  }
  return 0;
}

function cunimobApplyArmorPieces(server, positioned, set, level, rarity) {
  if (!server || !positioned || !set || set.length !== 4) {
    return;
  }

  var slots = ['armor.head', 'armor.chest', 'armor.legs', 'armor.feet'];
  var indexes = cunimobShuffledIndexes(4);
  var count = cunimobArmorPieceCountForLevel(level, rarity);
  for (var i = 0; i < count && i < indexes.length; i++) {
    var index = indexes[i];
    var item = cunimobEnchantItem(set[index], level, 'armor', rarity);
    if (item) {
      server.runCommandSilent(positioned + ' run item replace entity @s ' + slots[index] + ' with ' + item + ' 1');
    }
  }
}

function cunimobIsBowWeapon(itemId) {
  var id = String(itemId || '');
  return id === 'minecraft:bow'
    || (id.indexOf('archers:') === 0 && id.indexOf('bow') >= 0 && id.indexOf('crossbow') < 0);
}

function cunimobIsCrossbowWeapon(itemId) {
  var id = String(itemId || '');
  return id === 'minecraft:crossbow'
    || (id.indexOf('archers:') === 0 && id.indexOf('crossbow') >= 0);
}

function cunimobIsRangedWeapon(itemId) {
  return cunimobIsBowWeapon(itemId) || cunimobIsCrossbowWeapon(itemId);
}

function cunimobCanUseBow(mobId) {
  return mobId === 'minecraft:skeleton'
    || mobId === 'minecraft:stray'
    || mobId === 'minecraft:bogged'
    || mobId === 'minecraft:illusioner';
}

function cunimobCanUseCrossbow(mobId) {
  return mobId === 'minecraft:pillager'
    || mobId === 'minecraft:piglin';
}

function cunimobCanUseWeaponItem(mobId, itemId) {
  if (!cunimobIsRangedWeapon(itemId)) {
    return true;
  }
  if (cunimobIsBowWeapon(itemId)) {
    return cunimobCanUseBow(mobId);
  }
  if (cunimobIsCrossbowWeapon(itemId)) {
    return cunimobCanUseCrossbow(mobId);
  }
  return false;
}

function cunimobWeaponItemsForMob(mobId, items) {
  var usable = [];
  var fallback = [];
  for (var i = 0; i < items.length; i++) {
    var itemId = String(items[i] || '');
    if (!cunimobIsRangedWeapon(itemId)) {
      fallback.push(itemId);
    }
    if (cunimobCanUseWeaponItem(mobId, itemId)) {
      usable.push(itemId);
    }
  }
  return usable.length ? usable : fallback;
}

function cunimobLootTier(level) {
  var selected = CUNIMOB_RPG_LOOT_TIERS[0];
  for (var i = 0; i < CUNIMOB_RPG_LOOT_TIERS.length; i++) {
    if (level >= CUNIMOB_RPG_LOOT_TIERS[i].min) {
      selected = CUNIMOB_RPG_LOOT_TIERS[i];
    }
  }
  return selected;
}

function cunimobLootTierByKey(key) {
  for (var i = 0; i < CUNIMOB_RPG_LOOT_TIERS.length; i++) {
    if (CUNIMOB_RPG_LOOT_TIERS[i].key === key) {
      return CUNIMOB_RPG_LOOT_TIERS[i];
    }
  }
  return CUNIMOB_RPG_LOOT_TIERS[0];
}

function cunimobWorldTierProfileByKey(key) {
  var safeKey = String(key || '').toLowerCase();
  for (var i = 0; i < CUNIMOB_APOTHEOSIS_WORLD_TIERS.length; i++) {
    if (CUNIMOB_APOTHEOSIS_WORLD_TIERS[i].key === safeKey) {
      return CUNIMOB_APOTHEOSIS_WORLD_TIERS[i];
    }
  }
  return CUNIMOB_APOTHEOSIS_WORLD_TIERS[0];
}

function cunimobNormalizeWorldTierKey(value) {
  var text = String(value || '').toLowerCase();
  if (text.indexOf('pinnacle') >= 0) {
    return 'pinnacle';
  }
  if (text.indexOf('summit') >= 0) {
    return 'summit';
  }
  if (text.indexOf('ascent') >= 0) {
    return 'ascent';
  }
  if (text.indexOf('frontier') >= 0) {
    return 'frontier';
  }
  if (text.indexOf('haven') >= 0) {
    return 'haven';
  }
  return '';
}

function cunimobWorldTierIndex(key) {
  var profile = cunimobWorldTierProfileByKey(key);
  for (var i = 0; i < CUNIMOB_APOTHEOSIS_WORLD_TIERS.length; i++) {
    if (CUNIMOB_APOTHEOSIS_WORLD_TIERS[i].key === profile.key) {
      return i;
    }
  }
  return 0;
}

function cunimobWorldTierLabel(key) {
  return cunimobWorldTierProfileByKey(key).label || 'Haven';
}

function cunimobTryReadApotheosisWorldTier(player) {
  if (!player || !CUNIMOB_APOTHEOSIS_WORLD_TIER_CLASS) {
    return '';
  }

  var handles = [];
  try { handles.push(player); } catch (ignored) { }
  try { handles.push(player.minecraftPlayer); } catch (ignored) { }
  try { handles.push(player.actual); } catch (ignored) { }
  try { handles.push(player.entity); } catch (ignored) { }
  try { handles.push(player.getEntity()); } catch (ignored) { }
  try { handles.push(player.getPlayer()); } catch (ignored) { }

  for (var i = 0; i < handles.length; i++) {
    var handle = handles[i];
    if (!handle) {
      continue;
    }
    try {
      var tier = CUNIMOB_APOTHEOSIS_WORLD_TIER_CLASS.getTier(handle);
      var key = '';
      try { key = cunimobNormalizeWorldTierKey(tier.getSerializedName()); } catch (ignoredName) { }
      if (!key) {
        key = cunimobNormalizeWorldTierKey(tier);
      }
      if (key) {
        return key;
      }
    } catch (ignoredTier) {
    }
  }
  return '';
}

function cunimobInferWorldTierFromPlayer(player, dimension) {
  var progress = 0;
  var equipment = 0;
  var xp = 0;
  var maxHealth = 20;
  var armor = 0;
  try { progress = cunimobPlayerProgressScore(player); } catch (ignoredProgress) { progress = 0; }
  try { equipment = cunimobPlayerEquipmentScore(player); } catch (ignoredEquipment) { equipment = 0; }
  try { xp = cunimobReadNumber(player, ['experienceLevel', 'xpLevel', 'getXpLevel', 'experienceLevels']); } catch (ignoredXp) { xp = 0; }
  try { maxHealth = cunimobReadNumber(player, ['maxHealth', 'getMaxHealth']); } catch (ignoredHealth) { maxHealth = 20; }
  try { armor = cunimobReadNumber(player, ['armorValue', 'getArmorValue']); } catch (ignoredArmor) { armor = 0; }

  var score = progress
    + Math.floor(equipment * 0.55)
    + Math.floor(Math.max(0, xp) / 6)
    + Math.floor(Math.max(0, maxHealth - 20) / 3)
    + Math.floor(Math.max(0, armor) / 3)
    + (dimension === 'minecraft:the_nether' ? 4 : 0)
    + (dimension === 'minecraft:the_end' ? 7 : 0);

  if (score >= 54) {
    return 'pinnacle';
  }
  if (score >= 40) {
    return 'summit';
  }
  if (score >= 26) {
    return 'ascent';
  }
  if (score >= 12) {
    return 'frontier';
  }
  return 'haven';
}

function cunimobEffectiveWorldTierForPlayer(player, dimension) {
  var apothTier = cunimobTryReadApotheosisWorldTier(player);
  if (apothTier) {
    return apothTier;
  }
  try {
    var stored = cunimobNormalizeWorldTierKey(player.persistentData.cuniculum_apotheosis_world_tier || '');
    if (stored) {
      return stored;
    }
  } catch (ignoredStored) {
  }
  return cunimobInferWorldTierFromPlayer(player, dimension);
}

function cunimobRememberDropWorldTier(entity, player, dimension) {
  if (!entity || !player) {
    return 'haven';
  }
  var tier = cunimobEffectiveWorldTierForPlayer(player, dimension);
  try {
    entity.persistentData[CUNIMOB_DROP_WORLD_TIER_KEY] = tier;
  } catch (ignored) {
  }
  return tier;
}

function cunimobDropWorldTierFromEntity(entity) {
  try {
    var stored = cunimobNormalizeWorldTierKey(entity.persistentData[CUNIMOB_DROP_WORLD_TIER_KEY] || '');
    if (stored) {
      return stored;
    }
  } catch (ignored) {
  }
  return 'haven';
}

function cunimobMaxLootTierForWorldTier(worldTierKey) {
  var profile = cunimobWorldTierProfileByKey(worldTierKey);
  return cunimobLootTierByKey(profile.maxLootTier || 'madriguera');
}

function cunimobClampLootTierToWorldTier(tier, worldTierKey, boss, guaranteed) {
  var selected = tier || CUNIMOB_RPG_LOOT_TIERS[0];
  var profile = cunimobWorldTierProfileByKey(worldTierKey);
  var maxTier = cunimobLootTierByKey(profile.maxLootTier || 'madriguera');
  var maxIndex = cunimobTierPowerIndex(maxTier);
  var selectedIndex = cunimobTierPowerIndex(selected);
  if (selectedIndex > maxIndex) {
    selected = maxTier;
    selectedIndex = maxIndex;
  }

  if (boss && guaranteed) {
    var minBossTier = cunimobLootTierByKey(profile.minBossLootTier || 'madriguera');
    var minIndex = cunimobTierPowerIndex(minBossTier);
    if (selectedIndex < minIndex && maxIndex >= minIndex) {
      selected = minBossTier;
    }
  }
  return selected;
}

function cunimobClampApothRarityToWorldTier(rarity, worldTierKey) {
  var profile = cunimobWorldTierProfileByKey(worldTierKey);
  return cunimobApothItemRarityAtMost(rarity || cunimobApothItemRarityByKey('common'), profile.maxApoth || 'common');
}

function cunimobWorldTierAllowsSpecialDrop(drop, worldTierKey, boss) {
  var profile = cunimobWorldTierProfileByKey(worldTierKey);
  var maxApoth = cunimobApothItemRarityByKey(profile.maxApoth || 'common');
  var dropApoth = cunimobApothItemRarityByKey(drop && drop.apoth || 'common');
  if (Number(dropApoth.weight || 1) > Number(maxApoth.weight || 1)) {
    return false;
  }

  var maxTier = cunimobMaxLootTierForWorldTier(profile.key);
  var maxMin = Number(maxTier && maxTier.min || 1);
  var dropMin = Number(drop && drop.min || 1);
  var grace = boss ? 14 : 6;
  return dropMin <= maxMin + grace;
}

function cunimobLootTierForReward(level, boss, rarity, guaranteed, worldTierKey) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var tier = cunimobLootTier(safeLevel);
  var profile = rarity || cunimobRarityProfileByKey('common');
  var weightBonus = Math.max(0, Number(profile.weight || 1) - 1);
  if (tier.key === 'mitico') {
    var mythicKeep = (guaranteed ? 0.11 : 0.035) + Math.min(0.10, Math.max(0, safeLevel - 80) * 0.0012) + weightBonus * 0.012 + (boss ? 0.05 : 0);
    if (Math.random() > Math.min(0.28, mythicKeep)) {
        return cunimobClampLootTierToWorldTier(Math.random() < 0.42 ? cunimobLootTierByKey('juramento') : cunimobLootTierByKey('vigia'), worldTierKey, boss, guaranteed);
      }
  }
  if (tier.key === 'juramento') {
    var netherKeep = (guaranteed ? 0.22 : 0.10) + Math.min(0.18, Math.max(0, safeLevel - 55) * 0.0030) + weightBonus * 0.018 + (boss ? 0.06 : 0);
    if (Math.random() > Math.min(0.52, netherKeep)) {
      return cunimobClampLootTierToWorldTier(cunimobLootTierByKey('vigia'), worldTierKey, boss, guaranteed);
    }
  }
  return cunimobClampLootTierToWorldTier(tier, worldTierKey, boss, guaranteed);
}

function cunimobRollApothItemRarity(level, tier, boss, mobRarity, kind, worldTierKey) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var tierIndex = cunimobTierPowerIndex(tier);
  var mobWeight = Math.max(1, Number(mobRarity && mobRarity.weight || 1));
  var score = safeLevel + tierIndex * 6 + (mobWeight - 1) * 5 + (boss ? 18 : 0);

  var mythicSpikeChance = 0;
  if (score >= 105) {
    mythicSpikeChance = 0.00010 + Math.min(0.00012, (score - 105) * 0.000002);
    if (boss) {
      mythicSpikeChance += 0.00008;
    }
    if (mobWeight >= 5) {
      mythicSpikeChance += 0.00005;
    }
    mythicSpikeChance = Math.min(0.00035, mythicSpikeChance);
  }
  if (Math.random() < mythicSpikeChance) {
    return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('mythic'), worldTierKey);
  }

  var mythicChance = score >= 70 ? Math.min(0.018, 0.0015 + (score - 70) * 0.00018 + (boss ? 0.003 : 0)) : 0;
  if (Math.random() < mythicChance) {
    return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('mythic'), worldTierKey);
  }

  var epicChance = score >= 35 ? Math.min(0.090, 0.012 + (score - 35) * 0.00085 + (boss ? 0.012 : 0)) : 0;
  if (Math.random() < epicChance) {
    return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('epic'), worldTierKey);
  }

  var rareChance = score >= 12 ? Math.min(0.300, 0.040 + (score - 12) * 0.0017 + (boss ? 0.030 : 0)) : 0.018;
  if (Math.random() < rareChance) {
    return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('rare'), worldTierKey);
  }

  var uncommonChance = Math.min(0.620, 0.105 + score * 0.0040 + (kind === 'armor' ? 0.035 : 0));
  if (Math.random() < uncommonChance) {
    return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('uncommon'), worldTierKey);
  }

  return cunimobClampApothRarityToWorldTier(cunimobApothItemRarityByKey('common'), worldTierKey);
}

function cunimobItemQualityIndexFromText(text) {
  var value = String(text || '').toLowerCase();
  for (var i = CUNIMOB_APOTHEOSIS_ITEM_RARITIES.length - 1; i >= 0; i--) {
    var rarity = CUNIMOB_APOTHEOSIS_ITEM_RARITIES[i];
    if (value.indexOf('cuniculum_apotheosis_rarity:"' + rarity.key + '"') >= 0
      || value.indexOf('cuniculum_apotheosis_rarity:' + rarity.key) >= 0
      || value.indexOf('cuniculum_apoth_rarity:"' + rarity.key + '"') >= 0
      || value.indexOf('cuniculum_apoth_rarity:' + rarity.key) >= 0) {
      return i;
    }
  }
  return 0;
}

function cunimobItemNameComponent(name, color) {
  return "custom_name='" + JSON.stringify({ text: String(name || 'Reliquia de CUNICULUM'), color: color || 'white', italic: false }).replace(/'/g, "\\'") + "'";
}

function cunimobLoreJson(text, color) {
  return JSON.stringify({ text: String(text || ''), color: color || 'gray', italic: false }).replace(/'/g, "\\'");
}

function cunimobLoreComponent(lines) {
  var parts = [];
  for (var i = 0; i < lines.length; i++) {
    if (lines[i]) {
      parts.push("'" + cunimobLoreJson(lines[i].text, lines[i].color) + "'");
    }
  }
  return parts.length ? 'lore=[' + parts.join(',') + ']' : '';
}

function cunimobCustomDataComponent(data) {
  var parts = ['cuniculum_loot:1b'];
  var keys = Object.keys(data || {});
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    var value = data[key];
    if (typeof value === 'number') {
      parts.push(key + ':' + value);
    } else if (typeof value === 'boolean') {
      parts.push(key + ':' + (value ? '1b' : '0b'));
    } else {
      parts.push(key + ':"' + String(value || '').replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"');
    }
  }
  return 'custom_data={' + parts.join(',') + '}';
}

function cunimobApotheosisRarityComponent(rarity) {
  var profile = cunimobApothItemRarityByKey(rarity && (rarity.key || rarity.apoth || rarity));
  return 'apotheosis:rarity="' + profile.apoth + '"';
}

function cunimobEnchantComponent(enchants) {
  var parts = [];
  var keys = Object.keys(enchants || {});
  for (var i = 0; i < keys.length; i++) {
    var level = Math.max(1, Math.floor(Number(enchants[keys[i]] || 1)));
    parts.push('"' + keys[i] + '":' + level);
  }
  if (!parts.length) {
    return '';
  }
  return 'enchantments={levels:{' + parts.join(',') + '},show_in_tooltip:true}';
}

function cunimobMiningShapeLabel(shape) {
  if (shape === '3x3') return 'Mineria especial: area 3x3';
  if (shape === '2x3') return 'Mineria especial: area 2x3';
  if (shape === '3x2') return 'Mineria especial: area 3x2';
  if (shape === '2x2') return 'Mineria especial: area 2x2';
  if (shape === '1x3') return 'Mineria especial: linea 1x3';
  if (shape === '1x2') return 'Mineria especial: linea 1x2';
  return '';
}

function cunimobToolRoleLabel(role) {
  if (role === 'miner') return 'Funcion: mineria y excavacion profunda';
  if (role === 'wood') return 'Funcion: tala y combate pesado';
  if (role === 'dig') return 'Funcion: excavacion rapida';
  if (role === 'farm') return 'Funcion: cultivo, sustento y suerte';
  if (role === 'fish') return 'Funcion: pesca, suerte y exploracion acuatica';
  return '';
}

function cunimobTraitLabel(trait) {
  if (trait === 'tunelero') return 'Rasgo: Tunelero - prisa de minado';
  if (trait === 'prospero') return 'Rasgo: Prospero - suerte al explorar';
  if (trait === 'vigia') return 'Rasgo: Vigia - vision y alerta';
  if (trait === 'ligero') return 'Rasgo: Ligero - movilidad';
  if (trait === 'baluarte') return 'Rasgo: Baluarte - resistencia';
  if (trait === 'sanguino') return 'Rasgo: Sanguino - recuperacion leve';
  if (trait === 'arcano') return 'Rasgo: Arcano - proteccion elemental';
  if (trait === 'devastador') return 'Rasgo: Devastador - fuerza';
  if (trait === 'cosechador') return 'Rasgo: Cosechador - sustento';
  if (trait === 'salto') return 'Rasgo: Saltador - impulso vertical';
  if (trait === 'quebrantador') return 'Rasgo: Quebrantador - golpe pesado';
  if (trait === 'ojo_halcon') return 'Rasgo: Ojo de Halcon - precision';
  if (trait === 'estable') return 'Rasgo: Paso Firme - minado seguro';
  if (trait === 'excavador') return 'Rasgo: Excavador - avance rapido';
  if (trait === 'lenador') return 'Rasgo: Lenador - tala agresiva';
  if (trait === 'pescador') return 'Rasgo: Arroyo Oculto - respiracion y movilidad acuatica';
  if (trait === 'prismal') return 'Rasgo: Prisma de Refugio - defensa magica';
  if (trait === 'eco_pradera') return 'Rasgo: Eco de Pradera - vida y sustento';
  if (trait === 'bruma') return 'Rasgo: Bruma Baja - escape y salto';
  if (trait === 'cazador') return 'Rasgo: Cazador de Galeria - dano sostenido';
  if (trait === 'respirador') return 'Rasgo: Branquia de Arroyo - respiracion bajo agua';
  if (trait === 'termico') return 'Rasgo: Abrigo de Madriguera - defensa contra extremos';
  if (trait === 'ignifugo') return 'Rasgo: Brasa Serena - fuego controlado';
  if (trait === 'pluma') return 'Rasgo: Pluma de Salto - caidas suaves';
  if (trait === 'nadador') return 'Rasgo: Corriente Baja - velocidad en agua';
  if (trait === 'zancada') return 'Rasgo: Zancada de Prado - avance veloz';
  if (trait === 'centinela') return 'Rasgo: Centinela - alerta y defensa';
  if (trait === 'marea') return 'Rasgo: Marea Oculta - dominio acuatico';
  if (trait === 'escarcha') return 'Rasgo: Escarcha Mansa - firmeza ante frio';
  if (trait === 'aereo') return 'Rasgo: Brisa Alta - caida lenta y movilidad';
  if (trait === 'fundidor') return 'Rasgo: Fundidor de Galeria - puede cocinar minerales al picar';
  return '';
}

function cunimobTraitsFromData(data) {
  var traits = [];
  var itemData = data || {};
  if (itemData.cuniculum_trait) traits.push(itemData.cuniculum_trait);
  if (itemData.cuniculum_trait2) traits.push(itemData.cuniculum_trait2);
  if (itemData.cuniculum_trait3) traits.push(itemData.cuniculum_trait3);
  return traits;
}

function cunimobTraitLoreLines(data) {
  var traits = cunimobTraitsFromData(data);
  var lines = [];
  for (var i = 0; i < traits.length; i++) {
    var label = cunimobTraitLabel(traits[i]);
    if (label) {
      lines.push({ text: label, color: i === 0 ? 'gold' : 'yellow' });
    }
  }
  return lines;
}

function cunimobBuildDropItem(itemId, name, color, enchants, data) {
  var itemData = data || {};
  if (typeof cunirpgApplySetData === 'function') {
    itemData = cunirpgApplySetData(itemId, name, itemData);
  }
  var apothRarity = cunimobApothItemRarityByKey(itemData.cuniculum_apotheosis_rarity || itemData.cuniculum_apoth_rarity || itemData.cuniculum_rarity);
  itemData.cuniculum_apotheosis_rarity = apothRarity.key;
  itemData.cuniculum_apotheosis_id = apothRarity.apoth;
  itemData.cuniculum_apotheosis_salvage = true;
  itemData.cuniculum_salvage_material = apothRarity.key;
  var components = [
    cunimobItemNameComponent(name, color || apothRarity.color),
    cunimobCustomDataComponent(itemData),
    cunimobApotheosisRarityComponent(apothRarity)
  ];
  var loreLines = [
    { text: 'Rareza Apotheosis: ' + apothRarity.label, color: apothRarity.color },
    { text: 'Origen: CUNICULUM', color: 'dark_gray' },
    { text: 'Reciclaje CUNICULUM: materiales Apotheosis', color: 'dark_gray' },
    itemData.cuniculum_tier ? { text: 'Tier RPG: ' + itemData.cuniculum_tier, color: 'gray' } : null,
    itemData.cuniculum_tool ? { text: cunimobToolRoleLabel(itemData.cuniculum_tool), color: 'dark_aqua' } : null,
    itemData.cuniculum_mining_shape ? { text: cunimobMiningShapeLabel(itemData.cuniculum_mining_shape), color: 'aqua' } : null
  ];
  if (itemData.cuniculum_set_id && typeof cunirpgSetLoreLines === 'function') {
    var setLines = cunirpgSetLoreLines(itemData);
    for (var s = 0; s < setLines.length; s++) {
      loreLines.push(setLines[s]);
    }
  }
  var traitLines = cunimobTraitLoreLines(itemData);
  for (var t = 0; t < traitLines.length; t++) {
    loreLines.push(traitLines[t]);
  }
  var loreComponent = cunimobLoreComponent(loreLines);
  if (loreComponent) {
    components.push(loreComponent);
  }
  var enchantComponent = cunimobEnchantComponent(enchants || {});
  if (enchantComponent) {
    components.push(enchantComponent);
  }
  return itemId + '[' + components.join(',') + ']';
}

function cunimobDropChance(base, level, tier, boss, kind, rarity) {
  var growth = kind === 'armor' ? 0.00022 : (kind === 'tool' ? 0.00016 : 0.00019);
  var cap = kind === 'armor' ? 0.076 : (kind === 'tool' ? 0.050 : 0.064);
  var profile = rarity || cunimobRarityProfileByKey('common');
  var bonus = Math.max(0, level - Number(tier.min || 1)) * growth + Number(profile.lootBonus || 0);
  if (boss) {
    bonus += kind === 'armor' ? 0.014 : 0.011;
  }
  var chance = Math.min(cap + Math.max(0, Number(profile.weight || 1) - 1) * 0.004, Number(base || 0) + bonus);
  return chance * (boss ? CUNIMOB_BOSS_EQUIPMENT_DROP_RATE_MULTIPLIER : CUNIMOB_EQUIPMENT_DROP_RATE_MULTIPLIER);
}

function cunimobEnchantRollChance(level, tier, boss, rarity, itemRarity) {
  var profile = rarity || cunimobRarityProfileByKey('common');
  var quality = itemRarity || cunimobApothItemRarityByKey('common');
  var effectiveLevel = cunimobComplexityLevel(level, profile);
  var chance = Number(tier.enchantChance || 0) * 0.82 + Math.max(0, effectiveLevel - Number(tier.min || 1)) * 0.0018 + Number(profile.enchantBonus || 0) + Math.max(0, Number(quality.weight || 1) - 1) * 0.067;
  if (boss) {
    chance += 0.10;
  }
  var qualityCap = quality.weight >= 5 ? 0.98 : (quality.weight >= 4 ? 0.90 : (quality.weight >= 3 ? 0.76 : (quality.weight >= 2 ? 0.58 : 0.34)));
  return Math.min(qualityCap, chance);
}

function cunimobEnchantPower(level, tier, rarity, itemRarity) {
  var profile = rarity || cunimobRarityProfileByKey('common');
  var quality = itemRarity || cunimobApothItemRarityByKey('common');
  var effectiveLevel = cunimobComplexityLevel(level, profile);
  var max = Math.max(1, Math.floor(Number(tier.maxEnchant || 1)) + Math.floor(Math.max(0, Number(profile.weight || 1) - 1) / 2) + Math.floor(Math.max(0, Number(quality.weight || 1) - 1) / 2));
  var value = 1;
  if (effectiveLevel >= 95) {
    value = Math.min(max, 7);
  } else if (effectiveLevel >= 75) {
    value = Math.min(max, 6);
  } else if (effectiveLevel >= 55) {
    value = Math.min(max, 5);
  } else if (effectiveLevel >= 35) {
    value = Math.min(max, 4);
  } else if (effectiveLevel >= 18) {
    value = Math.min(max, 3);
  } else if (effectiveLevel >= 8) {
    value = Math.min(max, 2);
  }
  value += Math.floor(Math.max(0, Number(quality.weight || 1) - 1) / 3);
  return Math.max(1, Math.min(max, value));
}

function cunimobIsToolItem(itemId) {
  return itemId.indexOf('_pickaxe') >= 0 || itemId.indexOf('_axe') >= 0 || itemId.indexOf('_shovel') >= 0 || itemId.indexOf('_hoe') >= 0 || itemId.indexOf('oritech:hand_drill') === 0 || itemId.indexOf('oritech:chainsaw') === 0;
}

function cunimobIsArmorItem(itemId) {
  return itemId.indexOf('_helmet') >= 0 || itemId.indexOf('_chestplate') >= 0 || itemId.indexOf('_leggings') >= 0 || itemId.indexOf('_boots') >= 0 || itemId.indexOf('_head') >= 0 || itemId.indexOf('_chest') >= 0 || itemId.indexOf('_legs') >= 0 || itemId.indexOf('_feet') >= 0;
}

function cunimobWeaponFamily(itemId) {
  var id = String(itemId || '').toLowerCase();
  if (id.indexOf('crossbow') >= 0) return 'crossbow';
  if (id.indexOf('bow') >= 0) return 'bow';
  if (id.indexOf('staff') >= 0 || id.indexOf('wand') >= 0) return 'staff';
  if (id.indexOf('spear') >= 0) return 'spear';
  if (id.indexOf('dagger') >= 0) return 'dagger';
  if (id.indexOf('knuckle') >= 0) return 'knuckle';
  if (id.indexOf('hammer') >= 0 || id.indexOf('mace') >= 0) return 'heavy';
  if (id.indexOf('axe') >= 0) return 'axe';
  return 'blade';
}

function cunimobWeaponEnchantForMob(mobId, itemId) {
  if (itemId.indexOf('bow') >= 0) {
    return itemId.indexOf('crossbow') >= 0 ? 'minecraft:quick_charge' : 'minecraft:power';
  }
  var rule = cunimobRequiredSlayerRule(mobId);
  if (rule && rule.enchants && rule.enchants.length) {
    return rule.enchants[0];
  }
  return 'minecraft:sharpness';
}

function cunimobMiningShapeForDrop(level, tier, itemRarity, role) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var tierIndex = cunimobTierPowerIndex(tier);
  var qualityWeight = Math.max(1, Number(itemRarity && itemRarity.weight || 1));
  var score = safeLevel + tierIndex * 8 + qualityWeight * 6;
  if (role === 'farm') {
    return '';
  }
  if (score >= 95 && Math.random() < 0.42) {
    return '3x3';
  }
  if (score >= 76 && Math.random() < 0.30) {
    return Math.random() < 0.5 ? '2x3' : '3x2';
  }
  if (score >= 60 && Math.random() < 0.34) {
    return '2x2';
  }
  if (score >= 30 && Math.random() < 0.28) {
    return '1x3';
  }
  if (score >= 20 && Math.random() < 0.22) {
    return '1x2';
  }
  return '';
}

function cunimobAddUniqueTrait(list, trait) {
  if (!trait) {
    return;
  }
  for (var i = 0; i < list.length; i++) {
    if (list[i] === trait) {
      return;
    }
  }
  list.push(trait);
}

function cunimobClampChance(value) {
  return Math.max(0, Math.min(0.98, Number(value || 0)));
}

function cunimobRollEnchantLevel(maxLevel, effectiveLevel, qualityWeight, baseChance) {
  var cap = Math.max(1, Math.floor(Number(maxLevel || 1)));
  var safeLevel = Math.max(1, Math.floor(Number(effectiveLevel || 1)));
  var quality = Math.max(1, Number(qualityWeight || 1));
  var result = 0;
  for (var level = 1; level <= cap; level++) {
    var gate = 1 + (level - 1) * 18;
    var chance = Number(baseChance || 0.35)
      + Math.max(0, safeLevel - gate) * 0.0048
      + Math.max(0, quality - 1) * 0.035
      - Math.max(0, level - 1) * 0.135;
    if (level >= 4) {
      chance -= (level - 3) * 0.10;
    }
    if (Math.random() < cunimobClampChance(chance)) {
      result = level;
    } else if (level > 1 && Math.random() < 0.62) {
      break;
    }
  }
  return result;
}

function cunimobMaybeEnchant(enchants, id, maxLevel, effectiveLevel, qualityWeight, baseChance) {
  var rolled = cunimobRollEnchantLevel(maxLevel, effectiveLevel, qualityWeight, baseChance);
  if (rolled > 0) {
    enchants[id] = rolled;
  }
  return rolled;
}

function cunimobTraitPoolForDrop(kind, role, family, itemId) {
  var id = String(itemId || '').toLowerCase();
  var pool = [];
  if (kind === 'armor') {
    pool = ['baluarte', 'vigia', 'ligero', 'sanguino', 'arcano', 'prismal', 'eco_pradera', 'centinela'];
    if (id.indexOf('_boots') >= 0 || id.indexOf('_feet') >= 0) pool.push('salto', 'pluma', 'zancada');
    if (id.indexOf('_helmet') >= 0 || id.indexOf('_head') >= 0) pool.push('vigia', 'respirador', 'centinela');
    if (id.indexOf('_chestplate') >= 0 || id.indexOf('_chest') >= 0 || id.indexOf('robe') >= 0) pool.push('baluarte', 'termico', 'ignifugo', 'escarcha');
    if (id.indexOf('_leggings') >= 0 || id.indexOf('_legs') >= 0) pool.push('ligero', 'nadador', 'zancada', 'bruma');
    if (id.indexOf('frost') >= 0 || id.indexOf('glacier') >= 0) pool.push('escarcha', 'termico');
    if (id.indexOf('fire') >= 0 || id.indexOf('scarlet') >= 0 || id.indexOf('crusader') >= 0) pool.push('ignifugo', 'baluarte');
    if (id.indexOf('ocean') >= 0 || id.indexOf('kelp') >= 0 || id.indexOf('aqua') >= 0) pool.push('marea', 'respirador');
    return pool;
  }
  if (kind === 'tool') {
    if (role === 'miner') return ['tunelero', 'prospero', 'vigia', 'estable', 'bruma', 'fundidor'];
    if (role === 'wood') return ['lenador', 'devastador', 'ligero', 'cazador', 'fundidor'];
    if (role === 'dig') return ['excavador', 'ligero', 'prospero', 'bruma', 'fundidor'];
    if (role === 'farm') return ['cosechador', 'prospero', 'vigia', 'eco_pradera'];
    if (role === 'fish') return ['pescador', 'prospero', 'vigia', 'bruma'];
    return ['prospero', 'ligero', 'vigia'];
  }
  if (family === 'bow' || family === 'crossbow') return ['ojo_halcon', 'ligero', 'prospero', 'vigia', 'cazador'];
  if (family === 'dagger') return ['ligero', 'sanguino', 'salto', 'bruma'];
  if (family === 'heavy' || family === 'axe') return ['devastador', 'baluarte', 'quebrantador', 'cazador'];
  if (family === 'staff') return ['arcano', 'sanguino', 'vigia', 'prismal'];
  if (family === 'spear' || family === 'knuckle') return ['ligero', 'devastador', 'salto', 'cazador'];
  return ['devastador', 'sanguino', 'baluarte', 'cazador'];
}

function cunimobRollDropTraits(level, tier, itemRarity, kind, role, family, itemId) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var tierIndex = cunimobTierPowerIndex(tier);
  var qualityWeight = Math.max(1, Number(itemRarity && itemRarity.weight || 1));
  var score = safeLevel + tierIndex * 9 + qualityWeight * 8;
  var pool = cunimobTraitPoolForDrop(kind, role || 'utility', family || '', itemId);
  var traits = [];
  if (!pool.length || score < 12) {
    return traits;
  }

  var primaryChance = Math.min(0.78, 0.08 + score * 0.004 + Math.max(0, qualityWeight - 1) * 0.055);
  var secondChance = Math.min(0.42, 0.03 + Math.max(0, score - 35) * 0.003 + Math.max(0, qualityWeight - 2) * 0.05);
  var thirdChance = Math.min(0.18, 0.01 + Math.max(0, score - 85) * 0.0018 + Math.max(0, qualityWeight - 4) * 0.04);
  if (Math.random() < primaryChance) {
    cunimobAddUniqueTrait(traits, cunimobRandomChoice(pool));
  }
  if (score >= 35 && Math.random() < secondChance) {
    cunimobAddUniqueTrait(traits, cunimobRandomChoice(pool));
  }
  if (score >= 85 && qualityWeight >= 4 && Math.random() < thirdChance) {
    cunimobAddUniqueTrait(traits, cunimobRandomChoice(pool));
  }
  return traits;
}

function cunimobAssignDropTraits(data, traits, level, tier, itemRarity) {
  var itemData = data || {};
  var safeTraits = traits || [];
  if (!safeTraits.length) {
    return itemData;
  }
  itemData.cuniculum_trait = safeTraits[0];
  if (safeTraits.length > 1) itemData.cuniculum_trait2 = safeTraits[1];
  if (safeTraits.length > 2) itemData.cuniculum_trait3 = safeTraits[2];
  itemData.cuniculum_trait_power = Math.max(1, Math.min(5, Math.floor((Number(level || 1) + cunimobTierPowerIndex(tier) * 12 + Math.max(1, Number(itemRarity && itemRarity.weight || 1)) * 10) / 25)));
  return itemData;
}

function cunimobHasApothicEnchant(enchants) {
  if (!enchants) {
    return false;
  }
  for (var key in enchants) {
    if (String(key || '').indexOf('apothic_enchanting:') === 0) {
      return true;
    }
  }
  return false;
}

function cunimobSafeApothicLevel(maxLevel, level, qualityWeight, bias) {
  var safeMax = Math.max(1, Number(maxLevel || 1));
  var score = Math.max(1, Number(level || 1)) + Math.max(0, Number(qualityWeight || 1) - 1) * 11 + Math.max(0, Number(bias || 0));
  if (safeMax <= 1) {
    return 1;
  }
  var chance2 = Math.min(0.78, 0.12 + score * 0.006);
  var chance3 = Math.min(0.46, 0.04 + Math.max(0, score - 28) * 0.004);
  var chance4 = Math.min(0.24, 0.02 + Math.max(0, score - 55) * 0.0028);
  var chance5 = Math.min(0.14, 0.01 + Math.max(0, score - 85) * 0.0018);
  var value = 1;
  if (safeMax >= 2 && Math.random() < chance2) value = 2;
  if (safeMax >= 3 && Math.random() < chance3) value = 3;
  if (safeMax >= 4 && Math.random() < chance4) value = 4;
  if (safeMax >= 5 && Math.random() < chance5) value = 5;
  return Math.min(safeMax, value);
}

function cunimobEnsureApothicDropEnchant(enchants, itemId, kind, level, tier, quality) {
  var result = enchants || {};
  if (cunimobHasApothicEnchant(result)) {
    return result;
  }
  var id = String(itemId || '').toLowerCase();
  var itemKind = kind || (cunimobIsArmorItem(id) ? 'armor' : (cunimobIsToolItem(id) ? 'tool' : 'weapon'));
  var weight = Math.max(1, Number(quality && quality.weight || 1));

  if (itemKind === 'armor' || cunimobIsArmorItem(id)) {
    if (id.indexOf('_chest') >= 0 || id.indexOf('robe_chest') >= 0 || id.indexOf('_chestplate') >= 0) {
      result[Math.random() < 0.55 ? 'apothic_enchanting:icy_thorns' : 'apothic_enchanting:berserkers_fury'] = cunimobSafeApothicLevel(3, level, weight, 8);
    } else if (id.indexOf('_legs') >= 0 || id.indexOf('_leggings') >= 0) {
      result['apothic_enchanting:rebounding'] = cunimobSafeApothicLevel(3, level, weight, 4);
    } else if (id.indexOf('_feet') >= 0 || id.indexOf('_boots') >= 0) {
      result['apothic_enchanting:stable_footing'] = 1;
    } else {
      result['apothic_enchanting:life_mending'] = cunimobSafeApothicLevel(3, level, weight, 0);
      if (result['minecraft:mending']) {
        delete result['minecraft:mending'];
      }
    }
    return result;
  }

  if (itemKind === 'tool' || cunimobIsToolItem(id)) {
    if (id.indexOf('_axe') >= 0 && id.indexOf('pickaxe') < 0) {
      result['apothic_enchanting:chainsaw'] = 1;
    } else if (id.indexOf('_hoe') >= 0) {
      result['apothic_enchanting:natures_blessing'] = cunimobSafeApothicLevel(3, level, weight, 0);
    } else if (id.indexOf('_pickaxe') >= 0 || id.indexOf('drill') >= 0) {
      result[Math.random() < 0.48 ? 'apothic_enchanting:boon_of_the_earth' : 'apothic_enchanting:miners_fervor'] = cunimobSafeApothicLevel(5, level, weight, 4);
    } else {
      result['apothic_enchanting:life_mending'] = cunimobSafeApothicLevel(3, level, weight, 0);
      if (result['minecraft:mending']) {
        delete result['minecraft:mending'];
      }
    }
    return result;
  }

  if (id.indexOf('crossbow') >= 0) {
    result['apothic_enchanting:crescendo_of_bolts'] = cunimobSafeApothicLevel(5, level, weight, 4);
  } else if (id.indexOf('bow') >= 0) {
    if (result['minecraft:infinity']) {
      result['apothic_enchanting:life_mending'] = cunimobSafeApothicLevel(3, level, weight, 0);
      if (result['minecraft:mending']) {
        delete result['minecraft:mending'];
      }
    } else {
      result['apothic_enchanting:endless_quiver'] = 1;
    }
  } else if (id.indexOf('shield') >= 0) {
    result['apothic_enchanting:reflective_defenses'] = cunimobSafeApothicLevel(5, level, weight, 0);
  } else {
    var roll = Math.random();
    if (roll < 0.38) {
      result['apothic_enchanting:scavenger'] = cunimobSafeApothicLevel(3, level, weight, 0);
    } else if (roll < 0.72) {
      result['apothic_enchanting:knowledge_of_the_ages'] = cunimobSafeApothicLevel(3, level, weight, 0);
    } else {
      result['apothic_enchanting:life_mending'] = cunimobSafeApothicLevel(3, level, weight, 0);
      if (result['minecraft:mending']) {
        delete result['minecraft:mending'];
      }
    }
  }
  return result;
}

function cunimobEnchantmentsForDrop(itemId, level, tier, mobId, kind, rarity, itemRarity) {
  var enchants = {};
  var effectiveLevel = cunimobComplexityLevel(level, rarity);
  var quality = itemRarity || cunimobApothItemRarityByKey('common');
  var qualityWeight = Math.max(1, Number(quality.weight || 1));
  var power = cunimobEnchantPower(level, tier, rarity, quality);
  var unbreaking = Math.min(5, Math.max(1, Math.floor(power / 2) + (effectiveLevel >= 35 ? 2 : 1)));

  if (kind === 'armor' || cunimobIsArmorItem(itemId)) {
    var armorId = String(itemId || '').toLowerCase();
    var maxProtection = Math.min(4, Math.max(2, power));
    var primaryProtection = 'minecraft:protection';
    var protectionRoll = Math.random();
    if (armorId.indexOf('_chestplate') >= 0 || armorId.indexOf('_chest') >= 0 || armorId.indexOf('robe') >= 0) {
      if (protectionRoll < 0.22) primaryProtection = 'minecraft:fire_protection';
      else if (protectionRoll < 0.40) primaryProtection = 'minecraft:blast_protection';
    } else if (armorId.indexOf('_helmet') >= 0 || armorId.indexOf('_head') >= 0) {
      if (protectionRoll < 0.24) primaryProtection = 'minecraft:projectile_protection';
    } else if (armorId.indexOf('_boots') >= 0 || armorId.indexOf('_feet') >= 0) {
      if (protectionRoll < 0.16) primaryProtection = 'minecraft:blast_protection';
    }

    var mainProtection = cunimobMaybeEnchant(enchants, primaryProtection, maxProtection, effectiveLevel, qualityWeight, 0.58);
    if (mainProtection === 0 && (qualityWeight >= 3 || effectiveLevel >= 35) && Math.random() < 0.35) {
      enchants['minecraft:protection'] = 1;
    }
    cunimobMaybeEnchant(enchants, 'minecraft:unbreaking', Math.min(4, Math.max(2, unbreaking)), effectiveLevel, qualityWeight, 0.50);

    if (effectiveLevel >= 20 || qualityWeight >= 3) {
      cunimobMaybeEnchant(enchants, 'minecraft:thorns', Math.min(4, Math.max(1, Math.floor(power / 2) + 1)), effectiveLevel - 10, qualityWeight, 0.18);
    }
    if (effectiveLevel >= 24 || qualityWeight >= 3) {
      cunimobMaybeEnchant(enchants, 'extraspellattributes:warding', Math.min(4, Math.max(1, power - 1)), effectiveLevel - 6, qualityWeight, 0.24);
    }

    if (armorId.indexOf('_helmet') >= 0 || armorId.indexOf('_head') >= 0) {
      if ((effectiveLevel >= 12 || qualityWeight >= 2) && Math.random() < 0.58) {
        enchants['minecraft:respiration'] = Math.max(1, cunimobRollEnchantLevel(3, effectiveLevel, qualityWeight, 0.45));
      }
      if ((effectiveLevel >= 25 || qualityWeight >= 3) && Math.random() < 0.42) {
        enchants['minecraft:aqua_affinity'] = 1;
      }
    }
    if (armorId.indexOf('_boots') >= 0 || armorId.indexOf('_feet') >= 0) {
      cunimobMaybeEnchant(enchants, 'minecraft:feather_falling', Math.min(4, Math.max(2, power)), effectiveLevel, qualityWeight, 0.52);
      if ((effectiveLevel >= 18 || qualityWeight >= 2) && Math.random() < 0.45) {
        enchants['minecraft:depth_strider'] = Math.max(1, cunimobRollEnchantLevel(3, effectiveLevel, qualityWeight, 0.34));
      }
      if (effectiveLevel >= 55 && qualityWeight >= 3 && Math.random() < 0.25) {
        enchants['minecraft:soul_speed'] = Math.max(1, cunimobRollEnchantLevel(3, effectiveLevel, qualityWeight, 0.18));
      }
    }
    if (armorId.indexOf('_leggings') >= 0 || armorId.indexOf('_legs') >= 0) {
      if ((effectiveLevel >= 22 || qualityWeight >= 2) && Math.random() < 0.34) {
        enchants['minecraft:swift_sneak'] = Math.max(1, cunimobRollEnchantLevel(3, effectiveLevel, qualityWeight, 0.24));
      }
    }
    if (armorId.indexOf('_chestplate') >= 0 || armorId.indexOf('_chest') >= 0 || armorId.indexOf('robe') >= 0) {
      if ((effectiveLevel >= 18 || qualityWeight >= 2) && Math.random() < 0.24 && !enchants['minecraft:fire_protection']) {
        cunimobMaybeEnchant(enchants, 'minecraft:fire_protection', Math.min(4, power), effectiveLevel, qualityWeight, 0.20);
      }
      if ((effectiveLevel >= 35 || qualityWeight >= 3) && Math.random() < 0.20 && !enchants['minecraft:blast_protection']) {
        cunimobMaybeEnchant(enchants, 'minecraft:blast_protection', Math.min(4, power), effectiveLevel, qualityWeight, 0.18);
      }
    }
    if (qualityWeight >= 4 && Math.random() < 0.18 && !enchants['minecraft:projectile_protection']) {
      cunimobMaybeEnchant(enchants, 'minecraft:projectile_protection', Math.min(4, power), effectiveLevel, qualityWeight, 0.16);
    }
    return cunimobEnsureApothicDropEnchant(enchants, itemId, kind, level, tier, quality);
  }

  if (kind === 'tool' || cunimobIsToolItem(itemId)) {
    var efficiencyLevel = cunimobRollEnchantLevel(Math.min(5, Math.max(1, power)), effectiveLevel, qualityWeight, 0.76);
    if (efficiencyLevel > 0) {
      enchants['minecraft:efficiency'] = efficiencyLevel;
    }
    cunimobMaybeEnchant(enchants, 'minecraft:unbreaking', Math.min(4, Math.max(1, unbreaking)), effectiveLevel, qualityWeight, 0.58);
    if ((qualityWeight >= 5 || effectiveLevel >= 80) && Math.random() < 0.38 + qualityWeight * 0.035) {
      enchants['minecraft:mending'] = 1;
    }
    if (effectiveLevel >= 30 && Math.random() < 0.38 + qualityWeight * 0.06) {
      enchants['apothic_enchanting:miners_fervor'] = 1;
    }
    if (effectiveLevel >= 38 && Math.random() < 0.22 + qualityWeight * 0.04) {
      enchants['apothic_enchanting:boon_of_the_earth'] = 1;
    }
    if (itemId.indexOf('_axe') >= 0 && effectiveLevel >= 45 && Math.random() < 0.18 + qualityWeight * 0.04) {
      enchants['apothic_enchanting:chainsaw'] = 1;
    }
    if (effectiveLevel >= 50 && qualityWeight >= 3 && Math.random() < 0.20) {
      enchants['apothic_enchanting:stable_footing'] = 1;
    }
    if (itemId.indexOf('_hoe') >= 0) {
      cunimobMaybeEnchant(enchants, 'minecraft:fortune', Math.min(4, Math.max(1, Math.floor(power / 2))), effectiveLevel, qualityWeight, 0.44);
      if (effectiveLevel >= 35 && Math.random() < 0.30) {
        enchants['apothic_enchanting:natures_blessing'] = 1;
      }
    } else if (effectiveLevel >= 18 && Math.random() < 0.72) {
      cunimobMaybeEnchant(enchants, 'minecraft:fortune', Math.min(4, Math.max(1, Math.floor(power / 2))), effectiveLevel, qualityWeight, 0.38);
    } else if (effectiveLevel >= 35 && Math.random() < 0.28 + qualityWeight * 0.04) {
      enchants['minecraft:silk_touch'] = 1;
    }
    return cunimobEnsureApothicDropEnchant(enchants, itemId, kind, level, tier, quality);
  }

  var mainEnchant = cunimobWeaponEnchantForMob(mobId, itemId);
  var weaponPower = cunimobRollEnchantLevel(Math.min(5, Math.max(1, power)), effectiveLevel, qualityWeight, 0.76);
  if (weaponPower > 0) {
    enchants[mainEnchant] = weaponPower;
  }
  cunimobMaybeEnchant(enchants, 'minecraft:unbreaking', Math.min(4, Math.max(1, unbreaking)), effectiveLevel, qualityWeight, 0.52);
  if (itemId.indexOf('crossbow') >= 0) {
    if (Math.random() < 0.24 + qualityWeight * 0.045) {
      enchants['minecraft:mending'] = 1;
    }
    if (effectiveLevel >= 35) {
      cunimobMaybeEnchant(enchants, 'minecraft:piercing', Math.min(5, power), effectiveLevel, qualityWeight, 0.46);
    }
    if (effectiveLevel >= 70) {
      enchants['minecraft:multishot'] = 1;
    }
    if (effectiveLevel >= 45 && Math.random() < 0.34 + qualityWeight * 0.05) {
      enchants['apothic_enchanting:crescendo_of_bolts'] = 1;
    }
  } else if (itemId.indexOf('bow') >= 0) {
    if (Math.random() < 0.22 + qualityWeight * 0.045) {
      enchants['minecraft:mending'] = 1;
    }
    if (Math.random() < 0.26 + qualityWeight * 0.05) {
      enchants['minecraft:infinity'] = 1;
    }
    if (effectiveLevel >= 35) {
      enchants['minecraft:punch'] = Math.min(2, Math.max(1, Math.floor(power / 3)));
    }
    if (effectiveLevel >= 55) {
      enchants['minecraft:flame'] = 1;
    }
    if (effectiveLevel >= 60 && Math.random() < 0.25 + qualityWeight * 0.04) {
      enchants['apothic_enchanting:endless_quiver'] = 1;
    }
  } else {
    if (qualityWeight >= 5 && Math.random() < 0.40) {
      enchants['minecraft:mending'] = 1;
    }
    if (effectiveLevel >= 35) {
      enchants['minecraft:fire_aspect'] = Math.min(3, Math.max(1, Math.floor(power / 3)));
    }
    if (effectiveLevel >= 55) {
      enchants['minecraft:knockback'] = Math.min(3, Math.max(1, Math.floor(power / 4)));
    }
    if (effectiveLevel >= 30 && Math.random() < 0.24 + qualityWeight * 0.04) {
      enchants['apothic_enchanting:scavenger'] = 1;
    }
    if (effectiveLevel >= 42 && Math.random() < 0.20 + qualityWeight * 0.04) {
      enchants['apothic_enchanting:knowledge_of_the_ages'] = 1;
    }
    if (effectiveLevel >= 55 && Math.random() < 0.18 + qualityWeight * 0.035) {
      enchants['apothic_enchanting:berserkers_fury'] = 1;
    }
  }
  return cunimobEnsureApothicDropEnchant(enchants, itemId, kind, level, tier, quality);
}

function cunimobDecoratedName(base, tier, mobId, kind) {
  var rule = kind === 'weapon' ? cunimobRequiredSlayerRule(mobId) : null;
  if (rule && rule.enchants && rule.enchants[0] === 'minecraft:bane_of_arthropods') {
    return base + ' Aracnocida';
  }
  if (rule && rule.enchants && rule.enchants[0] === 'minecraft:smite') {
    return base + ' Sepulcral';
  }
  if (kind === 'tool') {
    return base + ' de Fortuna';
  }
  return base;
}

function cunimobDropTieredEquipment(event, mobId, level, boss, rarity, worldTierKey, playerClass) {
  var tier = cunimobLootTierForReward(level, boss, rarity, false, worldTierKey);
  if (!tier) {
    return;
  }

  var profile = rarity || cunimobRarityProfileByKey('common');
  var armorChance = cunimobDropChance(tier.armorChance, level, tier, boss, 'armor', profile);
  if (tier.armor && tier.armor.length && Math.random() < armorChance) {
    var armor = cunimobWeightedChoiceByClass(tier.armor, playerClass);
    var armorRarity = cunimobRollApothItemRarity(level, tier, boss, profile, 'armor', worldTierKey);
    var armorEnchants = cunimobEnchantmentsForDrop(armor.id, level, tier, mobId, 'armor', profile, armorRarity);
    var armorData = {
      cuniculum_set: tier.key,
      cuniculum_tier: tier.key,
      cuniculum_kind: 'armor',
      cuniculum_rarity: profile.key,
      cuniculum_apotheosis_rarity: armorRarity.key
    };
    cunimobAssignDropTraits(armorData, cunimobRollDropTraits(level, tier, armorRarity, 'armor', '', '', armor.id), level, tier, armorRarity);
    cunimobAddRpgDrop(event, cunimobBuildDropItem(armor.id, armor.name, armorRarity.color, armorEnchants, armorData));
  }

  if (tier.tools && tier.tools.length && Math.random() < cunimobDropChance(tier.toolChance, level, tier, boss, 'tool', profile)) {
    var tool = cunimobWeightedChoiceByClass(tier.tools, playerClass);
    var toolRarity = cunimobRollApothItemRarity(level, tier, boss, profile, 'tool', worldTierKey);
    var toolEnchants = cunimobEnchantmentsForDrop(tool.id, level, tier, mobId, 'tool', profile, toolRarity);
    var toolData = {
      cuniculum_tool: tool.role || 'utility',
      cuniculum_tier: tier.key,
      cuniculum_kind: 'tool',
      cuniculum_rarity: profile.key,
      cuniculum_apotheosis_rarity: toolRarity.key
    };
    var miningShape = cunimobMiningShapeForDrop(level, tier, toolRarity, tool.role || 'utility');
    if (miningShape) {
      toolData.cuniculum_mining_shape = miningShape;
    }
    cunimobAssignDropTraits(toolData, cunimobRollDropTraits(level, tier, toolRarity, 'tool', tool.role || 'utility', '', tool.id), level, tier, toolRarity);
    cunimobAddRpgDrop(event, cunimobBuildDropItem(tool.id, cunimobDecoratedName(tool.name, tier, mobId, 'tool'), toolRarity.color, toolEnchants, toolData));
  }

  if (tier.weapons && tier.weapons.length && Math.random() < cunimobDropChance(tier.weaponChance, level, tier, boss, 'weapon', profile)) {
    var weapon = cunimobWeightedChoiceByClass(tier.weapons, playerClass);
    var weaponRarity = cunimobRollApothItemRarity(level, tier, boss, profile, 'weapon', worldTierKey);
    var weaponEnchants = cunimobEnchantmentsForDrop(weapon.id, level, tier, mobId, 'weapon', profile, weaponRarity);
    var weaponFamily = cunimobWeaponFamily(weapon.id);
    var weaponData = {
      cuniculum_family: cunimobWeaponFamily(weapon.id),
      cuniculum_slayer: cunimobWeaponEnchantForMob(mobId, weapon.id),
      cuniculum_tier: tier.key,
      cuniculum_kind: 'weapon',
      cuniculum_rarity: profile.key,
      cuniculum_apotheosis_rarity: weaponRarity.key
    };
    weaponData.cuniculum_family = weaponFamily;
    cunimobAssignDropTraits(weaponData, cunimobRollDropTraits(level, tier, weaponRarity, 'weapon', '', weaponFamily, weapon.id), level, tier, weaponRarity);
    cunimobAddRpgDrop(event, cunimobBuildDropItem(weapon.id, cunimobDecoratedName(weapon.name, tier, mobId, 'weapon'), weaponRarity.color, weaponEnchants, weaponData));
  }
}

function cunimobGuaranteedDropKind(tier, boss) {
  var options = [];
  if (tier && tier.weapons && tier.weapons.length) {
    options.push('weapon');
    options.push('weapon');
    if (boss) {
      options.push('weapon');
    }
  }
  if (tier && tier.armor && tier.armor.length) {
    options.push('armor');
    if (boss) {
      options.push('armor');
    }
  }
  if (tier && tier.tools && tier.tools.length) {
    options.push('tool');
  }
  return cunimobRandomChoice(options);
}

function cunimobGuaranteedDropEntry(tier, kind, playerClass) {
  if (!tier || !kind) {
    return null;
  }
  if (kind === 'armor') {
    return cunimobWeightedChoiceByClass(tier.armor || [], playerClass);
  }
  if (kind === 'tool') {
    return cunimobWeightedChoiceByClass(tier.tools || [], playerClass);
  }
  return cunimobWeightedChoiceByClass(tier.weapons || [], playerClass);
}

function cunimobDropGuaranteedTieredReward(event, mobId, level, boss, rarity, category, worldTierKey, playerClass) {
  var categoryKey = cunimobCategoryKey(category);
  if (categoryKey !== CUNIMOB_CATEGORY_ELITE && categoryKey !== CUNIMOB_CATEGORY_BOSS) {
    return false;
  }

  var tier = cunimobLootTierForReward(level, boss, rarity, true, worldTierKey);
  if (!tier) {
    return false;
  }

  var profile = rarity || cunimobRarityProfileByKey('common');
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (categoryKey === CUNIMOB_CATEGORY_ELITE && Math.random() >= 0.62) {
    cunimobAddCoinDrop(event, 'minecraft:experience_bottle', Math.max(1, Math.min(6, 1 + Math.floor(safeLevel / 24))));
    return true;
  }

  var kind = cunimobGuaranteedDropKind(tier, boss || categoryKey === CUNIMOB_CATEGORY_BOSS);
  var entry = cunimobGuaranteedDropEntry(tier, kind, playerClass);
  if (!entry || !entry.id) {
    cunimobAddCoinDrop(event, 'minecraft:experience_bottle', Math.max(1, Math.min(8, 1 + Math.floor(safeLevel / 20))));
    return true;
  }

  var itemRarity = cunimobRollApothItemRarity(safeLevel, tier, boss || categoryKey === CUNIMOB_CATEGORY_BOSS, profile, kind, worldTierKey);
  itemRarity = cunimobApothItemRarityAtLeast(itemRarity, categoryKey === CUNIMOB_CATEGORY_BOSS ? 'rare' : 'uncommon');
  itemRarity = cunimobClampApothRarityToWorldTier(itemRarity, worldTierKey);
  var enchants = cunimobEnchantmentsForDrop(entry.id, safeLevel, tier, mobId, kind, profile, itemRarity);
  var data = {
    cuniculum_tier: tier.key,
    cuniculum_kind: kind,
    cuniculum_rarity: profile.key,
    cuniculum_apotheosis_rarity: itemRarity.key,
    cuniculum_guaranteed: categoryKey
  };
  if (kind === 'armor') {
    data.cuniculum_set = tier.key;
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'armor', '', '', entry.id), safeLevel, tier, itemRarity);
  } else if (kind === 'tool') {
    data.cuniculum_tool = entry.role || 'utility';
    var guaranteedShape = cunimobMiningShapeForDrop(safeLevel, tier, itemRarity, entry.role || 'utility');
    if (guaranteedShape) {
      data.cuniculum_mining_shape = guaranteedShape;
    }
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'tool', entry.role || 'utility', '', entry.id), safeLevel, tier, itemRarity);
  } else {
    var guaranteedFamily = cunimobWeaponFamily(entry.id);
    data.cuniculum_family = guaranteedFamily;
    data.cuniculum_slayer = cunimobWeaponEnchantForMob(mobId, entry.id);
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'weapon', '', guaranteedFamily, entry.id), safeLevel, tier, itemRarity);
  }

  cunimobAddRpgDrop(event, cunimobBuildDropItem(entry.id, cunimobDecoratedName(entry.name, tier, mobId, kind), itemRarity.color, enchants, data));
  return true;
}

function cunimobSpecialDropChance(drop, level, boss, rarity) {
  var profile = rarity || cunimobRarityProfileByKey('common');
  var base = Math.max(0, Number(drop && drop.chance || 0));
  var cap = Math.max(base, Number(drop && drop.cap || 0.02));
  var ultraRare = String(drop && drop.apoth || '').toLowerCase() === 'mythic' && Number(drop && drop.chance || 0) <= 0.0002;
  var growth = ultraRare ? 0.0000014 : 0.000035;
  var bonus = Math.max(0, Math.floor(Number(level || 1)) - Number(drop && drop.min || 1)) * growth;
  bonus += Math.max(0, Number(profile.weight || 1) - 1) * cap * 0.035;
  if (boss) {
    bonus += cap * 0.18;
  }
  return Math.min(cap, base + bonus) * (boss ? Math.max(CUNIMOB_SPECIAL_DROP_RATE_MULTIPLIER, 0.50) : CUNIMOB_SPECIAL_DROP_RATE_MULTIPLIER);
}

function cunimobSpecialDropItemWithApothData(itemText, apothKey) {
  var rarity = cunimobApothItemRarityByKey(apothKey || 'rare');
  var text = String(itemText || '');
  if (!text || text.indexOf('cuniculum_apotheosis_rarity') >= 0) {
    if (text && text.indexOf('apotheosis:rarity=') < 0 && text.lastIndexOf(']') > 0) {
      text = text.slice(0, text.lastIndexOf(']')) + ',' + cunimobApotheosisRarityComponent(rarity) + text.slice(text.lastIndexOf(']'));
    }
    return cunimobEnsureSpecialApothicEnchantText(text);
  }
  if (text.indexOf('custom_data={') >= 0) {
    text = text.replace('custom_data={', 'custom_data={cuniculum_apotheosis_rarity:"' + rarity.key + '",cuniculum_apotheosis_id:"' + rarity.apoth + '",');
    if (text.indexOf('cuniculum_apotheosis_salvage') < 0) {
      text = text.replace('custom_data={', 'custom_data={cuniculum_apotheosis_salvage:1b,cuniculum_salvage_material:"' + rarity.key + '",');
    }
    if (text.indexOf('apotheosis:rarity=') < 0 && text.lastIndexOf(']') > 0) {
      text = text.slice(0, text.lastIndexOf(']')) + ',' + cunimobApotheosisRarityComponent(rarity) + text.slice(text.lastIndexOf(']'));
    }
  }
  return cunimobEnsureSpecialApothicEnchantText(text);
}

function cunimobSpecialApothicEnchantForText(itemText) {
  var text = String(itemText || '').toLowerCase();
  var itemId = text.split('[')[0];
  if (!itemId || itemId.indexOf('artifacts:') === 0 || itemId.indexOf('more_jewels:') === 0 || itemId.indexOf('jewelry:') === 0) {
    return '';
  }
  if (text.indexOf('apothic_enchanting:') >= 0) {
    return '';
  }
  if (itemId.indexOf('crossbow') >= 0) return 'apothic_enchanting:crescendo_of_bolts';
  if (itemId.indexOf('bow') >= 0) return text.indexOf('minecraft:infinity') >= 0 ? 'apothic_enchanting:life_mending' : 'apothic_enchanting:endless_quiver';
  if (itemId.indexOf('_pickaxe') >= 0 || itemId.indexOf('drill') >= 0) return 'apothic_enchanting:boon_of_the_earth';
  if (itemId.indexOf('_axe') >= 0 && itemId.indexOf('pickaxe') < 0) return 'apothic_enchanting:chainsaw';
  if (itemId.indexOf('_hoe') >= 0) return 'apothic_enchanting:natures_blessing';
  if (itemId.indexOf('_chest') >= 0 || itemId.indexOf('_chestplate') >= 0 || itemId.indexOf('robe_chest') >= 0) return 'apothic_enchanting:icy_thorns';
  if (itemId.indexOf('_legs') >= 0 || itemId.indexOf('_leggings') >= 0) return 'apothic_enchanting:rebounding';
  if (itemId.indexOf('_feet') >= 0 || itemId.indexOf('_boots') >= 0) return 'apothic_enchanting:stable_footing';
  if (text.indexOf('cuniculum_kind:"weapon"') >= 0 || text.indexOf('_sword') >= 0 || text.indexOf('_dagger') >= 0 || text.indexOf('_spear') >= 0 || text.indexOf('_hammer') >= 0 || text.indexOf('_mace') >= 0 || text.indexOf('_knuckle') >= 0 || text.indexOf('staff') >= 0) return 'apothic_enchanting:scavenger';
  return 'apothic_enchanting:life_mending';
}

function cunimobEnsureSpecialApothicEnchantText(itemText) {
  var text = String(itemText || '');
  var enchant = cunimobSpecialApothicEnchantForText(text);
  if (!enchant) {
    return text;
  }
  var level = enchant === 'apothic_enchanting:endless_quiver' || enchant === 'apothic_enchanting:chainsaw' || enchant === 'apothic_enchanting:stable_footing' ? 1 : 2;
  var pair = '"' + enchant + '":' + level;
  if (text.indexOf('enchantments={levels:{') >= 0) {
    return text.replace('enchantments={levels:{', 'enchantments={levels:{' + pair + ',');
  }
  if (text.lastIndexOf(']') === text.length - 1) {
    return text.substring(0, text.length - 1) + ',enchantments={levels:{' + pair + '},show_in_tooltip:true}]';
  }
  return text;
}

function cunimobDropCategoryItems(event, level, boss, rarity, worldTierKey, playerClass) {
  var dropped = 0;
  var profile = rarity || cunimobRarityProfileByKey('common');
  var maxDrops = 1;
  for (var i = 0; i < CUNIMOB_RPG_CATEGORY_DROPS.length; i++) {
    if (dropped >= maxDrops) {
      return;
    }

    var drop = CUNIMOB_RPG_CATEGORY_DROPS[i];
    if (level < drop.min) {
      continue;
    }
    if (!cunimobWorldTierAllowsSpecialDrop(drop, worldTierKey, boss)) {
      continue;
    }

    var chance = cunimobSpecialDropChance(drop, level, boss, profile);
    var dropClass = cunimobClassFromText(String(drop.item || ''));
    if (playerClass && dropClass) {
      chance *= dropClass === playerClass ? 2.35 : 0.72;
    }
    if (Math.random() < chance) {
      cunimobAddRpgDrop(event, cunimobSpecialDropItemWithApothData(drop.item, drop.apoth));
      dropped++;
    }
  }
}

function cunimobCanDropPhantomFallback(mobId) {
  var id = String(mobId || '').toLowerCase();
  if (!id || id === 'minecraft:phantom') {
    return false;
  }
  return cunimobIsCustomRewardMob(id);
}

function cunimobDropPhantomFallback(event, mobId, level, rarity) {
  if (!cunimobCanDropPhantomFallback(mobId)) {
    return;
  }

  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var boss = cunimobIsBossMob(mobId);
  var profile = rarity || cunimobRarityProfileByKey('common');
  var chance = Math.min(0.09, 0.012 + safeLevel * 0.00055 + profile.weight * 0.006 + (boss ? 0.035 : 0));
  if (safeLevel < 10 || Math.random() >= chance) {
    return;
  }

  var amount = 1;
  if (safeLevel >= 70 && Math.random() < 0.22) {
    amount++;
  }
  if (boss && safeLevel >= 90 && Math.random() < 0.30) {
    amount++;
  }
  cunimobAddCoinDrop(event, 'minecraft:phantom_membrane', amount);
}

function cunimobEnchantItem(itemId, level, role, rarity) {
  if (!itemId || level < 5) {
    return itemId;
  }

  var effectiveLevel = cunimobComplexityLevel(level, rarity);
  var rarityBonus = rarity ? Number(rarity.enchantBonus || 0) : 0;
  var chance = Math.min(0.99, 0.14 + effectiveLevel * 0.022 + rarityBonus);
  if (Math.random() > chance) {
    return itemId;
  }

  var enchantment = 'minecraft:sharpness';
  if (itemId.indexOf('bow') >= 0 || itemId.indexOf('crossbow') >= 0) {
    enchantment = 'minecraft:power';
  }

  var enchantLevel = 1;
  if (effectiveLevel >= 95) {
    enchantLevel = 7;
  } else if (effectiveLevel >= 75) {
    enchantLevel = 6;
  } else if (effectiveLevel >= 50) {
    enchantLevel = 5;
  } else if (effectiveLevel >= 28) {
    enchantLevel = 4;
  } else if (effectiveLevel >= 20) {
    enchantLevel = 3;
  } else if (effectiveLevel >= 11) {
    enchantLevel = 2;
  }

  var unbreakingLevel = effectiveLevel >= 70 ? 5 : (effectiveLevel >= 45 ? 4 : (effectiveLevel >= 18 ? 3 : 1));
  if (role === 'armor') {
    var armorEnchants = {};
    cunimobMaybeEnchant(armorEnchants, 'minecraft:protection', Math.min(4, enchantLevel), effectiveLevel, 1, 0.52);
    cunimobMaybeEnchant(armorEnchants, 'minecraft:unbreaking', Math.min(4, unbreakingLevel), effectiveLevel, 1, 0.42);
    if (effectiveLevel >= 20) {
      cunimobMaybeEnchant(armorEnchants, 'minecraft:thorns', Math.min(4, Math.max(1, Math.floor(enchantLevel / 2) + 1)), effectiveLevel - 8, 1, 0.16);
    }
    if (effectiveLevel >= 26 && Math.random() < 0.24) {
      cunimobMaybeEnchant(armorEnchants, 'minecraft:projectile_protection', Math.min(4, enchantLevel), effectiveLevel, 1, 0.18);
    }
    var armorParts = [];
    for (var armorKey in armorEnchants) {
      armorParts.push('"' + armorKey + '":' + armorEnchants[armorKey]);
    }
    if (!armorParts.length) {
      return itemId;
    }
    var armorLevels = armorParts.join(',');
    return itemId + '[enchantments={levels:{' + armorLevels + '}}]';
  }
  return itemId + '[enchantments={levels:{"' + enchantment + '":' + enchantLevel + ',"minecraft:unbreaking":' + unbreakingLevel + '}}]';
}

function cunimobTraitAmp(level, minLevel, step, maxAmp) {
  if (level < minLevel) {
    return -1;
  }
  return Math.max(0, Math.min(maxAmp, Math.floor((level - minLevel) / step)));
}

function cunimobHealthProfile(mobId) {
  var id = String(mobId || '').toLowerCase();

  if (id === 'minecraft:creeper') {
    return { base: 6, perLevel: 0.09, curve: 0.004, cap: 28 };
  }
  if (id === 'minecraft:ghast') {
    return { base: 7, perLevel: 0.12, curve: 0.006, cap: 36 };
  }
  if (id === 'minecraft:blaze' || id === 'minecraft:breeze') {
    return { base: 10, perLevel: 0.24, curve: 0.010, cap: 64 };
  }
  if (id === 'minecraft:wolf') {
    return { base: 8, perLevel: 0.18, curve: 0.006, cap: 34 };
  }
  if (id === 'minecraft:silverfish' || id === 'minecraft:endermite' || id === 'minecraft:vex') {
    return { base: 6, perLevel: 0.22, curve: 0.010, cap: 50 };
  }
  if (id === 'minecraft:slime' || id === 'minecraft:magma_cube') {
    return { base: 10, perLevel: 0.30, curve: 0.012, cap: 74 };
  }
  if (id === 'minecraft:spider' || id === 'minecraft:cave_spider' || id === 'minecraft:bogged') {
    return { base: 10, perLevel: 0.30, curve: 0.010, cap: 76 };
  }
  if (id === 'minecraft:witch' || id === 'minecraft:evoker' || id === 'minecraft:illusioner' || id === 'minecraft:blaze' || id === 'minecraft:guardian' || id === 'minecraft:elder_guardian' || id === 'minecraft:enderman' || id === 'minecraft:breeze' || id === 'minecraft:ghast' || id.indexOf('wraith') >= 0 || id.indexOf('forgotten') >= 0) {
    return { base: 12, perLevel: 0.34, curve: 0.012, cap: 98 };
  }
  if (id === 'minecraft:polar_bear' || id === 'minecraft:hoglin' || id === 'minecraft:zoglin' || id === 'minecraft:ravager') {
    return { base: 18, perLevel: 0.42, curve: 0.014, cap: 132 };
  }
  if (id === 'minecraft:iron_golem') {
    return { base: 40, perLevel: 0.70, curve: 0.024, cap: 230 };
  }
  if (id === 'minecraft:warden' || id === 'minecraft:wither' || id === 'minecraft:ender_dragon' || cunimobIsBossMob(id)) {
    return { base: 80, perLevel: 1.15, curve: 0.050, cap: 750 };
  }

  return { base: 10, perLevel: 0.30, curve: 0.010, cap: 88 };
}

function cunimobHealthCategoryMultiplier(category, mobId) {
  var key = cunimobCategoryKey(category);
  if (key === CUNIMOB_CATEGORY_BOSS) {
    return mobId === 'minecraft:creeper' ? 1.08 : 1.50;
  }
  if (key === CUNIMOB_CATEGORY_ELITE) {
    return mobId === 'minecraft:creeper' ? 1.08 : 1.35;
  }
  return 1.0;
}

function cunimobHealthRarityMultiplier(rarity) {
  var weight = Math.max(1, Number(rarity && rarity.weight || 1));
  if (weight <= 1) {
    return 1.00;
  }
  if (weight === 2) {
    return 1.12;
  }
  if (weight === 3) {
    return 1.26;
  }
  if (weight === 4) {
    return 1.48;
  }
  if (weight === 5) {
    return 1.76;
  }
  return 2.05;
}

function cunimobHealthLootTierMultiplier(level, rarity) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var rarityWeight = Math.max(1, Number(rarity && rarity.weight || 1));
  var value = 1.0;
  if (safeLevel >= 80) {
    value += 0.22;
  } else if (safeLevel >= 55) {
    value += 0.16;
  } else if (safeLevel >= 35) {
    value += 0.10;
  } else if (safeLevel >= 25) {
    value += 0.06;
  } else if (safeLevel >= 18) {
    value += 0.03;
  }
  if (rarityWeight >= 5) {
    value += 0.08;
  } else if (rarityWeight >= 4) {
    value += 0.04;
  }
  return value;
}

function cunimobMaxHealthForLevel(mobId, level, rarity, category, dimension) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfileByKey('common');
  var healthProfile = cunimobHealthProfile(mobId);
  var growthLevel = Math.max(0, safeLevel - 1);
  var curveBonus = Math.pow(growthLevel, 1.10) * healthProfile.curve;
  var value = healthProfile.base + growthLevel * healthProfile.perLevel + curveBonus;
  var rarityMultiplier = cunimobHealthRarityMultiplier(profile);
  var lootTierMultiplier = cunimobHealthLootTierMultiplier(safeLevel, profile);
  var categoryMultiplier = cunimobHealthCategoryMultiplier(category, mobId);
  var dimensionMultiplier = cunimobDimensionHealthMultiplier(dimension);
  value = Math.floor(value * rarityMultiplier * lootTierMultiplier * categoryMultiplier * dimensionMultiplier);
  var categoryCap = Math.floor(healthProfile.cap * rarityMultiplier * lootTierMultiplier * categoryMultiplier * dimensionMultiplier);
  return Math.max(1, Math.min(categoryCap, value));
}

function cunimobApplyMaxHealth(server, positioned, mobId, level, rarity, category, dimension) {
  var health = cunimobMaxHealthForLevel(mobId, level, rarity, category, dimension);
  server.runCommandSilent(positioned + ' run attribute @s minecraft:generic.max_health base set ' + health);
  server.runCommandSilent(positioned + ' run data merge entity @s {Health:' + health + 'f}');
}

function cunimobFillHealth(server, positioned, mobId, level, rarity, category, dimension) {
  if (!server || !positioned) {
    return;
  }
  var health = cunimobMaxHealthForLevel(mobId, level, rarity, category, dimension);
  server.runCommandSilent(positioned + ' run data merge entity @s {Health:' + health + 'f}');
  server.runCommandSilent(positioned + ' run execute store result entity @s Health float 1 run attribute @s minecraft:generic.max_health get 1');
}

function cunimobBuildTargetedPositioned(prefix, mobId, radius, tag) {
  var limit = cunimobScanLimitForMob(mobId);
  return prefix + ' as @e[type=' + mobId + ',distance=..' + radius + ',tag=' + tag + ',limit=' + limit + ',sort=nearest]';
}

function cunimobScanRadiusForMob(mobId) {
  return mobId === 'minecraft:blaze' ? CUNIMOB_BLAZE_SCAN_RADIUS : CUNIMOB_NATURAL_SCAN_RADIUS;
}

function cunimobScanLimitForMob(mobId) {
  return mobId === 'minecraft:blaze' ? CUNIMOB_BLAZE_SCAN_LIMIT : CUNIMOB_NATURAL_SCAN_LIMIT;
}

function cunimobScheduleFullHealth(server, positioned, healPositioned, mobId, level, rarity, category, dimension) {
  cunimobFillHealth(server, positioned, mobId, level, rarity, category, dimension);
  [2, 4, 10, 20, 40, 80, 160, 320].forEach(function (delay, index, delays) {
    server.scheduleInTicks(delay, function () {
      cunimobApplyMaxHealth(server, healPositioned, mobId, level, rarity, category, dimension);
      cunimobFillHealth(server, healPositioned, mobId, level, rarity, category, dimension);
      if (index === delays.length - 1) {
        server.runCommandSilent(healPositioned + ' run tag @s remove ' + CUNIMOB_HEAL_TARGET_TAG);
      }
    });
  });
}

function cunimobTryApplyTrait(server, positioned, level, count, effectId, minLevel, baseChance, growth, step, maxAmp, maxCount, rarity) {
  if (count >= maxCount || level < minLevel) {
    return count;
  }

  var rarityChance = rarity ? Math.max(0, Number(rarity.weight || 1) - 1) * 0.010 : 0;
  var chance = Math.min(0.72, baseChance + Math.max(0, level - minLevel) * growth + rarityChance);
  if (Math.random() > chance) {
    return count;
  }

  var amp = cunimobTraitAmp(level, minLevel, step, maxAmp);
  server.runCommandSilent(positioned + ' run effect give @s ' + effectId + ' 999999 ' + amp + ' true');
  return count + 1;
}

function cunimobApplyMobTraits(server, positioned, level, rarity, category) {
  var effectiveLevel = cunimobComplexityLevel(level, rarity);
  var categoryKey = cunimobCategoryKey(category);
  var maxCount = effectiveLevel >= 90 ? 3 : (effectiveLevel >= 55 ? 2 : (effectiveLevel >= 30 ? 1 : 0));
  maxCount += Math.max(0, Math.min(1, Number(rarity && rarity.effectBonus || 0)));
  if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    maxCount += 1;
  } else if (categoryKey === CUNIMOB_CATEGORY_BOSS) {
    maxCount += 2;
    server.runCommandSilent(positioned + ' run effect give @s minecraft:resistance 999999 ' + Math.min(2, Math.floor(effectiveLevel / 45)) + ' true');
  }
  var count = 0;
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:strength', 18, 0.18, 0.0022, 26, 3, maxCount, rarity);
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:speed', 22, 0.14, 0.0018, 34, 3, maxCount, rarity);
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:resistance', 30, 0.10, 0.0015, 42, 2, maxCount, rarity);
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:absorption', 40, 0.10, 0.0015, 34, 3, maxCount, rarity);
  if (CUNIMOB_MOB_REGEN_TRAITS_ENABLED) {
    count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:regeneration', 55, 0.08, 0.0012, 50, 2, maxCount, rarity);
  }
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:fire_resistance', 45, 0.10, 0.0010, 999, 0, maxCount, rarity);
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:jump_boost', 55, 0.08, 0.0010, 40, 2, maxCount, rarity);
  count = cunimobTryApplyTrait(server, positioned, effectiveLevel, count, 'minecraft:glowing', 75, 0.05, 0.0008, 999, 0, maxCount, rarity);

  var followRange = Math.min(80, 24 + Math.floor(effectiveLevel * 0.32) + Number(rarity && rarity.weight || 1) * 2 + (categoryKey === CUNIMOB_CATEGORY_BOSS ? 12 : 0));
  server.runCommandSilent(positioned + ' run attribute @s minecraft:generic.follow_range base set ' + followRange);
}

function cunimobApplyDimensionTraits(server, positioned, dimension, mobId, level, rarity, category) {
  if (!server || !positioned || !dimension || !mobId) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var effectiveLevel = cunimobComplexityLevel(safeLevel, rarity);
  var categoryKey = cunimobCategoryKey(category);
  var rarityWeight = Math.max(1, Number(rarity && rarity.weight || 1));

  if (dimension === 'minecraft:the_nether' || cunimobIsNetherNativeMob(mobId)) {
    server.runCommandSilent(positioned + ' run effect give @s minecraft:fire_resistance 999999 0 true');
    server.runCommandSilent(positioned + ' run attribute @s minecraft:generic.knockback_resistance base set ' + Math.min(0.65, 0.12 + effectiveLevel * 0.003));
    if (effectiveLevel >= 28 || categoryKey !== CUNIMOB_CATEGORY_NORMAL) {
      server.runCommandSilent(positioned + ' run effect give @s minecraft:strength 999999 ' + Math.min(2, Math.floor(effectiveLevel / 55)) + ' true');
    }
    if (effectiveLevel >= 38 && Math.random() < Math.min(0.34, 0.08 + rarityWeight * 0.035 + effectiveLevel * 0.0012)) {
      server.runCommandSilent(positioned + ' run effect give @s minecraft:speed 999999 0 true');
    }
    if (categoryKey !== CUNIMOB_CATEGORY_NORMAL || effectiveLevel >= 45) {
      server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_ELITE_REFLECT_TAG);
    }
  }

  if (dimension === 'minecraft:the_end' || cunimobIsEndNativeMob(mobId)) {
    server.runCommandSilent(positioned + ' run effect give @s minecraft:slow_falling 999999 0 true');
    server.runCommandSilent(positioned + ' run attribute @s minecraft:generic.knockback_resistance base set ' + Math.min(0.72, 0.18 + effectiveLevel * 0.0035));
    if (effectiveLevel >= 22 || categoryKey !== CUNIMOB_CATEGORY_NORMAL) {
      server.runCommandSilent(positioned + ' run effect give @s minecraft:resistance 999999 ' + Math.min(1, Math.floor(effectiveLevel / 70)) + ' true');
    }
    if (effectiveLevel >= 35 || categoryKey !== CUNIMOB_CATEGORY_NORMAL) {
      server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_ELITE_BLINK_TAG);
    }
    if (effectiveLevel >= 48 && Math.random() < Math.min(0.38, 0.08 + rarityWeight * 0.04 + effectiveLevel * 0.0014)) {
      server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_ELITE_PULL_TAG);
    }
    if (categoryKey === CUNIMOB_CATEGORY_BOSS || effectiveLevel >= 60) {
      server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_ELITE_SPELL_TAG);
    }
  }
}

function cunimobApplySpecialMobState(server, positioned, mobId, level, rarity) {
  if (!server || !positioned || mobId !== 'minecraft:creeper') {
    return;
  }

  var safeLevel = cunimobComplexityLevel(level, rarity);
  var chance = Math.min(0.60, 0.035 + safeLevel * 0.0045);
  if (safeLevel >= 35) {
    chance += 0.04;
  }
  if (safeLevel >= 70) {
    chance += 0.06;
  }
  if (Math.random() < Math.min(0.72, chance)) {
    server.runCommandSilent(positioned + ' run data merge entity @s {powered:1b}');
  }

  var fuse = 30;
  if (safeLevel >= 120) {
    fuse = 10;
  } else if (safeLevel >= 80) {
    fuse = 14;
  } else if (safeLevel >= 55) {
    fuse = 18;
  } else if (safeLevel >= 35) {
    fuse = 22;
  } else if (safeLevel >= 18) {
    fuse = 26;
  }
  server.runCommandSilent(positioned + ' run data merge entity @s {Fuse:' + fuse + 's}');
}

function cunimobEliteAbilityChance(level, minLevel, baseChance, growth, cap) {
  if (level < minLevel) {
    return 0;
  }
  return Math.min(cap, baseChance + Math.max(0, level - minLevel) * growth);
}

function cunimobApplyEliteAbilityTags(server, positioned, mobId, level, source, rarity, category) {
  if (!server || !positioned || source === 'minion') {
    return;
  }

  var safeLevel = cunimobComplexityLevel(level, rarity);
  var categoryKey = cunimobIsBossMob(mobId) ? CUNIMOB_CATEGORY_BOSS : cunimobCategoryKey(category);
  if (categoryKey === CUNIMOB_CATEGORY_NORMAL && safeLevel < CUNIMOB_ELITE_SPELL_LEVEL) {
    return;
  }

  var candidates = [];
  function maybe(tag, minLevel, baseChance, growth, cap) {
    if (Math.random() < cunimobEliteAbilityChance(safeLevel, minLevel, baseChance, growth, cap)) {
      candidates.push(tag);
    }
  }

  if (categoryKey === CUNIMOB_CATEGORY_BOSS) {
    server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_ELITE_SHUFFLE_TAG);
    candidates.push(CUNIMOB_ELITE_SUMMON_TAG);
    candidates.push(CUNIMOB_ELITE_SPELL_TAG);
    maybe(CUNIMOB_ELITE_BLINK_TAG, 1, 0.62, 0.0018, 0.82);
    maybe(CUNIMOB_ELITE_REFLECT_TAG, 1, 0.58, 0.0018, 0.78);
    maybe(CUNIMOB_ELITE_SPELL_TAG, 1, 0.72, 0.0020, 0.88);
    maybe(CUNIMOB_ELITE_PULL_TAG, 12, 0.38, 0.0018, 0.66);
    maybe(CUNIMOB_ELITE_DISPEL_TAG, 10, 0.52, 0.0020, 0.78);
    maybe(CUNIMOB_ELITE_SUNDER_TAG, 8, 0.62, 0.0022, 0.86);
    maybe(CUNIMOB_ELITE_DISARM_TAG, 18, 0.28, 0.0015, 0.54);
    maybe(CUNIMOB_ELITE_SHUFFLE_TAG, 1, 0.40, 0.0014, 0.64);
    maybe(CUNIMOB_ELITE_CHAIN_TAG, 1, 0.58, 0.0018, 0.80);
    maybe(CUNIMOB_ELITE_WARCRY_TAG, 1, 0.70, 0.0020, 0.88);
    maybe(CUNIMOB_ELITE_SNARE_TAG, 1, 0.55, 0.0017, 0.76);
    maybe(CUNIMOB_ELITE_METEOR_TAG, 1, 0.42, 0.0015, 0.68);
  } else if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    maybe(CUNIMOB_ELITE_BLINK_TAG, 8, 0.20, 0.0017, 0.42);
    maybe(CUNIMOB_ELITE_REFLECT_TAG, 10, 0.18, 0.0017, 0.40);
    maybe(CUNIMOB_ELITE_SPELL_TAG, 8, 0.26, 0.0018, 0.46);
    maybe(CUNIMOB_ELITE_PULL_TAG, 24, 0.11, 0.0013, 0.28);
    maybe(CUNIMOB_ELITE_DISPEL_TAG, 18, 0.16, 0.0015, 0.34);
    maybe(CUNIMOB_ELITE_SUNDER_TAG, 16, 0.22, 0.0018, 0.42);
    maybe(CUNIMOB_ELITE_DISARM_TAG, 28, 0.05, 0.0009, 0.16);
    maybe(CUNIMOB_ELITE_SHUFFLE_TAG, 24, 0.07, 0.0011, 0.22);
    maybe(CUNIMOB_ELITE_CHAIN_TAG, 28, 0.12, 0.0012, 0.30);
    maybe(CUNIMOB_ELITE_WARCRY_TAG, 22, 0.16, 0.0014, 0.36);
    maybe(CUNIMOB_ELITE_SNARE_TAG, 20, 0.13, 0.0012, 0.30);
    maybe(CUNIMOB_ELITE_METEOR_TAG, 45, 0.08, 0.0009, 0.20);
  } else {
    maybe(CUNIMOB_ELITE_BLINK_TAG, CUNIMOB_ELITE_ABILITY_LEVEL, 0.13, 0.0024, 0.38);
    maybe(CUNIMOB_ELITE_REFLECT_TAG, CUNIMOB_ELITE_ABILITY_LEVEL, 0.14, 0.0026, 0.42);
    maybe(CUNIMOB_ELITE_SPELL_TAG, CUNIMOB_ELITE_SPELL_LEVEL, 0.18, 0.0028, 0.50);
    maybe(CUNIMOB_ELITE_PULL_TAG, 55, 0.12, 0.0020, 0.32);
    maybe(CUNIMOB_ELITE_DISPEL_TAG, 38, 0.14, 0.0026, 0.44);
    maybe(CUNIMOB_ELITE_SUNDER_TAG, 35, 0.18, 0.0030, 0.52);
    maybe(CUNIMOB_ELITE_DISARM_TAG, 50, 0.08, 0.0018, 0.28);
    maybe(CUNIMOB_ELITE_CHAIN_TAG, 55, 0.08, 0.0016, 0.26);
    maybe(CUNIMOB_ELITE_SNARE_TAG, 50, 0.08, 0.0015, 0.24);
    maybe(CUNIMOB_ELITE_WARCRY_TAG, 60, 0.07, 0.0012, 0.20);
    maybe(CUNIMOB_ELITE_METEOR_TAG, 75, 0.04, 0.0009, 0.14);
  }

  var rarityWeight = rarity ? Number(rarity.weight || 1) : 1;
  var maxAbilities = safeLevel >= 100 ? 4 : (safeLevel >= 70 ? 3 : (safeLevel >= 50 ? 2 : 1));
  if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    maxAbilities = Math.min(3, Math.max(1, maxAbilities));
  }
  if (categoryKey === CUNIMOB_CATEGORY_BOSS) {
    maxAbilities = Math.min(7, Math.max(2, maxAbilities + 2));
  }
  if (rarityWeight >= 5) {
    maxAbilities++;
  }
  if (rarityWeight >= 7) {
    maxAbilities++;
  }
  maxAbilities = Math.min(categoryKey === CUNIMOB_CATEGORY_BOSS ? 7 : 5, maxAbilities);
  var indexes = cunimobShuffledIndexes(candidates.length);
  var added = 0;
  for (var i = 0; i < indexes.length && i < maxAbilities; i++) {
    server.runCommandSilent(positioned + ' run tag @s add ' + candidates[indexes[i]]);
    added++;
  }

  var auraChance = categoryKey === CUNIMOB_CATEGORY_BOSS
    ? 1
    : (categoryKey === CUNIMOB_CATEGORY_ELITE
      ? 0.82
      : Math.min(0.18, 0.008 + safeLevel * 0.0007 + Math.max(0, rarityWeight - 1) * 0.018));
  if (added > 0 || Math.random() < auraChance) {
    server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_AURA_TAG);
  }

  if (added > 0) {
    var particle = categoryKey === CUNIMOB_CATEGORY_BOSS ? 'minecraft:soul_fire_flame' : 'minecraft:enchant';
    server.runCommandSilent(positioned + ' run particle ' + particle + ' ~ ~1.2 ~ 0.45 0.55 0.45 0.02 26 force');
    server.runCommandSilent(positioned + ' run playsound minecraft:block.enchantment_table.use hostile @a[distance=..20] ~ ~ ~ 0.35 0.85');
  }
}

function cunimobApplyEquipmentAndTraitsAt(server, dimension, x, y, z, mobId, level, source, radius, requiredTag, rarity, category) {
  if (!server || !dimension || !mobId || !cunimobIsVisualTarget(mobId) || cunimobIsBossMob(mobId)) {
    return;
  }

  var scanRadius = radius || 3;
  var requiredTagSelector = requiredTag ? ',tag=' + requiredTag : '';
  var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + requiredTagSelector + ',tag=!' + CUNIMOB_GEAR_TAG + ',limit=1,sort=nearest]';
  var targetSelector = '@e[type=' + mobId + ',distance=..' + scanRadius + requiredTagSelector + ',tag=' + CUNIMOB_GEAR_TARGET_TAG + ',limit=1,sort=nearest]';
  var positionedPrefix = 'execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z;
  var positioned = positionedPrefix + ' as ' + targetSelector;
  var healPositioned = cunimobBuildTargetedPositioned(positionedPrefix, mobId, scanRadius, CUNIMOB_HEAL_TARGET_TAG);
  var canEquip = cunimobUsesEquipmentPools(mobId);
  var profile = rarity || cunimobRarityProfile(1);
  var categoryKey = cunimobCategoryKey(category);
  var weaponPool = canEquip ? cunimobPickPool(CUNIMOB_WEAPON_POOLS, level, profile) : null;
  var armorPool = canEquip ? cunimobPickPool(CUNIMOB_ARMOR_POOLS, level, profile) : null;

  server.runCommandSilent('execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as ' + selector + ' run tag @s add ' + CUNIMOB_GEAR_TARGET_TAG);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_HEAL_TARGET_TAG);
  cunimobApplyMaxHealth(server, positioned, mobId, level, profile, categoryKey, dimension);
  if (canEquip) {
    server.runCommandSilent(positioned + ' run data merge entity @s {CanPickUpLoot:1b,HandDropChances:[0.0f,0.0f],ArmorDropChances:[0.0f,0.0f,0.0f,0.0f]}');
  }
  cunimobApplyMobTraits(server, positioned, level, profile, categoryKey);
  cunimobApplyDimensionTraits(server, positioned, dimension, mobId, level, profile, categoryKey);
  cunimobApplySpecialMobState(server, positioned, mobId, level, profile);
  cunimobApplyEliteAbilityTags(server, positioned, mobId, level, source, profile, categoryKey);

  if (canEquip && weaponPool) {
    var weaponItems = cunimobWeaponItemsForMob(mobId, weaponPool.items);
    var weapon = cunimobEnchantItem(cunimobRandomChoice(weaponItems), level, 'weapon', profile);
    if (weapon) {
      server.runCommandSilent(positioned + ' run item replace entity @s weapon.mainhand with ' + weapon + ' 1');
    }
  }

  if (canEquip && armorPool) {
    var set = cunimobRandomChoice(armorPool.sets);
    cunimobApplyArmorPieces(server, positioned, set, level, profile);
  }

  cunimobScheduleFullHealth(server, positioned, healPositioned, mobId, level, profile, categoryKey, dimension);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_GEAR_TAG);
  server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_GEAR_TARGET_TAG);
}

function cunimobApplyEquipmentAndTraitsNearPlayer(server, playerName, mobId, level, radius, requiredTag, rarity, category, dimension) {
  if (!server || !playerName || !mobId || !cunimobIsVisualTarget(mobId) || cunimobIsBossMob(mobId)) {
    return;
  }

  var scanRadius = radius || CUNIMOB_NATURAL_SCAN_RADIUS;
  var baseTag = requiredTag || CUNIMOB_LEVEL_TAG;
  var scanLimit = cunimobScanLimitForMob(mobId);
  var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + baseTag + ',tag=!' + CUNIMOB_GEAR_TAG + ',limit=' + scanLimit + ',sort=nearest]';
  var targetSelector = '@e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_GEAR_TARGET_TAG + ',limit=' + scanLimit + ',sort=nearest]';
  var positionedPrefix = 'execute at ' + playerName;
  var positioned = positionedPrefix + ' as ' + targetSelector;
  var healPositioned = cunimobBuildTargetedPositioned(positionedPrefix, mobId, scanRadius, CUNIMOB_HEAL_TARGET_TAG);
  var canEquip = cunimobUsesEquipmentPools(mobId);
  var profile = rarity || cunimobRarityProfileByKey('common');
  var categoryKey = cunimobCategoryKey(category);
  var weaponPool = canEquip ? cunimobPickPool(CUNIMOB_WEAPON_POOLS, level, profile) : null;
  var armorPool = canEquip ? cunimobPickPool(CUNIMOB_ARMOR_POOLS, level, profile) : null;

  server.runCommandSilent('execute at ' + playerName + ' as ' + selector + ' run tag @s add ' + CUNIMOB_GEAR_TARGET_TAG);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_HEAL_TARGET_TAG);
  cunimobApplyMaxHealth(server, positioned, mobId, level, profile, categoryKey, dimension);
  if (canEquip) {
    server.runCommandSilent(positioned + ' run data merge entity @s {CanPickUpLoot:1b,HandDropChances:[0.0f,0.0f],ArmorDropChances:[0.0f,0.0f,0.0f,0.0f]}');
  }
  cunimobApplyMobTraits(server, positioned, level, profile, categoryKey);
  cunimobApplyDimensionTraits(server, positioned, dimension, mobId, level, profile, categoryKey);
  cunimobApplySpecialMobState(server, positioned, mobId, level, profile);
  cunimobApplyEliteAbilityTags(server, positioned, mobId, level, 'natural', profile, categoryKey);

  if (canEquip && weaponPool) {
    var weaponItems = cunimobWeaponItemsForMob(mobId, weaponPool.items);
    var weapon = cunimobEnchantItem(cunimobRandomChoice(weaponItems), level, 'weapon', profile);
    if (weapon) {
      server.runCommandSilent(positioned + ' run item replace entity @s weapon.mainhand with ' + weapon + ' 1');
    }
  }

  if (canEquip && armorPool) {
    var set = cunimobRandomChoice(armorPool.sets);
    cunimobApplyArmorPieces(server, positioned, set, level, profile);
  }

  cunimobScheduleFullHealth(server, positioned, healPositioned, mobId, level, profile, categoryKey, dimension);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_GEAR_TAG);
  server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_GEAR_TARGET_TAG);
}

function cunimobClearKnownLevelTags(server, positioned, maxLevel) {
  if (!server || !positioned) {
    return;
  }
  var limit = Math.max(1, Math.floor(Number(maxLevel || 512)));
  for (var level = 1; level <= limit; level++) {
    server.runCommandSilent(positioned + ' run tag @s remove cuniculum_level_' + level);
  }
}

function cunimobPromoteNearbyBelowLevel(server, playerName, mobId, targetLevel, radius) {
  if (!server || !playerName || !mobId || !cunimobIsVisualTarget(mobId) || cunimobIsBossMob(mobId)) {
    return;
  }

  var safeLevel = Math.max(1, Math.floor(Number(targetLevel || 1)));
  var scanRadius = radius || CUNIMOB_NATURAL_SCAN_RADIUS;
  var maxTagSweep = Math.min(safeLevel - 1, 512);
  for (var level = 1; level <= maxTagSweep; level++) {
    var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + ',tag=cuniculum_level_' + level + ']';
    server.runCommandSilent('execute at ' + playerName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_LEVEL_TAG);
    server.runCommandSilent('execute at ' + playerName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_GEAR_TAG);
    server.runCommandSilent('execute at ' + playerName + ' as ' + selector + ' run tag @s remove cuniculum_level_' + level);
  }
}

function cunimobLevelText(level, mobId, category, dimension, rarity) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var padded = safeLevel < 10 ? '0' + safeLevel : String(safeLevel);
  return 'Nv. ' + padded + ' ' + cunimobVariantMobName(mobId, dimension, rarity, category);
}

function cunimobMinionLevelText(level, mobId, dimension) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var padded = safeLevel < 10 ? '0' + safeLevel : String(safeLevel);
  if (dimension === 'minecraft:the_nether') {
    return 'Nv. ' + padded + ' Secuaz Abisal';
  }
  if (dimension === 'minecraft:the_end') {
    return 'Nv. ' + padded + ' Secuaz del Vacio';
  }
  return 'Nv. ' + padded + ' ' + cunimobMinionDisplayName(mobId);
}

function cunimobLevelGearSuffix(level, mobId, rarity) {
  var tags = [];
  var secondary = cunimobSecondaryTags(level, rarity);
  var canEquip = cunimobUsesEquipmentPools(mobId);
  for (var i = 0; i < secondary.length && i < 2; i++) {
    var tag = secondary[i];
    if (!canEquip && (tag === 'SIN EQ' || tag === 'EQ' || tag === 'ARM' || tag.indexOf('ENC') === 0)) {
      continue;
    }
    tags.push('[' + tag + ']');
  }
  return tags.length ? ' ' + tags.join('') : '';
}

function cunimobLevelNameJson(level, mobId, source, rarity, category, dimension) {
  var labelText = source === 'minion'
    ? cunimobMinionLevelText(level, mobId, dimension)
    : cunimobLevelText(level, mobId, category, dimension, rarity);
  return JSON.stringify({
    text: labelText,
    color: cunimobColorForLevel(level, source, rarity),
    bold: true,
    italic: false
  }).replace(/'/g, "\\'");
}

function cunimobClearRarityTags(server, positioned) {
  if (!server || !positioned) {
    return;
  }
  for (var i = 0; i < CUNIMOB_RARITY_PROFILES.length; i++) {
    server.runCommandSilent(positioned + ' run tag @s remove ' + CUNIMOB_RARITY_TAG_PREFIX + CUNIMOB_RARITY_PROFILES[i].key);
  }
}

function cunimobApplyVisualNameAt(server, dimension, x, y, z, mobId, level, source, radius, requiredTag, rarityOverride, categoryOverride) {
  if (!server || !dimension || !mobId || !cunimobIsVisualTarget(mobId)) {
    return;
  }

  var scanRadius = radius || 2;
  var requiredTagSelector = requiredTag ? ',tag=' + requiredTag : '';
  var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + requiredTagSelector + ',limit=1,sort=nearest]';
  var positioned = 'execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as ' + selector;
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var rarity = rarityOverride || cunimobRollRarityProfile(safeLevel, mobId, source);
  var category = cunimobRollCategory(safeLevel, mobId, source, rarity, categoryOverride);
  rarity = cunimobBossMinimumRarity(mobId, rarity, category);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_LEVEL_TAG);
  server.runCommandSilent(positioned + ' run tag @s add cuniculum_level_' + safeLevel);
  cunimobClearRarityTags(server, positioned);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_RARITY_TAG_PREFIX + rarity.key);
  cunimobClearCategoryTags(server, positioned);
  server.runCommandSilent(positioned + ' run tag @s add ' + CUNIMOB_CATEGORY_TAG_PREFIX + category);
  server.runCommandSilent(positioned + ' run data merge entity @s {CustomName:\'' + cunimobLevelNameJson(level, mobId, source, rarity, category, dimension) + '\',CustomNameVisible:0b}');
  cunimobApplyEquipmentAndTraitsAt(server, dimension, x, y, z, mobId, safeLevel, source, scanRadius, requiredTag, rarity, category);
}

function cunimobApplyNaturalNearPlayer(server, player, levelObj) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!server || !safeName) {
    return;
  }

  var dimension = cunimobDimensionFromLevel(levelObj);
  if (!cunimobIsCombatDimension(dimension)) {
    return;
  }

  for (var i = 0; i < CUNIMOB_NATURAL_TYPES.length; i++) {
    var mobId = CUNIMOB_NATURAL_TYPES[i].id;
    if (!cunimobIsVisualTarget(mobId) || mobId.indexOf('#') === 0) {
      continue;
    }
    var level = cunimobAdjustLevelForMob(mobId, cunimobLevelForPlayer(player, levelObj, dimension, 'natural', cunimobLevelBonusForMob(mobId)));
    var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
    var scanRadius = cunimobScanRadiusForMob(mobId);
    var scanLimit = cunimobScanLimitForMob(mobId);
    cunimobPromoteNearbyBelowLevel(server, safeName, mobId, safeLevel, scanRadius);
    var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + ',tag=!' + CUNIMOB_LEVEL_TAG + ',limit=' + scanLimit + ',sort=nearest]';
    var rarity = cunimobRollRarityProfile(safeLevel, mobId, 'natural');
    var category = cunimobRollCategory(safeLevel, mobId, 'natural', rarity);
    rarity = cunimobBossMinimumRarity(mobId, rarity, category);
    server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s add ' + CUNIMOB_SCAN_TAG);
    server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s add ' + CUNIMOB_LEVEL_TAG);
    server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s add cuniculum_level_' + safeLevel);
    var rarityPositioned = 'execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest]';
    cunimobClearRarityTags(server, rarityPositioned);
    server.runCommandSilent(rarityPositioned + ' run tag @s add ' + CUNIMOB_RARITY_TAG_PREFIX + rarity.key);
    cunimobClearCategoryTags(server, rarityPositioned);
    server.runCommandSilent(rarityPositioned + ' run tag @s add ' + CUNIMOB_CATEGORY_TAG_PREFIX + category);
    server.runCommandSilent(rarityPositioned + ' run data merge entity @s {CustomName:\'' + cunimobLevelNameJson(level, mobId, 'natural', rarity, category, dimension) + '\',CustomNameVisible:0b}');
    cunimobApplyEquipmentAndTraitsNearPlayer(server, safeName, mobId, safeLevel, scanRadius, CUNIMOB_SCAN_TAG, rarity, category, dimension);
    server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s remove ' + CUNIMOB_SCAN_TAG);
  }
}

function cunimobCleanupOldDisplayLabels(server, playerName) {
  if (!server) {
    return;
  }
  for (var i = 0; i < CUNIMOB_OLD_LABEL_TAGS.length; i++) {
    var tag = CUNIMOB_OLD_LABEL_TAGS[i];
    if (playerName) {
      server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:text_display,tag=' + tag + ',distance=..128] run kill @s');
    } else {
      server.runCommandSilent('kill @e[type=minecraft:text_display,tag=' + tag + ']');
    }
  }
}

function cunimobControlIronGolemDensity(server, playerName) {
  if (!server || !playerName) {
    return;
  }

  var radius = CUNIMOB_IRON_GOLEM_FARM_RADIUS;
  var keep = CUNIMOB_IRON_GOLEM_FARM_KEEP;
  var remove = CUNIMOB_IRON_GOLEM_FARM_REMOVE;
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:iron_golem,distance=..' + radius + ',sort=nearest,limit=' + keep + '] run tag @s add ' + CUNIMOB_IRON_GOLEM_KEEP_TAG);
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:iron_golem,distance=..' + radius + ',tag=!' + CUNIMOB_IRON_GOLEM_KEEP_TAG + ',sort=furthest,limit=' + remove + '] run kill @s');
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:iron_golem,distance=..' + radius + ',tag=' + CUNIMOB_IRON_GOLEM_KEEP_TAG + '] run tag @s remove ' + CUNIMOB_IRON_GOLEM_KEEP_TAG);
}

function cunimobPlayerUuidText(player) {
  var values = [];
  try { values.push(player.uuid); } catch (ignored) { }
  try { values.push(player.stringUUID); } catch (ignored) { }
  try { values.push(player.getUUID()); } catch (ignored) { }
  try { values.push(player.getStringUUID()); } catch (ignored) { }
  try { values.push(player.getUuid()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '').trim().toLowerCase();
    if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(text)) {
      return text;
    }
  }
  return '';
}

function cunimobUuidToIntArrayNbt(uuidText) {
  var compact = String(uuidText || '').replace(/-/g, '').toLowerCase();
  if (!/^[0-9a-f]{32}$/.test(compact)) {
    return '';
  }

  var parts = [];
  for (var i = 0; i < 4; i++) {
    var value = parseInt(compact.substring(i * 8, i * 8 + 8), 16);
    if (value > 2147483647) {
      value -= 4294967296;
    }
    parts.push(value);
  }
  return '[I;' + parts.join(',') + ']';
}

function cunimobLimitTamedWolvesForOwner(server, playerName, ownerNbt) {
  if (!server || !playerName || !ownerNbt) {
    return;
  }

  var radius = CUNIMOB_TAMED_WOLF_RADIUS;
  var keep = CUNIMOB_TAMED_WOLF_MAX;
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:wolf,distance=..' + radius + ',nbt={Owner:' + ownerNbt + '},sort=nearest,limit=' + keep + '] run tag @s add ' + CUNIMOB_TAMED_WOLF_KEEP_TAG);
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:wolf,distance=..' + radius + ',nbt={Owner:' + ownerNbt + '},tag=!' + CUNIMOB_TAMED_WOLF_KEEP_TAG + ',sort=furthest] run data merge entity @s {Sitting:0b}');
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:wolf,distance=..' + radius + ',nbt={Owner:' + ownerNbt + '},tag=!' + CUNIMOB_TAMED_WOLF_KEEP_TAG + ',sort=furthest] run data remove entity @s Owner');
  server.runCommandSilent('execute at ' + playerName + ' as @e[type=minecraft:wolf,distance=..' + radius + ',tag=' + CUNIMOB_TAMED_WOLF_KEEP_TAG + '] run tag @s remove ' + CUNIMOB_TAMED_WOLF_KEEP_TAG);
}

function cunimobLimitTamedWolves(server, player) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  var uuid = cunimobPlayerUuidText(player);
  if (!server || !safeName || !uuid) {
    return;
  }

  var intNbt = cunimobUuidToIntArrayNbt(uuid);
  if (intNbt) {
    cunimobLimitTamedWolvesForOwner(server, safeName, intNbt);
  }
  cunimobLimitTamedWolvesForOwner(server, safeName, '"' + uuid + '"');
}

function cunimobEnsureVisibleNames(server) {
  return;
}
function cunihordeActive(server) {
  try {
    var until = Number(server.persistentData.cuniculum_horde_active_until_ms || 0);
    return until > Date.now();
  } catch (ignored) {
    return false;
  }
}

function cunihordeMarkActive(server) {
  try {
    server.persistentData.cuniculum_horde_active_until_ms = Date.now() + CUNIHORDE_ACTIVE_MAX_MS;
  } catch (ignored) {
  }
}

function cunihordeClearActive(server) {
  try {
    server.persistentData.cuniculum_horde_active_until_ms = 0;
  } catch (ignored) {
  }
}

function cunihordeAutoEnabled(server) {
  try {
    if (server.persistentData.cuniculum_horde_auto_enabled === undefined) {
      server.persistentData.cuniculum_horde_auto_enabled = true;
    }
    return !!server.persistentData.cuniculum_horde_auto_enabled;
  } catch (ignored) {
    return false;
  }
}

function cunihordeSetAuto(server, value) {
  try {
    server.persistentData.cuniculum_horde_auto_enabled = !!value;
  } catch (ignored) {
  }
}

function cunihordeCanAutoRun(server) {
  try {
    var last = Number(server.persistentData.cuniculum_horde_last_auto_ms || 0);
    return Date.now() - last >= CUNIHORDE_AUTO_COOLDOWN_MS;
  } catch (ignored) {
    return false;
  }
}

function cunihordeMarkAutoRun(server) {
  try {
    server.persistentData.cuniculum_horde_last_auto_ms = Date.now();
  } catch (ignored) {
  }
}

function cunihordePlayerReady(player) {
  try {
    var last = Number(player.persistentData.cuniculum_horde_last_target_ms || 0);
    return Date.now() - last >= CUNIHORDE_PLAYER_COOLDOWN_MS;
  } catch (ignored) {
    return true;
  }
}

function cunihordeMarkPlayer(player) {
  try {
    player.persistentData.cuniculum_horde_last_target_ms = Date.now();
  } catch (ignored) {
  }
}

function cunihordeSummon(server, targetName, typeKey, levelOverride) {
  var config = CUNIHORDE_TYPES[typeKey] || CUNIHORDE_TYPES.small;
  var safeName = cunihordeSafePlayer(targetName);
  if (!server || !safeName) {
    return 0;
  }

  var hordeLevel = Math.max(1, Math.floor(Number(levelOverride || config.bonus + 4)));
  for (var i = 0; i < config.count; i++) {
    var mobId = config.mobs[Math.floor(Math.random() * config.mobs.length)];
    var dx = Math.floor((Math.random() * 2 - 1) * config.radius);
    var dz = Math.floor((Math.random() * 2 - 1) * config.radius);
    var rarity = cunimobRollRarityProfile(hordeLevel, mobId, 'horde');
    var category = cunimobRollCategory(hordeLevel, mobId, 'horde', rarity);
    var nbt = `{Tags:["cuniculum_horde","${CUNIMOB_LEVEL_TAG}","${CUNIMOB_RARITY_TAG_PREFIX}${rarity.key}","${CUNIMOB_CATEGORY_TAG_PREFIX}${category}"],PersistenceRequired:0b,CustomName:'${cunimobLevelNameJson(hordeLevel, mobId, 'horde', rarity, category, 'minecraft:overworld')}',CustomNameVisible:0b}`;
    server.runCommandSilent(`execute at ${safeName} run summon ${mobId} ~${dx} ~ ~${dz} ${nbt}`);
    (function (localMobId, localRarity, localCategory) {
      server.scheduleInTicks(8, function () {
        cunimobApplyEquipmentAndTraitsNearPlayer(server, safeName, localMobId, hordeLevel, config.radius + 8, 'cuniculum_horde', localRarity, localCategory, 'minecraft:overworld');
      });
    })(mobId, rarity, category);
  }

  cunihordeMarkActive(server);
  server.scheduleInTicks(20 * 60 * 12, () => {
    cunihordeClearActive(server);
    cunihordeFeedback(server, 'La zona vuelve a estar tranquila.', 'dark_green');
  });
  cunihordeFeedback(server, `Una horda ${config.label} aparecio cerca de ${safeName}.`, config.color);
  return config.count;
}

function cunihordeRandomType(player) {
  var dimension = '';
  try { dimension = cunimobDimensionFromLevel(player.level); } catch (ignored) { }
  var progress = cunimobPlayerProgressScore(player);
  var equipment = cunimobPlayerEquipmentScore(player);
  var xpLevel = cunimobReadNumber(player, ['experienceLevel', 'xpLevel', 'getXpLevel', 'experienceLevels']);
  var pressure = Math.floor(progress * 1.2) + Math.floor(equipment * 0.35) + Math.floor(xpLevel / 3) + cunimobDimensionBonus(dimension);
  if (pressure >= 26 && Math.random() < 0.28) {
    return 'advanced';
  }
  if (pressure >= 12 && Math.random() < 0.45) {
    return 'medium';
  }
  return 'small';
}

function cunimobLevelFromEntity(entity) {
  var values = [];
  try { values.push(entity.customName); } catch (ignored) { }
  try { values.push(entity.getCustomName()); } catch (ignored) { }
  try { values.push(entity.name); } catch (ignored) { }
  try { values.push(entity.getName()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '');
    var match = text.match(/Nv\.\s*([0-9]+)/i);
    if (match) {
      return Math.max(1, Math.floor(Number(match[1])));
    }
  }

  try {
    var tags = entity.getTags ? entity.getTags() : entity.tags;
    var array = tags && tags.toArray ? tags.toArray() : tags;
    if (array && array.length) {
      for (var j = 0; j < array.length; j++) {
        var tagText = String(array[j] || '');
        var tagMatch = tagText.match(/^cuniculum_level_([0-9]+)$/i);
        if (tagMatch) {
          return Math.max(1, Math.floor(Number(tagMatch[1])));
        }
      }
    }
  } catch (ignored) {
  }

  return 1;
}

function cunimobIsPlayerEntity(entity) {
  if (!entity) {
    return false;
  }
  try {
    if (entity.isPlayer && entity.isPlayer()) {
      return true;
    }
  } catch (ignored) {
  }
  return cunimobEntityTypeId(entity) === 'minecraft:player';
}

function cunimobDamageAttacker(event) {
  var source = null;
  var values = [];
  try { source = event.source; } catch (ignored) { }
  try { if (!source) { source = event.getSource(); } } catch (ignored) { }
  if (!source) {
    return null;
  }

  try { values.push(source.actual); } catch (ignored) { }
  try { values.push(source.entity); } catch (ignored) { }
  try { values.push(source.player); } catch (ignored) { }
  try { values.push(source.getActual()); } catch (ignored) { }
  try { values.push(source.getEntity()); } catch (ignored) { }
  try { values.push(source.getDirectEntity()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    if (cunimobIsPlayerEntity(values[i])) {
      return values[i];
    }
  }

  return null;
}

function cunimobDamageSourceEntity(event) {
  var source = null;
  var values = [];
  try { source = event.source; } catch (ignored) { }
  try { if (!source) { source = event.getSource(); } } catch (ignored) { }
  if (!source) {
    return null;
  }

  try { values.push(source.actual); } catch (ignored) { }
  try { values.push(source.entity); } catch (ignored) { }
  try { values.push(source.getActual()); } catch (ignored) { }
  try { values.push(source.getEntity()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    if (values[i] && !cunimobIsPlayerEntity(values[i])) {
      return values[i];
    }
  }

  return null;
}

function cunimobDamageDirectEntityId(event) {
  var source = null;
  var values = [];
  try { source = event.source; } catch (ignored) { }
  try { if (!source) { source = event.getSource(); } } catch (ignored) { }
  if (!source) {
    return '';
  }

  try { values.push(source.direct); } catch (ignored) { }
  try { values.push(source.directEntity); } catch (ignored) { }
  try { values.push(source.getDirectEntity()); } catch (ignored) { }
  try { values.push(source.getSourcePosition && source.getSourcePosition()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var id = cunimobEntityTypeId(values[i]);
    if (id) {
      return id;
    }
  }

  return '';
}

function cunimobMainHandItemId(player) {
  if (!player) {
    return '';
  }

  var values = [];
  try { values.push(player.mainHandItem); } catch (ignored) { }
  try { values.push(player.getMainHandItem()); } catch (ignored) { }
  try { values.push(player.getInventory().getSelected()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var id = cunimobStackId(values[i]);
    if (id) {
      return id;
    }
  }

  return '';
}

function cunimobIsPlayerRangedDamage(event, player) {
  var directId = cunimobDamageDirectEntityId(event);
  if (directId === 'minecraft:arrow' || directId === 'minecraft:spectral_arrow' || directId === 'minecraft:trident') {
    return true;
  }

  var itemId = cunimobMainHandItemId(player);
  if (!itemId) {
    return false;
  }
  return cunimobIsRangedWeapon(itemId)
    || itemId === 'minecraft:trident'
    || itemId.indexOf('bow') >= 0
    || itemId.indexOf('crossbow') >= 0
    || itemId.indexOf('archers:') === 0;
}

function cunimobDamageSourceText(event) {
  var source = null;
  var values = [];
  try { source = event.source; } catch (ignored) { }
  try { if (!source) { source = event.getSource(); } } catch (ignored) { }
  if (source) {
    try { values.push(source); } catch (ignored) { }
    try { values.push(source.type); } catch (ignored) { }
    try { values.push(source.msgId); } catch (ignored) { }
    try { values.push(source.getMsgId()); } catch (ignored) { }
    try { values.push(source.getEntity()); } catch (ignored) { }
    try { values.push(source.getDirectEntity()); } catch (ignored) { }
  }
  try { values.push(cunimobDamageDirectEntityId(event)); } catch (ignored) { }
  return values.join(' ').toLowerCase();
}

function cunimobIsFallDamage(event) {
  var text = cunimobDamageSourceText(event);
  return text.indexOf('minecraft:fall') >= 0
    || text.indexOf(' damage_type:fall') >= 0
    || text.indexOf('msgid=fall') >= 0
    || /\bfall\b/.test(text);
}

function cunimobIsFireDamage(event) {
  var text = cunimobDamageSourceText(event);
  return text.indexOf('minecraft:in_fire') >= 0
    || text.indexOf('minecraft:on_fire') >= 0
    || text.indexOf('minecraft:lava') >= 0
    || text.indexOf('minecraft:hot_floor') >= 0
    || text.indexOf('minecraft:fireball') >= 0
    || text.indexOf(' damage_type:in_fire') >= 0
    || text.indexOf(' damage_type:on_fire') >= 0
    || text.indexOf(' damage_type:lava') >= 0
    || text.indexOf('msgid=in_fire') >= 0
    || text.indexOf('msgid=on_fire') >= 0
    || text.indexOf('msgid=lava') >= 0
    || /\bfire\b/.test(text)
    || /\blava\b/.test(text);
}

function cunimobIsNetherNativeMob(mobId) {
  var id = String(mobId || '').toLowerCase();
  return id === 'minecraft:wither_skeleton'
    || id === 'minecraft:wither'
    || id === 'minecraft:hoglin'
    || id === 'minecraft:zoglin'
    || id === 'minecraft:zombified_piglin'
    || id === 'minecraft:piglin'
    || id === 'minecraft:piglin_brute'
    || id === 'minecraft:blaze'
    || id === 'minecraft:ghast'
    || id === 'minecraft:magma_cube'
    || id === 'quark:foxhound'
    || id.indexOf('lava') >= 0
    || id.indexOf('nether') >= 0
    || id.indexOf('magma') >= 0;
}

function cunimobIsEndNativeMob(mobId) {
  var id = String(mobId || '').toLowerCase();
  return id === 'minecraft:enderman'
    || id === 'minecraft:shulker'
    || id === 'minecraft:endermite'
    || id === 'minecraft:ender_dragon'
    || id.indexOf('end') >= 0
    || id.indexOf('void') >= 0;
}

function cunimobShouldIgnoreFireDamage(mobId, dimension) {
  return dimension === 'minecraft:the_nether' || cunimobIsNetherNativeMob(mobId);
}

function cunimobIsMagicPlayerDamage(event, player) {
  var heldText = '';
  try {
    var stacks = cunimobHeldStacks(player);
    for (var i = 0; i < stacks.length; i++) {
      heldText += ' ' + cunimobStackText(stacks[i]) + ' ' + cunimobStackId(stacks[i]);
    }
  } catch (ignored) {
  }

  var text = (cunimobDamageSourceText(event) + ' ' + heldText).toLowerCase();
  return cunimobTextHasAny(text, [
    'magic',
    'spell',
    'spell_engine',
    'spell_power',
    'wizards:',
    'elemental_wizards',
    'staff',
    'wand',
    'arcane',
    'frost',
    'lightning',
    'soulfire',
    'fireball',
    'bards_rpg'
  ]);
}

function cunimobHasCuniculumName(entity) {
  var values = [];
  try { values.push(entity.customName); } catch (ignored) { }
  try { values.push(entity.getCustomName()); } catch (ignored) { }
  try { values.push(entity.name); } catch (ignored) { }
  try { values.push(entity.getName()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    if (/Nv\.\s*[0-9]+/i.test(String(values[i] || ''))) {
      return true;
    }
  }
  return false;
}

function cunimobEnsureLeveledFromAttacker(event, entity, attacker, dimension, mobId) {
  if (!event || !entity || !attacker || !dimension || !mobId || cunimobHasCuniculumName(entity)) {
    return cunimobLevelFromEntity(entity);
  }

  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = entity.server; } } catch (ignored) { }
  try { if (!server) { server = attacker.server; } } catch (ignored) { }
  if (!server) {
    return cunimobLevelFromEntity(entity);
  }

  var x = Math.round(Number(entity.x) * 100) / 100;
  var y = Math.round(Number(entity.y) * 100) / 100;
  var z = Math.round(Number(entity.z) * 100) / 100;
  var levelObj = event.level || attacker.level || entity.level;
  var level = cunimobAdjustLevelForMob(mobId, cunimobLevelForPlayer(attacker, levelObj, dimension, 'natural', cunimobLevelBonusForMob(mobId)));
  cunimobApplyVisualNameAt(server, dimension, x, y, z, mobId, level, 'natural', 3);
  return Math.max(1, Math.floor(Number(level || 1)));
}

function cunimobHeldStacks(player) {
  var values = [];
  try { values.push(player.mainHandItem); } catch (ignored) { }
  try { values.push(player.offHandItem); } catch (ignored) { }
  try { values.push(player.getMainHandItem()); } catch (ignored) { }
  try { values.push(player.getOffhandItem()); } catch (ignored) { }
  try { values.push(player.getInventory().getSelected()); } catch (ignored) { }
  return values;
}

function cunimobStackEnchantText(stack) {
  var values = [];
  try { values.push(String(stack)); } catch (ignored) { }
  try { values.push(stack.id); } catch (ignored) { }
  try { values.push(stack.item); } catch (ignored) { }
  try { values.push(stack.nbt); } catch (ignored) { }
  try { values.push(stack.components); } catch (ignored) { }
  try { values.push(stack.getComponents()); } catch (ignored) { }
  try { values.push(stack.enchantments); } catch (ignored) { }
  try { values.push(stack.getEnchantments()); } catch (ignored) { }
  return values.join(' ').toLowerCase();
}

function cunimobPlayerHasEnchant(player, enchantments) {
  if (!player || !enchantments || !enchantments.length) {
    return false;
  }
  var stacks = cunimobHeldStacks(player);
  for (var i = 0; i < stacks.length; i++) {
    var stack = stacks[i];
    for (var j = 0; j < enchantments.length; j++) {
      var id = String(enchantments[j] || '').toLowerCase();
      try { if (stack && stack.hasEnchantment && stack.hasEnchantment(id)) { return true; } } catch (ignored) { }
      try { if (stack && stack.getEnchantmentLevel && Number(stack.getEnchantmentLevel(id)) > 0) { return true; } } catch (ignored) { }
      try { if (stack && stack.enchantments && Number(stack.enchantments[id] || 0) > 0) { return true; } } catch (ignored) { }
    }
    var text = cunimobStackEnchantText(stacks[i]);
    for (var k = 0; k < enchantments.length; k++) {
      var id = String(enchantments[k] || '').toLowerCase();
      var shortId = id.indexOf(':') >= 0 ? id.split(':')[1] : id;
      if (text.indexOf(id) >= 0 || (shortId && text.indexOf(shortId) >= 0)) {
        return true;
      }
    }
  }
  return false;
}

function cunimobAllSlayerDamageEnchants() {
  return ['minecraft:sharpness', 'minecraft:smite', 'minecraft:bane_of_arthropods'];
}

function cunimobPlayerHasAnySlayerDamageEnchant(player) {
  return cunimobPlayerHasEnchant(player, cunimobAllSlayerDamageEnchants());
}

function cunimobArmorStacks(player) {
  var stacks = [];
  var armorSlots = cunimobArmorSlotNames();
  for (var i = 0; i < armorSlots.length; i++) {
    var stack = cunimobReadStack(player, armorSlots[i]);
    if (stack) {
      stacks.push(stack);
    }
  }
  return stacks;
}

function cunimobPlayerHasArmorEnchant(player, enchantments) {
  if (!player || !enchantments || !enchantments.length) {
    return false;
  }

  var stacks = cunimobArmorStacks(player);
  for (var i = 0; i < stacks.length; i++) {
    var stack = stacks[i];
    var text = cunimobStackEnchantText(stack);
    for (var j = 0; j < enchantments.length; j++) {
      var id = String(enchantments[j] || '').toLowerCase();
      var shortId = id.indexOf(':') >= 0 ? id.split(':')[1] : id;
      try { if (stack && stack.hasEnchantment && stack.hasEnchantment(id)) { return true; } } catch (ignored) { }
      try { if (stack && stack.getEnchantmentLevel && Number(stack.getEnchantmentLevel(id)) > 0) { return true; } } catch (ignored) { }
      try { if (stack && stack.enchantments && Number(stack.enchantments[id] || 0) > 0) { return true; } } catch (ignored) { }
      if (text.indexOf(id) >= 0 || (shortId && text.indexOf(shortId) >= 0)) {
        return true;
      }
    }
  }

  return false;
}

function cunimobEquipmentSlotConstant(slotName) {
  if (!CUNIMOB_EQUIPMENT_SLOT_CLASS || !slotName) {
    return null;
  }
  try { return CUNIMOB_EQUIPMENT_SLOT_CLASS[slotName]; } catch (ignored) { }
  try { return CUNIMOB_EQUIPMENT_SLOT_CLASS.valueOf(slotName); } catch (ignored) { }
  return null;
}

function cunimobEquipmentSlotsForPlayer() {
  return [
    { slot: 'HEAD', command: 'armor.head', label: 'casco' },
    { slot: 'CHEST', command: 'armor.chest', label: 'pechera' },
    { slot: 'LEGS', command: 'armor.legs', label: 'pantalones' },
    { slot: 'FEET', command: 'armor.feet', label: 'botas' }
  ];
}

function cunimobGetEquipmentStack(player, slotName) {
  if (!player || !slotName) {
    return null;
  }
  var slot = cunimobEquipmentSlotConstant(slotName);
  if (slot) {
    try {
      var stack = player.getItemBySlot(slot);
      if (stack && String(stack) !== 'empty' && String(stack) !== 'minecraft:air' && String(stack) !== 'Item.empty') {
        return stack;
      }
    } catch (ignored) {
    }
  }

  if (slotName === 'MAINHAND') {
    return cunimobReadStack(player, ['mainHandItem', 'getMainHandItem', 'heldItem']);
  }
  if (slotName === 'OFFHAND') {
    return cunimobReadStack(player, ['offHandItem', 'getOffHandItem']);
  }
  if (slotName === 'HEAD') {
    return cunimobReadStack(player, ['headArmorItem', 'getHeadArmorItem', 'helmetItem']);
  }
  if (slotName === 'CHEST') {
    return cunimobReadStack(player, ['chestArmorItem', 'getChestArmorItem', 'chestplateItem']);
  }
  if (slotName === 'LEGS') {
    return cunimobReadStack(player, ['legsArmorItem', 'getLegsArmorItem', 'leggingsItem']);
  }
  if (slotName === 'FEET') {
    return cunimobReadStack(player, ['feetArmorItem', 'getFeetArmorItem', 'bootsItem']);
  }

  return null;
}

function cunimobSetEquipmentStack(player, slotName, stack) {
  if (!player || !slotName || !CUNIMOB_ITEM_STACK_CLASS) {
    return false;
  }
  var slot = cunimobEquipmentSlotConstant(slotName);
  if (!slot) {
    return false;
  }
  try {
    player.setItemSlot(slot, stack || CUNIMOB_ITEM_STACK_CLASS.EMPTY);
    return true;
  } catch (ignored) {
  }
  return false;
}

function cunimobStackIsEmpty(stack) {
  if (!stack) {
    return true;
  }
  try { if (stack.isEmpty && stack.isEmpty()) { return true; } } catch (ignored) { }
  var id = cunimobStackId(stack);
  return !id || id === 'minecraft:air';
}

function cunimobDamageEquipmentStack(player, slotName, amount) {
  var stack = cunimobGetEquipmentStack(player, slotName);
  if (cunimobStackIsEmpty(stack)) {
    return false;
  }

  var maxDamage = 0;
  var currentDamage = 0;
  try { maxDamage = Number(stack.getMaxDamage()); } catch (ignored) { }
  try { currentDamage = Number(stack.getDamageValue()); } catch (ignored) { }
  if (!isFinite(maxDamage) || maxDamage <= 0) {
    return false;
  }
  if (!isFinite(currentDamage) || currentDamage < 0) {
    currentDamage = 0;
  }

  var newDamage = currentDamage + Math.max(1, Math.floor(Number(amount || 1)));
  if (newDamage >= maxDamage) {
    try {
      stack.setDamageValue(maxDamage - 1);
      return true;
    } catch (ignored) {
    }

    try {
      stack.damageValue = maxDamage - 1;
      return true;
    } catch (ignored) {
    }

    return false;
  }

  try {
    stack.setDamageValue(newDamage);
    return true;
  } catch (ignored) {
  }

  try {
    stack.damageValue = newDamage;
    return true;
  } catch (ignored) {
  }

  return false;
}

function cunimobDropAndClearEquipment(player, slotName) {
  var stack = cunimobGetEquipmentStack(player, slotName);
  if (cunimobStackIsEmpty(stack)) {
    return false;
  }

  try {
    var copy = stack.copy ? stack.copy() : null;
    if (!copy || cunimobStackIsEmpty(copy)) {
      return false;
    }

    var moved = false;
    try {
      moved = !!player.getInventory().add(copy);
    } catch (ignored) {
      moved = false;
    }

    if (!moved) {
      try {
        player.spawnAtLocation(copy);
        moved = true;
      } catch (ignored) {
        try {
          player.drop(copy, false);
          moved = true;
        } catch (ignoredDrop) {
          moved = false;
        }
      }
    }

    return moved && cunimobSetEquipmentStack(player, slotName, CUNIMOB_ITEM_STACK_CLASS.EMPTY);
  } catch (ignored) {
  }

  return false;
}

function cunimobRequiredSlayerRule(mobId) {
  if (!mobId) {
    return null;
  }
  if (mobId === 'minecraft:spider' || mobId === 'minecraft:cave_spider' || mobId === 'minecraft:silverfish' || mobId === 'minecraft:endermite' || mobId.indexOf('arthropod') >= 0) {
    return { label: 'Perdicion de los Artropodos', enchants: ['minecraft:bane_of_arthropods'] };
  }
  if (mobId === 'minecraft:zombie' || mobId === 'minecraft:zombie_villager' || mobId === 'minecraft:husk' || mobId === 'minecraft:drowned' || mobId === 'minecraft:skeleton' || mobId === 'minecraft:stray' || mobId === 'minecraft:wither_skeleton' || mobId === 'minecraft:zombified_piglin' || mobId === 'minecraft:phantom' || mobId === 'quark:forgotten' || mobId.indexOf('undead') >= 0) {
    return { label: 'Castigo', enchants: ['minecraft:smite'] };
  }
  return { label: 'Filo', enchants: ['minecraft:sharpness'] };
}

function cunimobRequiredArmorRule(mobId, directId) {
  var mob = String(mobId || '');
  var direct = String(directId || '');

  if (mob === 'minecraft:creeper' || direct.indexOf('explosion') >= 0 || direct.indexOf('tnt') >= 0) {
    return { label: 'Proteccion contra Explosiones', enchants: ['minecraft:blast_protection', 'minecraft:protection'] };
  }

  if (mob === 'minecraft:skeleton' || mob === 'minecraft:stray' || mob === 'minecraft:bogged' || mob === 'minecraft:pillager' || mob === 'minecraft:illusioner' || mob === 'minecraft:shulker' || mob === 'minecraft:guardian' || mob === 'minecraft:elder_guardian' || mob === 'minecraft:ghast' || mob === 'minecraft:blaze' || direct === 'minecraft:arrow' || direct === 'minecraft:spectral_arrow' || direct.indexOf('fireball') >= 0 || direct.indexOf('projectile') >= 0) {
    return { label: 'Proteccion contra Proyectiles', enchants: ['minecraft:projectile_protection', 'minecraft:protection'] };
  }

  if (mob === 'minecraft:magma_cube' || mob === 'minecraft:wither_skeleton' || mob === 'quark:foxhound' || direct.indexOf('fire') >= 0 || direct.indexOf('lava') >= 0) {
    return { label: 'Proteccion contra Fuego', enchants: ['minecraft:fire_protection', 'minecraft:protection'] };
  }

  if (mob === 'minecraft:witch' || mob === 'minecraft:evoker' || mob === 'minecraft:vex' || mob === 'minecraft:warden' || mob.indexOf('cataclysm:') === 0 || direct.indexOf('magic') >= 0 || direct.indexOf('spell') >= 0) {
    return { label: 'Defensa Magica o Proteccion', enchants: ['extraspellattributes:warding', 'minecraft:protection'] };
  }

  return { label: 'Proteccion', enchants: ['minecraft:protection'] };
}

function cunimobTellEnchantGate(player, rule, multiplier) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!player || !safeName || !rule) {
    return;
  }
  var now = Date.now();
  try {
    if (Number(player.persistentData.cunimob_gate_msg_ms || 0) + 1500 > now) {
      return;
    }
    player.persistentData.cunimob_gate_msg_ms = now;
  } catch (ignored) {
  }
  var server = null;
  try { server = player.server; } catch (ignored) { }
  if (server) {
    var percent = Math.max(1, Math.round(Number(multiplier || 1) * 100));
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Encantamiento incorrecto: usa ' + rule.label + '. Dano actual ' + percent + '%.', 'red'));
  }
}

function cunimobTellArmorGate(player, rule, multiplier) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!player || !safeName || !rule) {
    return;
  }
  var now = Date.now();
  try {
    if (Number(player.persistentData.cunimob_armor_gate_msg_ms || 0) + 1800 > now) {
      return;
    }
    player.persistentData.cunimob_armor_gate_msg_ms = now;
  } catch (ignored) {
  }
  var server = null;
  try { server = player.server; } catch (ignored) { }
  if (server) {
    var percent = Math.round((Number(multiplier || 1) - 1) * 100);
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Armadura inadecuada: necesitas ' + rule.label + '. Dano recibido +' + percent + '%.', 'red'));
  }
}

function cunimobEventDamage(event) {
  var values = [];
  try { values.push(event.damage); } catch (ignored) { }
  try { values.push(event.amount); } catch (ignored) { }
  try { values.push(event.getDamage()); } catch (ignored) { }
  try { values.push(event.getNewDamage()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var amount = Number(values[i]);
    if (isFinite(amount) && amount > 0) {
      return amount;
    }
  }
  return 1;
}

function cunimobSetEventDamage(event, amount) {
  var safeAmount = Math.max(0, Number(amount || 0));
  try { event.damage = safeAmount; } catch (ignored) { }
  try { event.amount = safeAmount; } catch (ignored) { }
  try { event.setDamage(safeAmount); } catch (ignored) { }
  try { event.setNewDamage(safeAmount); } catch (ignored) { }
}

function cunimobWrongSlayerMultiplier(level) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < CUNIMOB_ENCHANT_GATE_LEVEL) {
    return 1;
  }
  var reduction = CUNIMOB_WRONG_ENCHANT_MIN_REDUCTION
    + Math.max(0, safeLevel - CUNIMOB_ENCHANT_GATE_LEVEL) * CUNIMOB_WRONG_ENCHANT_REDUCTION_PER_LEVEL;
  reduction = Math.min(CUNIMOB_WRONG_ENCHANT_MAX_REDUCTION, Math.max(0, reduction));
  return Math.max(0.05, 1 - reduction);
}

function cunimobReduceDamageWithoutEnchant(event, entity, attacker, mobId, level) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < CUNIMOB_ENCHANT_GATE_LEVEL || cunimobIsBossMob(mobId)) {
    return false;
  }

  var rule = cunimobRequiredSlayerRule(mobId);
  if (!rule) {
    return false;
  }

  var originalDamage = cunimobEventDamage(event);

  if (cunimobPlayerHasEnchant(attacker, rule.enchants)) {
    cunimobSetEventDamage(event, originalDamage * CUNIMOB_CORRECT_ENCHANT_DAMAGE_MULTIPLIER);
    return true;
  }

  if (!cunimobPlayerHasAnySlayerDamageEnchant(attacker)) {
    return false;
  }

  var multiplier = cunimobWrongSlayerMultiplier(safeLevel);
  cunimobSetEventDamage(event, originalDamage * multiplier);
  cunimobTellEnchantGate(attacker, rule, multiplier);
  return true;
}

function cunimobPlayerHeldText(player) {
  var text = '';
  try {
    var stacks = cunimobHeldStacks(player);
    for (var i = 0; i < stacks.length; i++) {
      text += ' ' + cunimobStackText(stacks[i]) + ' ' + cunimobStackId(stacks[i]);
    }
  } catch (ignored) {
  }
  return text.toLowerCase();
}

function cunimobApplyElementalWeaknessDamage(event, entity, attacker, mobId, level) {
  if (!event || !entity || !attacker || !mobId) {
    return false;
  }
  var sourceText = String(cunimobDamageSourceText(event) + ' ' + cunimobPlayerHeldText(attacker)).toLowerCase();
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var multiplier = 1.0;

  if ((mobId === 'minecraft:enderman' || mobId === 'minecraft:endermite') && cunimobTextHasAny(sourceText, ['water', 'drown', 'aqua', 'frost', 'ice'])) {
    multiplier *= 1.30 + Math.min(0.35, safeLevel * 0.0025);
  }

  var undeadRule = cunimobRequiredSlayerRule(mobId);
  if (undeadRule && undeadRule.enchants && undeadRule.enchants[0] === 'minecraft:smite' && cunimobTextHasAny(sourceText, ['fire', 'flame', 'lava', 'soulfire'])) {
    multiplier *= 1.18 + Math.min(0.32, safeLevel * 0.0022);
  }

  if (undeadRule && undeadRule.enchants && undeadRule.enchants[0] === 'minecraft:bane_of_arthropods' && cunimobPlayerHasEnchant(attacker, ['minecraft:bane_of_arthropods'])) {
    multiplier *= 1.10 + Math.min(0.25, safeLevel * 0.0018);
  }

  if ((mobId === 'minecraft:blaze' || mobId === 'minecraft:magma_cube' || mobId === 'quark:foxhound') && cunimobTextHasAny(sourceText, ['water', 'aqua', 'frost', 'ice', 'snow'])) {
    multiplier *= 1.22 + Math.min(0.32, safeLevel * 0.0020);
  }

  if (multiplier <= 1.001) {
    return false;
  }
  cunimobSetEventDamage(event, cunimobEventDamage(event) * multiplier);
  return true;
}

function cunimobApplyDimensionMobResistance(event, dimension, level) {
  var multiplier = cunimobDimensionIncomingDamageMultiplier(dimension);
  if (multiplier >= 0.999) {
    return false;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var levelPressure = Math.min(0.08, Math.max(0, safeLevel - 25) * 0.0009);
  var finalMultiplier = Math.max(0.70, multiplier - levelPressure);
  cunimobSetEventDamage(event, cunimobEventDamage(event) * finalMultiplier);
  return true;
}

function cunimobApplyDimensionMobDamage(event, dimension, level) {
  var multiplier = cunimobDimensionOutgoingDamageMultiplier(dimension);
  if (multiplier <= 1.001) {
    return false;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var levelPressure = Math.min(0.10, Math.max(0, safeLevel - 25) * 0.0008);
  cunimobSetEventDamage(event, cunimobEventDamage(event) * (multiplier + levelPressure));
  return true;
}

function cunimobBoostCreeperExplosionDamage(event, player, mobId, level) {
  if (mobId !== 'minecraft:creeper') {
    return false;
  }

  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < CUNIMOB_CREEPER_EXPLOSION_DAMAGE_LEVEL) {
    return false;
  }

  var originalDamage = cunimobEventDamage(event);
  var multiplier = 1 + Math.max(0, safeLevel - CUNIMOB_CREEPER_EXPLOSION_DAMAGE_LEVEL) * 0.0175;
  if (safeLevel >= 45) {
    multiplier += 0.20;
  }
  if (safeLevel >= 75) {
    multiplier += 0.25;
  }
  multiplier = Math.min(CUNIMOB_CREEPER_EXPLOSION_DAMAGE_CAP, multiplier);
  cunimobSetEventDamage(event, originalDamage * multiplier);
  return true;
}

function cunimobEnsureMobLeveledForPlayerHit(event, mob, player, dimension, mobId) {
  var level = cunimobLevelFromEntity(mob);
  if (level > 1 || cunimobHasCuniculumName(mob)) {
    return level;
  }

  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = mob.server; } } catch (ignored) { }
  try { if (!server) { server = player.server; } } catch (ignored) { }
  if (!server) {
    return level;
  }

  var pos = cunimobEntityPosition(mob);
  var levelObj = event.level || player.level || mob.level;
  var newLevel = cunimobAdjustLevelForMob(mobId, cunimobLevelForPlayer(player, levelObj, dimension, 'natural', cunimobLevelBonusForMob(mobId)));
  cunimobApplyVisualNameAt(server, dimension, pos.x, pos.y, pos.z, mobId, newLevel, 'natural', 4);
  return Math.max(1, Math.floor(Number(newLevel || 1)));
}

function cunimobIncreaseDamageWithoutArmor(event, player, mob, mobId, level) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (!player || !mob || safeLevel < CUNIMOB_ARMOR_GATE_LEVEL || cunimobIsBossMob(mobId)) {
    return false;
  }

  var directId = cunimobDamageDirectEntityId(event);
  var rule = cunimobRequiredArmorRule(mobId, directId);
  if (!rule || cunimobPlayerHasArmorEnchant(player, rule.enchants)) {
    return false;
  }

  var levelFactor = Math.min(CUNIMOB_ARMOR_WRONG_DAMAGE_CAP - CUNIMOB_ARMOR_WRONG_DAMAGE_BASE, Math.max(0, safeLevel - CUNIMOB_ARMOR_GATE_LEVEL) * 0.012);
  var multiplier = Math.min(CUNIMOB_ARMOR_WRONG_DAMAGE_CAP, CUNIMOB_ARMOR_WRONG_DAMAGE_BASE + levelFactor);
  var originalDamage = cunimobEventDamage(event);
  cunimobSetEventDamage(event, originalDamage * multiplier);
  cunimobTellArmorGate(player, rule, multiplier);
  return true;
}

function cunimobRetargetLastPlayerHit(target, attacker) {
  if (!target || !attacker) {
    return;
  }

  try { target.setTarget(attacker); } catch (ignored) { }
  try { target.target = attacker; } catch (ignored) { }
  try { target.setLastHurtByMob(attacker); } catch (ignored) { }
  try { target.setLastHurtByPlayer(attacker); } catch (ignored) { }
  try { target.lastHurtByMob = attacker; } catch (ignored) { }
}

function cunimobYaw(entity) {
  var values = [];
  try { values.push(entity.yRot); } catch (ignored) { }
  try { values.push(entity.yaw); } catch (ignored) { }
  try { values.push(entity.rotationYaw); } catch (ignored) { }
  try { values.push(entity.getYRot()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var value = Number(values[i]);
    if (isFinite(value)) {
      return value;
    }
  }
  return 0;
}

function cunimobRunAsNearestMob(server, dimension, entity, mobId, command) {
  if (!server || !dimension || !entity || !mobId || !command) {
    return;
  }
  var pos = cunimobEntityPosition(entity);
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' as @e[type=' + mobId + ',distance=..4,tag=' + CUNIMOB_LEVEL_TAG + ',limit=1,sort=nearest] run ' + command);
}

function cunimobMinionPool(mobId, dimension) {
  if (dimension === 'minecraft:the_nether' || mobId === 'minecraft:blaze' || mobId === 'minecraft:magma_cube' || mobId === 'minecraft:ghast') {
    return ['minecraft:wither_skeleton', 'minecraft:blaze', 'minecraft:magma_cube', 'minecraft:zombified_piglin', 'quark:foxhound'];
  }
  if (mobId === 'minecraft:spider' || mobId === 'minecraft:cave_spider') {
    return ['minecraft:cave_spider', 'minecraft:spider', 'minecraft:silverfish', 'minecraft:endermite'];
  }
  if (mobId === 'minecraft:creeper') {
    return ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:silverfish', 'minecraft:bogged'];
  }
  if (mobId === 'minecraft:skeleton' || mobId === 'minecraft:stray' || mobId === 'minecraft:bogged') {
    return ['minecraft:skeleton', 'minecraft:stray', 'minecraft:bogged', 'minecraft:zombie', 'minecraft:silverfish'];
  }
  if (mobId === 'minecraft:pillager' || mobId === 'minecraft:vindicator' || mobId === 'minecraft:evoker') {
    return ['minecraft:pillager', 'minecraft:vindicator', 'minecraft:skeleton', 'minecraft:witch'];
  }
  if (mobId.indexOf('cataclysm:') === 0) {
    return ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:spider', 'cataclysm:koboleton'];
  }
  return ['minecraft:zombie', 'minecraft:skeleton', 'minecraft:spider', 'minecraft:silverfish', 'minecraft:bogged', 'quark:forgotten', 'quark:wraith'];
}

function cunimobMinionDisplayName(mobId) {
  var id = String(mobId || '').toLowerCase();
  if (id.indexOf('skeleton') >= 0 || id.indexOf('stray') >= 0 || id.indexOf('bogged') >= 0 || id.indexOf('pillager') >= 0) {
    return 'Arquero Invocado';
  }
  if (id.indexOf('spider') >= 0 || id.indexOf('silverfish') >= 0 || id.indexOf('endermite') >= 0) {
    return 'Rastreador Invocado';
  }
  if (id.indexOf('blaze') >= 0 || id.indexOf('magma') >= 0 || id.indexOf('foxhound') >= 0) {
    return 'Ascua Invocada';
  }
  if (id.indexOf('witch') >= 0 || id.indexOf('wraith') >= 0) {
    return 'Sombra Invocada';
  }
  if (id.indexOf('koboleton') >= 0) {
    return 'Koboleton Jurado';
  }
  return 'Esbirro Invocado';
}

function cunimobSummonEliteMinions(server, entity, attacker, dimension, mobId, level) {
  if (!server || !entity || !dimension || !mobId) {
    return;
  }
  if (!cunimobEntityHasTag(entity, CUNIMOB_ELITE_SUMMON_TAG) || cunimobEntityHasTag(entity, CUNIMOB_ELITE_MINION_TAG)) {
    return;
  }
  var bossCategory = cunimobEntityHasTag(entity, CUNIMOB_BOSS_TAG);
  if (!bossCategory && level < CUNIMOB_ELITE_MINION_LEVEL) {
    return;
  }
  if (cunimobEntityHasTag(entity, CUNIMOB_ELITE_STARTED_TAG) || cunimobGetEntityDataNumber(entity, 'cuniculum_elite_started_ms') > 0) {
    return;
  }

  cunimobMarkEntityTag(entity, CUNIMOB_ELITE_STARTED_TAG);
  cunimobSetEntityData(entity, 'cuniculum_elite_started_ms', Date.now());
  var pos = cunimobEntityPosition(entity);
  var pool = cunimobMinionPool(mobId, dimension);
  var count = bossCategory
    ? Math.min(8, 3 + Math.floor(level / 35) + (level >= 90 ? 1 : 0))
    : Math.min(6, 2 + Math.floor(level / 40) + (level >= 90 ? 1 : 0));

  for (var i = 0; i < count; i++) {
    var minionId = cunimobRandomChoice(pool);
    var dx = Math.floor(Math.random() * 7) - 3;
    var dz = Math.floor(Math.random() * 7) - 3;
    if (dx === 0 && dz === 0) {
      dx = 2;
    }
    var mx = Math.round((pos.x + dx) * 100) / 100;
    var mz = Math.round((pos.z + dz) * 100) / 100;
    var minionLevel = Math.max(1, Math.floor(level * (bossCategory ? (0.55 + Math.random() * 0.25) : (0.40 + Math.random() * 0.18))));
    server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run summon ' + minionId + ' ~' + dx + ' ~ ~' + dz + ' {Tags:["' + CUNIMOB_ELITE_MINION_TAG + '","' + CUNIMOB_NO_RPG_REWARD_TAG + '","' + CUNIMOB_MANUAL_SPAWN_TAG + '"],PersistenceRequired:0b}');
    (function (localMobId, localLevel, localX, localZ, localBossSummon) {
      server.scheduleInTicks(5, function () {
        var minionRarity = cunimobRollRarityProfile(localLevel, localMobId, 'minion');
        var eliteChance = localBossSummon ? Math.min(0.46, 0.12 + localLevel * 0.0020 + Math.max(0, Number(minionRarity.weight || 1) - 1) * 0.035) : 0;
        var minionCategory = localBossSummon && Math.random() < eliteChance ? CUNIMOB_CATEGORY_ELITE : CUNIMOB_CATEGORY_NORMAL;
        cunimobApplyVisualNameAt(server, dimension, localX, pos.y, localZ, localMobId, localLevel, 'minion', 5, CUNIMOB_ELITE_MINION_TAG, minionRarity, minionCategory);
      });
    })(minionId, minionLevel, mx, mz, bossCategory);
  }
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run particle minecraft:trial_spawner_detection_ominous ~ ~1.2 ~ 1.4 0.5 1.4 0.02 45 force');
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run playsound minecraft:block.trial_spawner.spawn_mob hostile @a[distance=..28] ~ ~ ~ 0.75 0.70');
}

function cunimobBlinkBehindAttacker(server, entity, attacker, dimension, mobId, level) {
  if (!cunimobEntityHasTag(entity, CUNIMOB_ELITE_BLINK_TAG) || level < CUNIMOB_ELITE_ABILITY_LEVEL) {
    return;
  }
  if (!cunimobSameDimension(attacker, dimension)) {
    return;
  }
  var chance = Math.min(0.34, 0.08 + level * 0.0016);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_blink_ms', 8500, chance)) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  if (!safeName) {
    return;
  }
  var yaw = cunimobYaw(attacker) * Math.PI / 180;
  var tx = Math.round((Number(attacker.x) + Math.sin(yaw) * 1.8) * 100) / 100;
  var ty = Math.round(Number(attacker.y) * 100) / 100;
  var tz = Math.round((Number(attacker.z) - Math.cos(yaw) * 1.8) * 100) / 100;
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'tp @s ' + tx + ' ' + ty + ' ' + tz + ' facing entity ' + safeName + ' eyes');
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:portal ~ ~1 ~ 0.35 0.45 0.35 0.08 24 force');
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + tx + ' ' + ty + ' ' + tz + ' run playsound minecraft:entity.enderman.teleport hostile @a[distance=..24] ~ ~ ~ 0.55 1.20');
}

function cunimobReflectDamage(server, entity, attacker, level) {
  if (!cunimobEntityHasTag(entity, CUNIMOB_ELITE_REFLECT_TAG) || level < CUNIMOB_ELITE_ABILITY_LEVEL) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  var chance = Math.min(0.40, 0.12 + level * 0.0018);
  if (!safeName || !cunimobRollEntityCooldown(entity, 'cuniculum_reflect_ms', 1800, chance)) {
    return;
  }
  var amount = Math.max(1, Math.min(9, Math.floor(1 + level / 28)));
  server.runCommandSilent('damage ' + safeName + ' ' + amount + ' minecraft:thorns');
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Reflejo de dano: el enemigo devuelve parte del golpe.', 'red'));
}

function cunimobCastEliteSpell(server, entity, attacker, dimension, mobId, level) {
  if (!cunimobEntityHasTag(entity, CUNIMOB_ELITE_SPELL_TAG) || level < CUNIMOB_ELITE_SPELL_LEVEL) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  var bossCaster = cunimobEntityHasTag(entity, CUNIMOB_BOSS_TAG);
  var chance = Math.min(bossCaster ? 0.68 : 0.46, (bossCaster ? 0.30 : 0.16) + level * 0.0020);
  if (!safeName || !cunimobRollEntityCooldown(entity, 'cuniculum_spell_ms', 6500, chance)) {
    return;
  }

  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:enchant ~ ~1.2 ~ 0.45 0.45 0.45 0.04 22 force');
  var amp = Math.max(0, Math.min(3, Math.floor(level / 35)));
  var roll = Math.random();
  if (roll < 0.16 && level >= 45) {
    server.runCommandSilent('execute at ' + safeName + ' run summon minecraft:lightning_bolt ~ ~ ~');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:slowness 4 ' + Math.min(1, amp) + ' true');
  } else if (roll < 0.32) {
    server.runCommandSilent('execute at ' + safeName + ' run effect give @a[distance=..4] minecraft:poison 5 ' + Math.min(2, amp) + ' true');
    server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:witch ~ ~1 ~ 1.5 0.4 1.5 0.05 28 force');
  } else if (roll < 0.48 && level >= 35) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:wither 4 ' + Math.min(1, amp) + ' true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:hunger 7 ' + Math.min(2, amp) + ' true');
  } else if (roll < 0.62) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:blindness 3 0 true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:weakness 5 ' + Math.min(1, amp) + ' true');
  } else if (roll < 0.74 && level >= 42) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:darkness 4 0 true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:levitation 2 0 true');
  } else if (roll < 0.90) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:slowness 6 ' + Math.min(2, amp) + ' true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:mining_fatigue 5 ' + Math.min(1, amp) + ' true');
  } else {
    cunimobRunAsNearestMob(server, dimension, entity, mobId, 'effect give @s minecraft:absorption 8 ' + Math.min(2, amp) + ' true');
    cunimobRunAsNearestMob(server, dimension, entity, mobId, 'effect give @s minecraft:resistance 5 ' + Math.min(1, amp) + ' true');
  }
}

function cunimobPullAttacker(server, entity, attacker, level) {
  if (!cunimobEntityHasTag(entity, CUNIMOB_ELITE_PULL_TAG) || level < 55) {
    return;
  }
  var dimension = cunimobDimensionFromEntity(entity);
  if (!dimension || !cunimobSameDimension(attacker, dimension)) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  if (!safeName || !cunimobRollEntityCooldown(entity, 'cuniculum_pull_ms', 9000, Math.min(0.34, 0.10 + level * 0.0015))) {
    return;
  }
  var pos = cunimobEntityPosition(entity);
  var ax = Number(attacker.x);
  var ay = Number(attacker.y);
  var az = Number(attacker.z);
  var dx = ax - pos.x;
  var dz = az - pos.z;
  var distanceSq = dx * dx + dz * dz;
  if (distanceSq < 10 || distanceSq > 400) {
    return;
  }
  var tx = Math.round((pos.x + dx * 0.38) * 100) / 100;
  var tz = Math.round((pos.z + dz * 0.38) * 100) / 100;
  server.runCommandSilent('execute in ' + dimension + ' run tp ' + safeName + ' ' + tx + ' ' + Math.round(ay * 100) / 100 + ' ' + tz);
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Atraccion: el enemigo te arrastra hacia el combate.', 'dark_purple'));
}

function cunimobBossCallAttacker(server, entity, attacker, dimension, mobId, level) {
  if (!server || !entity || !attacker || !dimension) {
    return;
  }
  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(entity));
  var bossLike = cunimobIsBossMob(mobId) || categoryKey === CUNIMOB_CATEGORY_BOSS;
  if (!bossLike) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < CUNIMOB_BOSS_CALL_LEVEL) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  if (!cunimobSameDimension(attacker, dimension)) {
    return;
  }
  var pos = cunimobEntityPosition(entity);
  var ax = Number(attacker.x);
  var az = Number(attacker.z);
  var dx = ax - pos.x;
  var dz = az - pos.z;
  var distanceSq = dx * dx + dz * dz;
  var minSq = CUNIMOB_BOSS_CALL_MIN_DISTANCE * CUNIMOB_BOSS_CALL_MIN_DISTANCE;
  var maxSq = CUNIMOB_BOSS_CALL_MAX_DISTANCE * CUNIMOB_BOSS_CALL_MAX_DISTANCE;
  if (distanceSq < minSq || distanceSq > maxSq) {
    return;
  }

  var chance = Math.min(0.74, 0.22 + safeLevel * 0.0028);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_boss_call_ms', 7200, chance)) {
    return;
  }

  var angle = Math.atan2(dz, dx);
  var offset = 2.2 + Math.random() * 1.4;
  var side = Math.random() < 0.5 ? -0.45 : 0.45;
  var tx = Math.round((pos.x + Math.cos(angle + side) * offset) * 100) / 100;
  var ty = Math.round((pos.y + 0.05) * 100) / 100;
  var tz = Math.round((pos.z + Math.sin(angle + side) * offset) * 100) / 100;
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run particle minecraft:reverse_portal ~ ~1.2 ~ 0.65 0.45 0.65 0.08 38 force');
  server.runCommandSilent('execute in ' + dimension + ' run tp ' + safeName + ' ' + tx + ' ' + ty + ' ' + tz + ' facing ' + pos.x + ' ' + (pos.y + 1.2) + ' ' + pos.z);
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + tx + ' ' + ty + ' ' + tz + ' run particle minecraft:portal ~ ~1 ~ 0.35 0.45 0.35 0.08 28 force');
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run playsound minecraft:entity.enderman.teleport hostile @a[distance=..36] ~ ~ ~ 0.80 0.65');
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Llamado del lider: no puedes huir tan facil.', 'dark_purple'));
}

function cunimobTrySoloBossPressure(server, entity, attacker, dimension, mobId, level) {
  if (!server || !entity || !attacker || !dimension || !mobId || !cunimobIsPlayerEntity(attacker)) {
    return;
  }
  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(entity));
  var bossLike = cunimobIsBossMob(mobId) || categoryKey === CUNIMOB_CATEGORY_BOSS;
  if (!bossLike) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var cooldown = safeLevel >= 80 ? 6500 : 8500;
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_solo_boss_pressure_ms', cooldown, 1)) {
    return;
  }

  var pos = cunimobEntityPosition(entity);
  var soloPrefix = 'execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z
    + ' if entity @a[name=' + safeName + ',distance=..34] unless entity @a[name=!' + safeName + ',distance=..34] run ';
  var clearEffects = [
    'minecraft:regeneration',
    'minecraft:resistance',
    'minecraft:absorption',
    'minecraft:strength',
    'minecraft:speed',
    'minecraft:haste',
    'minecraft:fire_resistance',
    'minecraft:saturation',
    'minecraft:luck',
    'minecraft:conduit_power'
  ];
  for (var i = 0; i < clearEffects.length; i++) {
    server.runCommandSilent(soloPrefix + 'effect clear ' + safeName + ' ' + clearEffects[i]);
  }

  var playerAmp = safeLevel >= 90 ? 1 : 0;
  var bossAmp = safeLevel >= 90 ? 1 : 0;
  server.runCommandSilent(soloPrefix + 'effect give ' + safeName + ' minecraft:weakness 8 ' + playerAmp + ' true');
  server.runCommandSilent(soloPrefix + 'effect give ' + safeName + ' minecraft:slowness 6 ' + Math.min(1, playerAmp) + ' true');
  server.runCommandSilent(soloPrefix + 'effect give ' + safeName + ' minecraft:darkness 5 0 true');
  server.runCommandSilent(soloPrefix + 'effect give @e[type=' + mobId + ',distance=..4,limit=1,sort=nearest] minecraft:resistance 5 ' + Math.min(1, bossAmp) + ' true');
  server.runCommandSilent(soloPrefix + 'particle minecraft:soul_fire_flame ~ ~1.25 ~ 0.75 0.55 0.75 0.025 36 force');
  server.runCommandSilent(soloPrefix + 'playsound minecraft:entity.warden.roar hostile @a[distance=..40] ~ ~ ~ 0.55 1.18');
  server.runCommandSilent(soloPrefix + 'title ' + safeName + ' actionbar ' + cunihordeJson('Furia de lider: no pelees solo, busca aliados.', 'red'));
}

function cunimobSummonVanillaBossMinion(server, dimension, entity, minionId, level, dx, dz) {
  if (!server || !dimension || !entity || !minionId) {
    return;
  }
  var pos = cunimobEntityPosition(entity);
  var mx = Math.round((pos.x + dx) * 100) / 100;
  var mz = Math.round((pos.z + dz) * 100) / 100;
  var minionLevel = Math.max(1, Math.floor(Number(level || 1) * (0.45 + Math.random() * 0.22)));
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run summon ' + minionId + ' ~' + dx + ' ~ ~' + dz + ' {Tags:["' + CUNIMOB_ELITE_MINION_TAG + '","' + CUNIMOB_NO_RPG_REWARD_TAG + '","' + CUNIMOB_MANUAL_SPAWN_TAG + '"],PersistenceRequired:0b}');
  server.scheduleInTicks(5, function () {
    var rarity = cunimobRarityProfileAtLeast(cunimobRollRarityProfile(minionLevel, minionId, 'minion'), 'rare');
    cunimobApplyVisualNameAt(server, dimension, mx, pos.y, mz, minionId, minionLevel, 'minion', 5, CUNIMOB_ELITE_MINION_TAG, rarity, CUNIMOB_CATEGORY_NORMAL);
  });
}

function cunimobUseVanillaBossSignatureSkills(server, entity, attacker, dimension, mobId, level) {
  if (!server || !entity || !attacker || !dimension || !mobId || !cunimobIsPlayerEntity(attacker)) {
    return;
  }
  var id = String(mobId || '').toLowerCase();
  if (id !== 'minecraft:wither' && id !== 'minecraft:ender_dragon' && id !== 'minecraft:warden') {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var pos = cunimobEntityPosition(entity);
  var prefix = 'execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run ';

  if (id === 'minecraft:wither') {
    if (!cunimobRollEntityCooldown(entity, 'cuniculum_wither_signature_ms', 7600, Math.min(0.78, 0.34 + safeLevel * 0.0020))) {
      return;
    }
    var witherAmp = safeLevel >= 85 ? 2 : (safeLevel >= 45 ? 1 : 0);
    server.runCommandSilent('effect clear ' + safeName + ' minecraft:regeneration');
    server.runCommandSilent('effect clear ' + safeName + ' minecraft:absorption');
    server.runCommandSilent('effect clear ' + safeName + ' minecraft:resistance');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:wither 6 ' + witherAmp + ' true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:weakness 7 ' + Math.min(1, witherAmp) + ' true');
    server.runCommandSilent('damage ' + safeName + ' ' + Math.max(3, Math.min(10, Math.floor(3 + safeLevel / 22))) + ' minecraft:generic');
    server.runCommandSilent(prefix + 'particle minecraft:soul ~ ~1.4 ~ 1.0 0.55 1.0 0.04 42 force');
    server.runCommandSilent(prefix + 'playsound minecraft:entity.wither.shoot hostile @a[distance=..42] ~ ~ ~ 0.70 0.70');
    if (Math.random() < 0.42) {
      cunimobSummonVanillaBossMinion(server, dimension, entity, 'minecraft:wither_skeleton', safeLevel, 2, 1);
      cunimobSummonVanillaBossMinion(server, dimension, entity, 'minecraft:wither_skeleton', safeLevel, -2, -1);
    }
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Ceniza del Wither: tus defensas se marchitan.', 'dark_red'));
    return;
  }

  if (id === 'minecraft:warden') {
    if (!cunimobRollEntityCooldown(entity, 'cuniculum_warden_signature_ms', 6200, Math.min(0.82, 0.38 + safeLevel * 0.0022))) {
      return;
    }
    var sonicDamage = Math.max(4, Math.min(12, Math.floor(4 + safeLevel / 20)));
    server.runCommandSilent('effect give ' + safeName + ' minecraft:darkness 7 0 true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:mining_fatigue 6 1 true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:slowness 4 1 true');
    server.runCommandSilent('damage ' + safeName + ' ' + sonicDamage + ' minecraft:generic');
    server.runCommandSilent(prefix + 'particle minecraft:sonic_boom ~ ~1.2 ~ 0.2 0.2 0.2 0.02 8 force');
    server.runCommandSilent(prefix + 'playsound minecraft:entity.warden.sonic_boom hostile @a[distance=..48] ~ ~ ~ 0.85 0.92');
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Pulso del Custodio: la oscuridad responde a tu ruido.', 'dark_aqua'));
    return;
  }

  if (id === 'minecraft:ender_dragon') {
    if (!cunimobRollEntityCooldown(entity, 'cuniculum_dragon_signature_ms', 7000, Math.min(0.76, 0.30 + safeLevel * 0.0020))) {
      return;
    }
    var breathDamage = Math.max(4, Math.min(11, Math.floor(4 + safeLevel / 24)));
    server.runCommandSilent('execute at ' + safeName + ' run effect give @a[distance=..6] minecraft:levitation 2 0 true');
    server.runCommandSilent('execute at ' + safeName + ' run effect give @a[distance=..6] minecraft:slowness 5 1 true');
    server.runCommandSilent('damage ' + safeName + ' ' + breathDamage + ' minecraft:generic');
    server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:dragon_breath ~ ~0.6 ~ 1.8 0.35 1.8 0.03 55 force');
    server.runCommandSilent(prefix + 'playsound minecraft:entity.ender_dragon.growl hostile @a[distance=..64] ~ ~ ~ 0.70 1.15');
    if (Math.random() < 0.34) {
      cunimobSummonVanillaBossMinion(server, dimension, entity, 'minecraft:endermite', safeLevel, 2, -2);
      cunimobSummonVanillaBossMinion(server, dimension, entity, 'minecraft:endermite', safeLevel, -2, 2);
    }
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Aliento del Dragon: separense o caen juntos.', 'light_purple'));
  }
}

function cunimobTryBleedMob(server, entity, dimension, mobId, level, rarity) {
  if (!server || !entity || !dimension || !mobId || cunimobEntityHasTag(entity, CUNIMOB_BLEED_TAG)) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < 10 || cunimobIsBossMob(mobId)) {
    return;
  }
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var chance = Math.min(0.34, 0.035 + safeLevel * 0.0012 + Math.max(0, Number(profile.weight || 1) - 1) * 0.025);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_bleed_ms', 8500, chance)) {
    return;
  }

  var pulses = safeLevel >= 75 ? 5 : (safeLevel >= 35 ? 4 : 3);
  var amount = Math.max(1, Math.min(5, Math.floor(1 + safeLevel / 38)));
  cunimobMarkEntityTag(entity, CUNIMOB_BLEED_TAG);
  for (var i = 0; i < pulses; i++) {
    (function (delay, last) {
      server.scheduleInTicks(delay, function () {
        cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:damage_indicator ~ ~1 ~ 0.35 0.25 0.35 0.03 7 force');
        cunimobRunAsNearestMob(server, dimension, entity, mobId, 'damage @s ' + amount + ' minecraft:generic');
        if (last) {
          cunimobRunAsNearestMob(server, dimension, entity, mobId, 'tag @s remove ' + CUNIMOB_BLEED_TAG);
        }
      });
    })(20 + i * 24, i === pulses - 1);
  }
}

function cunimobTryBreakMobEquipment(server, entity, dimension, mobId, level, rarity) {
  if (!server || !entity || !dimension || !mobId || !cunimobEntityHasTag(entity, CUNIMOB_GEAR_TAG)) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < 12) {
    return;
  }
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var chance = Math.min(0.20, 0.025 + safeLevel * 0.0007 + Math.max(0, Number(profile.weight || 1) - 1) * 0.010);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_mob_equipment_break_ms', 6200, chance)) {
    return;
  }
  var slots = ['weapon.mainhand', 'armor.head', 'armor.chest', 'armor.legs', 'armor.feet'];
  var slot = cunimobRandomChoice(slots);
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'item replace entity @s ' + slot + ' with minecraft:air');
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'playsound minecraft:item.shield.break hostile @a[distance=..18] ~ ~ ~ 0.42 1.35');
}

function cunimobMythicThreatRank(entity, mobId, level, rarity) {
  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(entity));
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var weight = Math.max(1, Number(profile && profile.weight || 1));
  if (cunimobIsBossMob(mobId) || categoryKey === CUNIMOB_CATEGORY_BOSS) {
    return 4 + Math.max(0, weight - 3);
  }
  if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    return 3 + Math.max(0, weight - 4) * 0.5;
  }
  if (weight >= 5 && level >= 45) {
    return 2.5;
  }
  if (weight >= 4 && level >= 55) {
    return 2;
  }
  return 0;
}

function cunimobUseMythicRuneBurst(server, entity, attacker, dimension, mobId, level, rarity) {
  var threat = cunimobMythicThreatRank(entity, mobId, level, rarity);
  if (threat <= 0) {
    return;
  }
  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(entity));
  var bossLike = cunimobIsBossMob(mobId) || categoryKey === CUNIMOB_CATEGORY_BOSS;
  var cooldown = bossLike ? 7200 : 10500;
  var chance = bossLike ? 0.42 : Math.min(0.26, 0.08 + level * 0.0014 + threat * 0.025);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_mythic_rune_burst_ms', cooldown, chance)) {
    return;
  }

  var pos = cunimobEntityPosition(entity);
  var radius = bossLike ? 5 : 4;
  var delay = bossLike ? 22 : 28;
  var amount = Math.max(2, Math.min(bossLike ? 10 : 6, Math.floor(2 + level / (bossLike ? 30 : 42) + threat)));
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  var prefix = 'execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run ';
  server.runCommandSilent(prefix + 'particle minecraft:witch ~ ~0.15 ~ ' + radius + ' 0.02 ' + radius + ' 0.02 42 force');
  server.runCommandSilent(prefix + 'particle minecraft:enchant ~ ~1.15 ~ 0.8 0.4 0.8 0.03 28 force');
  server.runCommandSilent(prefix + 'playsound minecraft:block.enchantment_table.use hostile @a[distance=..32] ~ ~ ~ 0.55 0.68');
  if (safeName) {
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Runa hostil: alejate o bloquea el impacto.', 'light_purple'));
  }
  server.scheduleInTicks(delay, function () {
    server.runCommandSilent(prefix + 'particle minecraft:soul_fire_flame ~ ~0.25 ~ ' + radius + ' 0.12 ' + radius + ' 0.025 52 force');
    server.runCommandSilent(prefix + 'damage @a[distance=..' + radius + '] ' + amount + ' minecraft:magic');
    server.runCommandSilent(prefix + 'effect give @a[distance=..' + radius + '] minecraft:slowness 4 ' + (bossLike ? 1 : 0) + ' true');
    if (bossLike || level >= 70) {
      server.runCommandSilent(prefix + 'effect give @a[distance=..' + radius + '] minecraft:weakness 5 0 true');
    }
  });
}

function cunimobUseMythicGuard(server, entity, dimension, mobId, level, rarity) {
  var threat = cunimobMythicThreatRank(entity, mobId, level, rarity);
  if (threat <= 0) {
    return;
  }
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(entity)) === CUNIMOB_CATEGORY_BOSS;
  var chance = bossLike ? 0.34 : Math.min(0.20, 0.05 + level * 0.0009 + threat * 0.018);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_mythic_guard_ms', bossLike ? 9800 : 13500, chance)) {
    return;
  }
  var amp = bossLike ? 1 : 0;
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'effect give @s minecraft:resistance 4 ' + amp + ' true');
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'effect give @s minecraft:absorption 7 ' + amp + ' true');
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:crit ~ ~1.1 ~ 0.45 0.35 0.45 0.02 18 force');
  cunimobRunAsNearestMob(server, dimension, entity, mobId, 'playsound minecraft:item.shield.block hostile @a[distance=..22] ~ ~ ~ 0.45 0.75');
}

function cunimobUseMythicPressureHit(server, mob, player, dimension, mobId, level) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!safeName || !mob || !dimension || cunimobEntityHasTag(mob, CUNIMOB_ELITE_MINION_TAG)) {
    return;
  }
  var rarity = cunimobRarityProfileFromEntity(mob);
  var threat = cunimobMythicThreatRank(mob, mobId, level, rarity);
  if (threat <= 0) {
    return;
  }
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(mob)) === CUNIMOB_CATEGORY_BOSS;
  var chance = bossLike ? 0.48 : Math.min(0.30, 0.08 + level * 0.0015 + threat * 0.022);
  if (!cunimobRollEntityCooldown(mob, 'cuniculum_mythic_pressure_hit_ms', bossLike ? 6400 : 9200, chance)) {
    return;
  }

  var roll = Math.random();
  var amp = Math.max(0, Math.min(2, Math.floor(level / 55)));
  if (roll < 0.28) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:mining_fatigue 6 ' + Math.min(1, amp) + ' true');
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Golpe pesado: tus manos pierden ritmo.', 'gray'));
  } else if (roll < 0.54) {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:weakness 6 ' + Math.min(1, amp) + ' true');
    server.runCommandSilent('effect give ' + safeName + ' minecraft:slowness 4 0 true');
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Marca de caza: el enemigo te presiona.', 'red'));
  } else if (roll < 0.78) {
    server.runCommandSilent('effect clear ' + safeName + ' minecraft:regeneration');
    server.runCommandSilent('effect clear ' + safeName + ' minecraft:absorption');
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Corte limpio: se rompio tu recuperacion.', 'dark_red'));
  } else {
    server.runCommandSilent('effect give ' + safeName + ' minecraft:darkness 4 0 true');
    if (bossLike) {
      server.runCommandSilent('effect give ' + safeName + ' minecraft:blindness 2 0 true');
    }
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Sombra de lider: pierdes lectura del combate.', 'dark_purple'));
  }
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:enchanted_hit ~ ~1 ~ 0.35 0.35 0.35 0.04 20 force');
}

function cunimobUseMythicChainArc(server, entity, attacker, dimension, mobId, level, rarity) {
  if (!server || !entity || !attacker || !dimension || !cunimobEntityHasTag(entity, CUNIMOB_ELITE_CHAIN_TAG)) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  var threat = cunimobMythicThreatRank(entity, mobId, level, rarity || cunimobRarityProfileFromEntity(entity));
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(entity)) === CUNIMOB_CATEGORY_BOSS;
  var chance = bossLike ? 0.46 : Math.min(0.28, 0.08 + level * 0.0014 + threat * 0.018);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_chain_arc_ms', bossLike ? 8200 : 11800, chance)) {
    return;
  }
  var amount = Math.max(2, Math.min(bossLike ? 9 : 6, Math.floor(2 + level / (bossLike ? 30 : 42) + threat)));
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:electric_spark ~ ~1 ~ 2.4 0.8 2.4 0.06 36 force');
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:crit ~ ~1 ~ 1.8 0.55 1.8 0.02 18 force');
  server.runCommandSilent('execute at ' + safeName + ' run damage @a[distance=..5] ' + amount + ' minecraft:lightning_bolt');
  server.runCommandSilent('execute at ' + safeName + ' run effect give @a[distance=..5] minecraft:slowness 3 0 true');
  server.runCommandSilent('playsound minecraft:entity.lightning_bolt.thunder hostile ' + safeName + ' ~ ~ ~ 0.28 1.45');
}

function cunimobUseMythicWarcry(server, entity, dimension, mobId, level, rarity) {
  if (!server || !entity || !dimension || !cunimobEntityHasTag(entity, CUNIMOB_ELITE_WARCRY_TAG)) {
    return;
  }
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(entity)) === CUNIMOB_CATEGORY_BOSS;
  var chance = bossLike ? 0.52 : Math.min(0.26, 0.07 + level * 0.0012 + Math.max(0, Number(profile.weight || 1) - 1) * 0.018);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_warcry_ms', bossLike ? 10500 : 15000, chance)) {
    return;
  }
  var pos = cunimobEntityPosition(entity);
  var prefix = 'execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run ';
  var amp = bossLike ? 1 : 0;
  server.runCommandSilent(prefix + 'effect give @e[type=!minecraft:player,distance=..10,tag=' + CUNIMOB_LEVEL_TAG + '] minecraft:strength 6 ' + amp + ' true');
  server.runCommandSilent(prefix + 'effect give @e[type=!minecraft:player,distance=..10,tag=' + CUNIMOB_LEVEL_TAG + '] minecraft:speed 6 0 true');
  if (bossLike || level >= 70) {
    server.runCommandSilent(prefix + 'effect give @e[type=!minecraft:player,distance=..10,tag=' + CUNIMOB_LEVEL_TAG + '] minecraft:resistance 4 0 true');
  }
  server.runCommandSilent(prefix + 'particle minecraft:note ~ ~1.4 ~ 1.6 0.5 1.6 0.04 26 force');
  server.runCommandSilent(prefix + 'playsound minecraft:entity.ravager.roar hostile @a[distance=..34] ~ ~ ~ 0.48 1.10');
}

function cunimobUseMythicSnare(server, entity, attacker, dimension, mobId, level, rarity) {
  if (!server || !entity || !attacker || !dimension || !cunimobEntityHasTag(entity, CUNIMOB_ELITE_SNARE_TAG)) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(entity)) === CUNIMOB_CATEGORY_BOSS;
  var chance = bossLike ? 0.50 : Math.min(0.30, 0.09 + level * 0.0012 + Math.max(0, Number(profile.weight || 1) - 1) * 0.016);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_snare_ms', bossLike ? 7800 : 11200, chance)) {
    return;
  }
  var amp = bossLike ? 5 : 3;
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:composter ~ ~0.08 ~ 1.2 0.08 1.2 0.02 34 force');
  server.runCommandSilent('effect give ' + safeName + ' minecraft:slowness 3 ' + amp + ' true');
  server.runCommandSilent('effect give ' + safeName + ' minecraft:mining_fatigue 4 ' + (bossLike ? 1 : 0) + ' true');
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Raices hostiles: rompe distancia o bloquea.', 'dark_green'));
}

function cunimobUseMythicMeteor(server, entity, attacker, dimension, mobId, level, rarity) {
  if (!server || !entity || !attacker || !dimension || !cunimobEntityHasTag(entity, CUNIMOB_ELITE_METEOR_TAG)) {
    return;
  }
  var safeName = cunihordeSafePlayer(attacker.username);
  if (!safeName) {
    return;
  }
  var bossLike = cunimobIsBossMob(mobId) || cunimobCategoryKey(cunimobCategoryFromEntity(entity)) === CUNIMOB_CATEGORY_BOSS;
  var threat = cunimobMythicThreatRank(entity, mobId, level, rarity || cunimobRarityProfileFromEntity(entity));
  var chance = bossLike ? 0.40 : Math.min(0.18, 0.035 + level * 0.0009 + threat * 0.016);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_meteor_ms', bossLike ? 12500 : 18000, chance)) {
    return;
  }
  var amount = Math.max(3, Math.min(bossLike ? 12 : 7, Math.floor(3 + level / (bossLike ? 25 : 45) + threat)));
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:flame ~ ~2.2 ~ 0.55 0.20 0.55 0.03 32 force');
  server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:smoke ~ ~0.1 ~ 1.4 0.05 1.4 0.01 20 force');
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Marca ardiente: sal del circulo.', 'gold'));
  server.scheduleInTicks(bossLike ? 22 : 28, function () {
    server.runCommandSilent('execute at ' + safeName + ' run particle minecraft:lava ~ ~0.25 ~ 1.4 0.18 1.4 0.08 24 force');
    server.runCommandSilent('execute at ' + safeName + ' run damage @a[distance=..3] ' + amount + ' minecraft:on_fire');
    server.runCommandSilent('execute at ' + safeName + ' run effect give @a[distance=..3] minecraft:weakness 4 0 true');
    server.runCommandSilent('execute at ' + safeName + ' run playsound minecraft:entity.generic.explode hostile @a[distance=..28] ~ ~ ~ 0.35 1.35');
  });
}

function cunimobSpawnReasonText(event) {
  var values = [];
  try { values.push(event.reason); } catch (ignored) { }
  try { values.push(event.spawnReason); } catch (ignored) { }
  try { values.push(event.spawnType); } catch (ignored) { }
  try { values.push(event.type); } catch (ignored) { }
  try { values.push(event.getReason()); } catch (ignored) { }
  try { values.push(event.getSpawnReason()); } catch (ignored) { }
  try { values.push(event.getSpawnType()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '').toLowerCase();
    if (text && text !== 'undefined' && text !== 'null') {
      return text;
    }
  }
  return '';
}

function cunimobIsSpawnerSpawn(event) {
  var text = cunimobSpawnReasonText(event);
  return text.indexOf('spawner') >= 0 || text.indexOf('mob_spawner') >= 0;
}

function cunimobMarkSpawnerMob(server, entity, dimension, mobId, x, y, z) {
  if (!server || !entity || !dimension || !mobId) {
    return;
  }
  try {
    entity.addTag(CUNIMOB_SPAWNER_MOB_TAG);
    entity.addTag(CUNIMOB_NO_RPG_REWARD_TAG);
  } catch (ignored) {
  }
  if (Math.random() < 0.35) {
    server.scheduleInTicks(1, function () {
      server.runCommandSilent('execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as @e[type=' + mobId + ',tag=' + CUNIMOB_SPAWNER_MOB_TAG + ',distance=..3,limit=1,sort=nearest] run kill @s');
    });
  }
}

function cunimobTryBlockIncomingAttack(event, entity, attacker, mobId, level, rarity) {
  if (!event || !entity || !attacker || !mobId) {
    return false;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfileFromEntity(entity);
  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(entity));
  var rarityWeight = Math.max(1, Number(profile && profile.weight || 1));
  var chance = 0.010 + Math.min(0.060, safeLevel * 0.00045) + Math.max(0, rarityWeight - 1) * 0.010;
  if (cunimobEntityHasTag(entity, CUNIMOB_GEAR_TAG)) {
    chance += 0.030;
  }
  if (categoryKey === CUNIMOB_CATEGORY_ELITE) {
    chance += 0.085;
  } else if (categoryKey === CUNIMOB_CATEGORY_BOSS) {
    chance += 0.155;
  }
  var cap = categoryKey === CUNIMOB_CATEGORY_BOSS ? 0.28 : (categoryKey === CUNIMOB_CATEGORY_ELITE ? 0.22 : 0.12);
  chance = Math.min(cap, chance);
  if (!cunimobRollEntityCooldown(entity, 'cuniculum_block_ms', categoryKey === CUNIMOB_CATEGORY_BOSS ? 3600 : 4200, chance)) {
    return false;
  }

  var server = cunimobServerFromEvent(event, entity, attacker);
  var dimension = cunimobDimensionFromEvent(event, entity);
  var safeName = cunihordeSafePlayer(attacker ? attacker.username : '');
  try { event.cancel(); } catch (ignored) { }
  if (server && dimension) {
    cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:crit ~ ~1.05 ~ 0.45 0.35 0.45 0.03 18 force');
    cunimobRunAsNearestMob(server, dimension, entity, mobId, 'particle minecraft:enchant ~ ~1.25 ~ 0.55 0.45 0.55 0.02 14 force');
    cunimobRunAsNearestMob(server, dimension, entity, mobId, 'playsound minecraft:item.shield.block hostile @a[distance=..18] ~ ~ ~ 0.65 0.82');
    if (safeName) {
      server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Bloqueo: el enemigo desvio tu ataque.', 'yellow'));
    }
  }
  return true;
}

function cunimobUseEliteCombatSkills(event, entity, attacker, mobId, level, dimension) {
  if (!event || !entity || !attacker || !dimension || cunimobEntityHasTag(entity, CUNIMOB_ELITE_MINION_TAG)) {
    return;
  }
  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = entity.server; } } catch (ignored) { }
  try { if (!server) { server = attacker.server; } } catch (ignored) { }
  if (!server) {
    return;
  }

  cunimobBossCallAttacker(server, entity, attacker, dimension, mobId, level);
  cunimobTrySoloBossPressure(server, entity, attacker, dimension, mobId, level);
  cunimobUseVanillaBossSignatureSkills(server, entity, attacker, dimension, mobId, level);
  var mythicRarity = cunimobRarityProfileFromEntity(entity);
  cunimobUseMythicGuard(server, entity, dimension, mobId, level, mythicRarity);
  cunimobUseMythicRuneBurst(server, entity, attacker, dimension, mobId, level, mythicRarity);
  cunimobUseMythicChainArc(server, entity, attacker, dimension, mobId, level, mythicRarity);
  cunimobUseMythicWarcry(server, entity, dimension, mobId, level, mythicRarity);
  cunimobUseMythicSnare(server, entity, attacker, dimension, mobId, level, mythicRarity);
  cunimobUseMythicMeteor(server, entity, attacker, dimension, mobId, level, mythicRarity);
  cunimobSummonEliteMinions(server, entity, attacker, dimension, mobId, level);
  cunimobBlinkBehindAttacker(server, entity, attacker, dimension, mobId, level);
  cunimobReflectDamage(server, entity, attacker, level);
  cunimobCastEliteSpell(server, entity, attacker, dimension, mobId, level);
  cunimobPullAttacker(server, entity, attacker, level);
}

function cunimobAuraPatternPoints(pattern) {
  if (pattern === 'crown') {
    return ['~0.55 ~1.55 ~0.25', '~-0.55 ~1.55 ~-0.25', '~0.25 ~1.85 ~-0.55', '~-0.25 ~1.85 ~0.55'];
  }
  if (pattern === 'low_ring') {
    return ['~0.85 ~0.25 ~', '~-0.85 ~0.25 ~', '~ ~0.25 ~0.85', '~ ~0.25 ~-0.85'];
  }
  if (pattern === 'runes') {
    return ['~0.80 ~0.85 ~0.25', '~-0.25 ~1.15 ~0.80', '~0.25 ~1.45 ~-0.80', '~-0.80 ~1.75 ~-0.25'];
  }
  if (pattern === 'spiral') {
    return ['~0.65 ~0.45 ~', '~ ~0.85 ~0.65', '~-0.65 ~1.25 ~', '~ ~1.65 ~-0.65'];
  }
  if (pattern === 'spark') {
    return ['~ ~1.20 ~'];
  }
  return ['~0.85 ~0.95 ~', '~-0.85 ~0.95 ~', '~ ~0.95 ~0.85', '~ ~0.95 ~-0.85'];
}

function cunimobAuraParticleFor(kind) {
  var boss = ['minecraft:soul_fire_flame', 'minecraft:dragon_breath', 'minecraft:reverse_portal', 'minecraft:electric_spark'];
  var elite = ['minecraft:enchant', 'minecraft:crit', 'minecraft:end_rod', 'minecraft:soul'];
  var mythic = ['minecraft:totem_of_undying', 'minecraft:end_rod', 'minecraft:dragon_breath', 'minecraft:electric_spark'];
  var legendary = ['minecraft:witch', 'minecraft:portal', 'minecraft:enchant', 'minecraft:flame'];
  var ambient = ['minecraft:end_rod', 'minecraft:enchant', 'minecraft:happy_villager', 'minecraft:soul'];
  if (kind === 'boss') return cunimobRandomChoice(boss);
  if (kind === 'elite') return cunimobRandomChoice(elite);
  if (kind === 'mythic') return cunimobRandomChoice(mythic);
  if (kind === 'legendary') return cunimobRandomChoice(legendary);
  return cunimobRandomChoice(ambient);
}

function cunimobAuraPatternFor(kind) {
  var roll = Math.random();
  if (kind === 'boss') {
    if (roll < 0.34) return 'low_ring';
    if (roll < 0.62) return 'runes';
    if (roll < 0.84) return 'spiral';
    return 'crown';
  }
  if (kind === 'elite') {
    if (roll < 0.42) return 'spiral';
    if (roll < 0.72) return 'runes';
    return 'low_ring';
  }
  if (kind === 'mythic') {
    if (roll < 0.45) return 'crown';
    if (roll < 0.75) return 'runes';
    return 'spark';
  }
  if (kind === 'legendary') {
    if (roll < 0.38) return 'runes';
    if (roll < 0.70) return 'low_ring';
    return 'spark';
  }
  return roll < 0.50 ? 'spark' : 'low_ring';
}

function cunimobRunAuraPattern(server, playerName, selector, kind, limit, maxPoints) {
  if (!server || !playerName || !selector) {
    return;
  }
  var particle = cunimobAuraParticleFor(kind);
  var points = cunimobAuraPatternPoints(cunimobAuraPatternFor(kind));
  var count = kind === 'boss' ? 1 : 1;
  var spread = kind === 'spark' ? '0.18 0.20 0.18 0.01' : '0.01 0.01 0.01 0';
  var used = Math.min(points.length, Math.max(1, maxPoints || points.length));
  var prefix = 'execute at ' + playerName + ' as ' + selector.replace('__LIMIT__', String(limit || 4)) + ' at @s run particle ' + particle + ' ';
  for (var i = 0; i < used; i++) {
    server.runCommandSilent(prefix + points[i] + ' ' + spread + ' ' + count + ' force');
  }
  if (kind === 'boss' && Math.random() < 0.28) {
    server.runCommandSilent('execute at ' + playerName + ' as ' + selector.replace('__LIMIT__', String(Math.max(1, Math.floor((limit || 4) / 2)))) + ' at @s run particle ' + cunimobAuraParticleFor('mythic') + ' ~ ~1.15 ~ 0.35 0.40 0.35 0.01 4 force');
  }
}

function cunimobRenderNearbyAuras(server, playerName) {
  var safeName = cunihordeSafePlayer(playerName);
  if (!server || !safeName) {
    return;
  }

  cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_BOSS_TAG + ',distance=..42,limit=__LIMIT__,sort=nearest]', 'boss', 4, 4);
  cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_ELITE_TAG + ',distance=..38,limit=__LIMIT__,sort=nearest]', 'elite', 6, 3);
  cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_RARITY_TAG_PREFIX + 'mythic,distance=..42,limit=__LIMIT__,sort=nearest]', 'mythic', 4, 3);
  cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_RARITY_TAG_PREFIX + 'legendary,distance=..42,limit=__LIMIT__,sort=nearest]', 'legendary', 4, 2);

  if (Math.random() < 0.55) {
    cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_AURA_TAG + ',distance=..34,limit=__LIMIT__,sort=nearest]', 'ambient', 6, 2);
  }
  if (Math.random() < 0.28) {
    cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_RARITY_TAG_PREFIX + 'epic,distance=..34,limit=__LIMIT__,sort=nearest]', 'elite', 3, 1);
  }
  if (Math.random() < 0.10) {
    cunimobRunAuraPattern(server, safeName, '@e[tag=' + CUNIMOB_RARITY_TAG_PREFIX + 'rare,distance=..28,limit=__LIMIT__,sort=nearest]', 'ambient', 2, 1);
  }
}

function cunimobBeneficialEffectsToPurge(level) {
  var effects = [
    'minecraft:strength',
    'minecraft:speed',
    'minecraft:haste',
    'minecraft:regeneration',
    'minecraft:resistance',
    'minecraft:absorption',
    'minecraft:fire_resistance',
    'minecraft:jump_boost',
    'minecraft:night_vision',
    'minecraft:water_breathing',
    'minecraft:slow_falling',
    'minecraft:luck',
    'minecraft:invisibility',
    'minecraft:saturation',
    'minecraft:conduit_power',
    'minecraft:hero_of_the_village'
  ];
  var count = level >= 90 ? 5 : (level >= 70 ? 4 : (level >= 50 ? 3 : 2));
  var picked = [];
  var available = effects.slice();
  while (picked.length < count && available.length > 0) {
    var index = Math.floor(Math.random() * available.length);
    picked.push(available[index]);
    available.splice(index, 1);
  }
  return picked;
}

function cunimobDispelPlayerBuffs(server, mob, player, level) {
  if (!cunimobEntityHasTag(mob, CUNIMOB_ELITE_DISPEL_TAG) || level < 38) {
    return false;
  }
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!safeName || !cunimobRollEntityCooldown(mob, 'cuniculum_dispel_ms', 10000, Math.min(0.46, 0.13 + level * 0.0024))) {
    return false;
  }
  var effects = cunimobBeneficialEffectsToPurge(level);
  for (var i = 0; i < effects.length; i++) {
    server.runCommandSilent('effect clear ' + safeName + ' ' + effects[i]);
  }
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Disipacion: el enemigo rompio parte de tus efectos activos.', 'dark_purple'));
  return true;
}

function cunimobSunderPlayerEquipment(server, mob, player, level) {
  if (!cunimobEntityHasTag(mob, CUNIMOB_ELITE_SUNDER_TAG) || level < 35) {
    return false;
  }
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!safeName || !cunimobRollEntityCooldown(mob, 'cuniculum_sunder_ms', 2800, Math.min(0.64, 0.24 + level * 0.0028))) {
    return false;
  }

  var slots = cunimobEquipmentSlotsForPlayer();
  var damaged = 0;
  var amount = Math.max(2, Math.min(18, Math.floor(2 + level / 18)));
  for (var i = 0; i < slots.length; i++) {
    if (Math.random() < 0.62 && cunimobDamageEquipmentStack(player, slots[i].slot, amount)) {
      damaged++;
    }
  }
  if (damaged > 0) {
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Quebrantamiento: tu armadura se desgasto por el golpe.', 'red'));
    return true;
  }
  return false;
}

function cunimobDisarmPlayer(server, mob, player, level) {
  if (!cunimobEntityHasTag(mob, CUNIMOB_ELITE_DISARM_TAG) || level < 50) {
    return false;
  }
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!safeName || !cunimobRollEntityCooldown(mob, 'cuniculum_disarm_ms', 16000, Math.min(0.24, 0.055 + level * 0.0013))) {
    return false;
  }

  var options = [
    { slot: 'MAINHAND', label: 'arma principal' },
    { slot: 'OFFHAND', label: 'arma u objeto secundario' }
  ];
  var armor = cunimobEquipmentSlotsForPlayer();
  for (var i = 0; i < armor.length; i++) {
    options.push({ slot: armor[i].slot, label: armor[i].label });
  }

  var selected = cunimobRandomChoice(options);
  if (selected && cunimobDropAndClearEquipment(player, selected.slot)) {
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Desarme: el enemigo te arranco ' + selected.label + '. Recuperalo rapido.', 'gold'));
    return true;
  }

  server.runCommandSilent('effect give ' + safeName + ' minecraft:weakness 5 1 true');
  server.runCommandSilent('effect give ' + safeName + ' minecraft:mining_fatigue 5 1 true');
  server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Desarme resistido: pierdes fuerza por unos segundos.', 'gold'));
  return false;
}

function cunimobPlayerCanHaveInventoryShuffled(player) {
  if (!player) {
    return false;
  }
  try { if (player.isCreative && player.isCreative()) { return false; } } catch (ignoredCreative) { }
  try { if (player.isSpectator && player.isSpectator()) { return false; } } catch (ignoredSpectator) { }
  return true;
}

function cunimobInventorySlotHasItem(stack) {
  if (!stack) {
    return false;
  }
  try { if (stack.isEmpty && stack.isEmpty()) { return false; } } catch (ignoredEmpty) { }
  var id = cunimobStackId(stack);
  return !!id && id !== 'minecraft:air';
}

function cunimobCopyStackForSwap(stack) {
  if (!stack) {
    return stack;
  }
  try { return stack.copy(); } catch (ignoredCopy) { }
  return stack;
}

function cunimobShufflePlayerInventory(server, mob, player, level) {
  if (!server || !mob || !player || !cunimobPlayerCanHaveInventoryShuffled(player)) {
    return false;
  }

  var categoryKey = cunimobCategoryKey(cunimobCategoryFromEntity(mob));
  var bossLike = categoryKey === CUNIMOB_CATEGORY_BOSS || cunimobIsBossMob(cunimobEntityTypeId(mob));
  if (!bossLike && !cunimobEntityHasTag(mob, CUNIMOB_ELITE_SHUFFLE_TAG)) {
    return false;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (!bossLike && safeLevel < 24) {
    return false;
  }

  var cooldown = bossLike ? CUNIMOB_BOSS_INVENTORY_SHUFFLE_COOLDOWN_MS : CUNIMOB_INVENTORY_SHUFFLE_COOLDOWN_MS;
  var chance = bossLike
    ? Math.min(0.62, 0.34 + safeLevel * 0.0017)
    : Math.min(0.34, 0.08 + safeLevel * 0.0012);
  if (!cunimobRollEntityCooldown(mob, 'cuniculum_inventory_shuffle_ms', cooldown, chance)) {
    return false;
  }

  var inventory = null;
  try { inventory = player.getInventory(); } catch (ignoredInventory) { }
  if (!inventory) {
    return false;
  }

  var size = 36;
  try { size = Math.min(36, Math.max(0, Number(inventory.getContainerSize()))); } catch (ignoredSize) { }
  var slots = [];
  for (var slot = 0; slot < size; slot++) {
    var stack = null;
    try { stack = inventory.getItem(slot); } catch (ignoredGet) { }
    if (cunimobInventorySlotHasItem(stack)) {
      slots.push(slot);
    }
  }
  if (slots.length < 2) {
    return false;
  }

  var swaps = Math.min(slots.length * 2, (bossLike ? 8 : 4) + Math.floor(safeLevel / 28));
  for (var i = 0; i < swaps; i++) {
    var a = slots[Math.floor(Math.random() * slots.length)];
    var b = slots[Math.floor(Math.random() * slots.length)];
    if (a === b) {
      continue;
    }
    try {
      var stackA = cunimobCopyStackForSwap(inventory.getItem(a));
      var stackB = cunimobCopyStackForSwap(inventory.getItem(b));
      inventory.setItem(a, stackB);
      inventory.setItem(b, stackA);
    } catch (ignoredSwap) {
      return false;
    }
  }

  try { inventory.setChanged(); } catch (ignoredChanged) { }
  try { player.containerMenu.broadcastChanges(); } catch (ignoredBroadcast) { }
  var safeName = cunihordeSafePlayer(player.username);
  if (safeName) {
    server.runCommandSilent('title ' + safeName + ' actionbar ' + cunihordeJson('Desorden: tu inventario fue revuelto por el enemigo.', 'dark_purple'));
    server.runCommandSilent('playsound minecraft:block.shulker_box.open player ' + safeName + ' ~ ~ ~ 0.45 0.70');
  }
  return true;
}

function cunimobUseEliteHitSkills(event, player, mob, mobId, level, dimension) {
  if (!event || !player || !mob || !dimension || cunimobEntityHasTag(mob, CUNIMOB_ELITE_MINION_TAG)) {
    return;
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < 35 && !cunimobEntityHasTag(mob, CUNIMOB_ELITE_SHUFFLE_TAG) && !cunimobIsBossMob(mobId)) {
    return;
  }

  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = player.server; } } catch (ignored) { }
  try { if (!server) { server = mob.server; } } catch (ignored) { }
  if (!server) {
    return;
  }

  cunimobTrySoloBossPressure(server, mob, player, cunimobDimensionFromEvent(event, mob), mobId, safeLevel);
  cunimobUseVanillaBossSignatureSkills(server, mob, player, cunimobDimensionFromEvent(event, mob), mobId, safeLevel);
  cunimobUseMythicPressureHit(server, mob, player, cunimobDimensionFromEvent(event, mob), mobId, safeLevel);
  cunimobDispelPlayerBuffs(server, mob, player, safeLevel);
  cunimobSunderPlayerEquipment(server, mob, player, safeLevel);
  cunimobDisarmPlayer(server, mob, player, safeLevel);
  cunimobShufflePlayerInventory(server, mob, player, safeLevel);
}

function cunimobAddCoinDrop(event, itemId, amount) {
  if (!event || !itemId || amount <= 0) {
    return;
  }
  try {
    event.addDrop(Item.of(itemId, amount));
  } catch (ignored) {
  }
}

function cunimobDropApotheosisSalvageMaterials(event, level, rarity, category, worldTierKey) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  var profile = rarity || cunimobRarityProfileByKey('common');
  var boss = cunimobCategoryKey(category) === CUNIMOB_CATEGORY_BOSS;
  var tierIndex = cunimobWorldTierIndex(cunimobWorldTierProfileByKey(worldTierKey).key);
  var materialRate = boss ? Math.max(CUNIMOB_MATERIAL_DROP_RATE_MULTIPLIER, 0.58) : CUNIMOB_MATERIAL_DROP_RATE_MULTIPLIER;
  var shardPool = [
    { minLevel: 1, minWorld: 0, item: 'apotheosis:common_material', chance: 0.020, amount: 1 },
    { minLevel: 18, minWorld: 0, item: 'apotheosis:uncommon_material', chance: 0.014, amount: 1 },
    { minLevel: 35, minWorld: 1, item: 'apotheosis:rare_material', chance: 0.010, amount: 1 },
    { minLevel: 60, minWorld: 2, item: 'apotheosis:epic_material', chance: 0.0050, amount: 1 },
    { minLevel: 90, minWorld: 4, item: 'apotheosis:mythic_material', chance: 0.0018, amount: 1 }
  ];
  for (var i = 0; i < shardPool.length; i++) {
    var entry = shardPool[i];
    if (safeLevel < entry.minLevel || tierIndex < entry.minWorld) {
      continue;
    }
    var chance = (entry.chance + profile.weight * 0.0015 + (boss ? entry.chance * 1.4 : 0)) * materialRate;
    if (Math.random() < Math.min(0.085, chance)) {
      cunimobAddCoinDrop(event, entry.item, entry.amount);
    }
  }
  if (safeLevel >= 20 && Math.random() < Math.min(0.10, (0.014 + profile.weight * 0.003 + (boss ? 0.025 : 0)) * materialRate)) {
    cunimobAddCoinDrop(event, 'apotheosis:gem_dust', Math.max(1, Math.min(3, Math.floor(profile.weight / 2))));
  }
}

function cunimobDropFamilyFromItemText(itemText) {
  var text = String(itemText || '').toLowerCase();
  if (!text) {
    return '';
  }
  if (text.indexOf('cuniculum_kind:"armor"') >= 0 || text.indexOf('cuniculum_kind:armor') >= 0) {
    return 'armor';
  }
  if (text.indexOf('cuniculum_kind:"weapon"') >= 0 || text.indexOf('cuniculum_kind:weapon') >= 0) {
    return 'weapon';
  }
  if (text.indexOf('cuniculum_kind:"tool"') >= 0 || text.indexOf('cuniculum_kind:tool') >= 0) {
    return 'tool';
  }
  if (text.indexOf('cuniculum_kind:"artifact"') >= 0 || text.indexOf('cuniculum_kind:artifact') >= 0 || text.indexOf('artifacts:') === 0) {
    return 'artifact';
  }
  if (text.indexOf('_helmet') >= 0 || text.indexOf('_chestplate') >= 0 || text.indexOf('_leggings') >= 0 || text.indexOf('_boots') >= 0
    || text.indexOf('_armor_head') >= 0 || text.indexOf('_armor_chest') >= 0 || text.indexOf('_armor_legs') >= 0 || text.indexOf('_armor_feet') >= 0
    || text.indexOf('_robe_head') >= 0 || text.indexOf('_robe_chest') >= 0 || text.indexOf('_robe_legs') >= 0 || text.indexOf('_robe_feet') >= 0
    || text.indexOf('_garb_head') >= 0 || text.indexOf('_garb_chest') >= 0 || text.indexOf('_garb_legs') >= 0 || text.indexOf('_garb_feet') >= 0) {
    return 'armor';
  }
  if (text.indexOf('_pickaxe') >= 0 || text.indexOf('_shovel') >= 0 || text.indexOf('_hoe') >= 0 || text.indexOf('fishing_rod') >= 0) {
    return 'tool';
  }
  if (text.indexOf('_sword') >= 0 || text.indexOf('_axe') >= 0 || text.indexOf('_bow') >= 0 || text.indexOf('crossbow') >= 0
    || text.indexOf('_dagger') >= 0 || text.indexOf('_mace') >= 0 || text.indexOf('_hammer') >= 0 || text.indexOf('_spear') >= 0
    || text.indexOf('staff_') >= 0 || text.indexOf('_staff') >= 0 || text.indexOf('_knuckle') >= 0 || text.indexOf('trident') >= 0) {
    return 'weapon';
  }
  return 'special';
}

function cunimobDropFamilyAlreadyUsed(event, family) {
  if (!event || !family) {
    return false;
  }
  try {
    if (!event.cuniculumDropFamilies) {
      event.cuniculumDropFamilies = {};
    }
    if (event.cuniculumDropFamilies[family]) {
      return true;
    }
    event.cuniculumDropFamilies[family] = true;
    return false;
  } catch (ignored) {
    return false;
  }
}

function cunimobAddRpgDrop(event, itemId) {
  if (!event || !itemId) {
    return;
  }
  var family = cunimobDropFamilyFromItemText(itemId);
  if (family && cunimobDropFamilyAlreadyUsed(event, family)) {
    return;
  }
  try {
    event.addDrop(Item.of(itemId));
  } catch (ignored) {
  }
}

function cunimobDropCoins(event, mobId, level, rarity, category) {
  if (!cunimobIsCustomRewardMob(mobId)) {
    return;
  }

  var boss = cunimobIsBossMob(mobId) || cunimobCategoryKey(category) === CUNIMOB_CATEGORY_BOSS;
  var profile = rarity || cunimobRarityProfileByKey('common');
  var chance = boss ? Math.min(0.58, 0.24 + level * 0.0048) : Math.min(0.24, 0.024 + profile.weight * 0.012 + level * 0.0018);
  if (Math.random() > chance) {
    return;
  }

  var copper = Math.max(1, Math.min(6, Math.floor((profile.weight + Math.floor(level / 24)) / 2) + 1));
  if (boss) {
    copper += 2 + Math.floor(profile.weight / 2);
  }
  cunimobAddCoinDrop(event, 'lightmanscurrency:coin_copper', copper);

  if (level >= 15 && Math.random() < Math.min(0.16, 0.012 + profile.weight * 0.008 + level * 0.0009)) {
    cunimobAddCoinDrop(event, 'lightmanscurrency:coin_iron', boss ? 1 + Math.floor(profile.weight / 3) : 1);
  }
  if (level >= 35 && Math.random() < Math.min(0.075, 0.007 + profile.weight * 0.0045 + level * 0.00055)) {
    cunimobAddCoinDrop(event, 'lightmanscurrency:coin_gold', boss ? 1 + Math.floor(profile.weight / 5) : 1);
  }
  if (level >= 60 && Math.random() < Math.min(0.032, 0.003 + profile.weight * 0.002 + level * 0.00018 + (boss ? 0.014 : 0))) {
    cunimobAddCoinDrop(event, 'lightmanscurrency:coin_emerald', 1);
  }
  if (level >= 95 && Math.random() < Math.min(0.012, 0.0015 + profile.weight * 0.0008 + level * 0.00005 + (boss ? 0.008 : 0))) {
    cunimobAddCoinDrop(event, 'lightmanscurrency:coin_diamond', 1);
  }
  if (boss && level >= 130 && Math.random() < 0.010) {
    cunimobAddCoinDrop(event, 'lightmanscurrency:coin_netherite', 1);
  }
}

function cunimobDropRpgRewards(event, mobId, level, rarity, category, worldTierKey, playerClass) {
  if (!cunimobIsCustomRewardMob(mobId)) {
    return;
  }

  var profile = rarity || cunimobRarityProfileByKey('common');
  var boss = cunimobIsBossMob(mobId) || cunimobCategoryKey(category) === CUNIMOB_CATEGORY_BOSS;
  var dropWorldTier = cunimobWorldTierProfileByKey(worldTierKey).key;
  var worldTierIndex = cunimobWorldTierIndex(dropWorldTier);
  var materialRate = boss ? Math.max(CUNIMOB_MATERIAL_DROP_RATE_MULTIPLIER, 0.58) : CUNIMOB_MATERIAL_DROP_RATE_MULTIPLIER;
  if (level >= 12 && Math.random() < Math.min(0.38, 0.04 + profile.weight * 0.035 + level * 0.0018) * materialRate) {
    cunimobAddCoinDrop(event, 'minecraft:experience_bottle', Math.max(1, Math.min(8, Math.floor(level / 16) + Math.floor(profile.weight / 3))));
  }
  if (worldTierIndex >= 1 && level >= 35 && Math.random() < Math.min(0.12, 0.015 + profile.weight * 0.01) * materialRate) {
    cunimobAddCoinDrop(event, 'minecraft:emerald', Math.max(1, Math.min(3, Math.floor(profile.weight / 2))));
  }
  if (worldTierIndex >= 2 && level >= 50 && Math.random() < Math.min(0.08, 0.01 + profile.weight * 0.006) * materialRate) {
    cunimobAddCoinDrop(event, 'minecraft:amethyst_shard', Math.max(1, Math.min(4, Math.floor(profile.weight / 2))));
  }
  if (worldTierIndex >= 3 && level >= 70 && Math.random() < (0.035 + (boss ? 0.035 : 0)) * materialRate) {
    cunimobAddCoinDrop(event, 'minecraft:echo_shard', 1);
  }
  if (worldTierIndex >= 4 && level >= 90 && Math.random() < (0.018 + (boss ? 0.025 : 0)) * materialRate) {
    cunimobAddCoinDrop(event, 'minecraft:netherite_scrap', 1);
  }

  cunimobDropApotheosisSalvageMaterials(event, level, profile, category, dropWorldTier);
  cunimobDropGuaranteedTieredReward(event, mobId, level, boss, profile, category, dropWorldTier, playerClass);
  cunimobDropTieredEquipment(event, mobId, level, boss, profile, dropWorldTier, playerClass);
  cunimobDropCategoryItems(event, level, boss, profile, dropWorldTier, playerClass);
  cunimobDropPhantomFallback(event, mobId, level, profile);
}

function cunimobCanLeaveDeathPoison(mobId) {
  var id = String(mobId || '').toLowerCase();
  if (!id || id === 'minecraft:creeper') {
    return false;
  }
  return cunimobIsCustomRewardMob(id);
}

function cunimobSpawnDeathPoison(event, entity, mobId, level, rarity, category) {
  var safeLevel = Math.max(1, Math.floor(Number(level || 1)));
  if (safeLevel < CUNIMOB_DEATH_POISON_LEVEL || !cunimobCanLeaveDeathPoison(mobId)) {
    return;
  }

  var boss = cunimobIsBossMob(mobId) || cunimobCategoryKey(category) === CUNIMOB_CATEGORY_BOSS;
  var profile = rarity || cunimobRarityProfileByKey('common');
  var chance = Math.min(0.46, 0.055 + Math.max(0, safeLevel - CUNIMOB_DEATH_POISON_LEVEL) * 0.0022 + profile.weight * 0.012 + (boss ? 0.12 : 0));
  if (Math.random() >= chance) {
    return;
  }

  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = entity.server; } } catch (ignored) { }
  var dimension = cunimobDimensionFromEvent(event, entity);
  if (!server || !cunimobIsCombatDimension(dimension)) {
    return;
  }

  var pos = cunimobEntityPosition(entity);
  var radiusCeil = Math.min(CUNIMOB_DEATH_POISON_MAX_RADIUS, CUNIMOB_DEATH_POISON_MIN_RADIUS + Math.floor(safeLevel / 16));
  var radius = Math.max(CUNIMOB_DEATH_POISON_MIN_RADIUS, Math.floor(CUNIMOB_DEATH_POISON_MIN_RADIUS + Math.random() * (radiusCeil - CUNIMOB_DEATH_POISON_MIN_RADIUS + 1)));
  var amplifier = safeLevel >= 110 ? 2 : (safeLevel >= 65 ? 1 : 0);
  var pulses = safeLevel >= 95 ? 9 : (safeLevel >= 60 ? 7 : 5);

  for (var i = 0; i < pulses; i++) {
    server.scheduleInTicks(i * 20, function () {
      server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run particle minecraft:witch ~ ~0.12 ~ ' + radius + ' 0.08 ' + radius + ' 0.02 90 force');
      server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run effect give @a[distance=..' + radius + '] minecraft:poison 2 ' + amplifier + ' true');
    });
  }
}

ServerEvents.loaded(event => {
  event.server.runCommandSilent('execute as @e[tag=' + CUNIMOB_COMBAT_TAG + '] run tag @s remove ' + CUNIMOB_COMBAT_TAG);
  event.server.runCommandSilent('execute as @e[tag=' + CUNIMOB_HEAL_TARGET_TAG + '] run tag @s remove ' + CUNIMOB_HEAL_TARGET_TAG);
  cunimobEnsureVisibleNames(event.server);
  cunimobCleanupOldDisplayLabels(event.server, '');
  cunihordeSetAuto(event.server, cunihordeAutoEnabled(event.server));
});

function cunimobSpawnManualFromSource(source, rawMobId, rawLevel, rawRarity, rawCategory) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }

  var safeName = cunihordeSafePlayer(player.username);
  var mobId = cunimobNormalizeMobId(rawMobId);
  var forcedLevel = Math.max(1, Math.floor(Number(rawLevel || 1)));
  if (!safeName || !mobId || !cunimobIsVisualTarget(mobId) || cunimobIsBossMob(mobId)) {
    server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Mob no permitido o invalido para /cunimob.', 'red'));
    return 0;
  }

  var rarity = rawRarity ? cunimobRarityProfileByKey(rawRarity) : cunimobRarityProfileByKey('common');
  var category = cunimobCategoryKey(rawCategory || CUNIMOB_CATEGORY_NORMAL);
  rarity = cunimobBossMinimumRarity(mobId, rarity, category);
  var dimension = cunimobDimensionFromLevel(player.level);
  var x = Math.round(Number(player.x) * 100) / 100;
  var y = Math.round(Number(player.y) * 100) / 100;
  var z = Math.round(Number(player.z) * 100) / 100;

  server.runCommandSilent('execute at ' + safeName + ' run summon ' + mobId + ' ~ ~ ~ {Tags:["' + CUNIMOB_MANUAL_SPAWN_TAG + '"]}');
  server.scheduleInTicks(4, function () {
    var manualPositioned = 'execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as @e[type=' + mobId + ',distance=..4,tag=' + CUNIMOB_MANUAL_SPAWN_TAG + ',limit=1,sort=nearest]';
    cunimobClearKnownLevelTags(server, manualPositioned, 512);
    server.runCommandSilent(manualPositioned + ' run tag @s remove ' + CUNIMOB_GEAR_TAG);
    cunimobApplyVisualNameAt(server, dimension, x, y, z, mobId, forcedLevel, 'manual', 4, CUNIMOB_MANUAL_SPAWN_TAG, rarity, category);
    server.runCommandSilent(manualPositioned + ' run tag @s remove ' + CUNIMOB_MANUAL_SPAWN_TAG);
  });

  var label = cunimobCategoryLabel(category) || 'NORMAL';
  server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Invocado ' + mobId + ' nv ' + forcedLevel + ', rareza ' + rarity.tag + ', categoria ' + label + '.', 'gold'));
  return 1;
}

function cuniitemFeedback(server, playerName, text, color) {
  var safeName = cunihordeSafePlayer(playerName);
  if (!server || !safeName) {
    return;
  }
  server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] ' + text, color || 'gold'));
}

function cuniitemTierByKey(rawTier) {
  var key = String(rawTier || '').trim().toLowerCase();
  var aliases = {
    inicial: 'madriguera',
    starter: 'madriguera',
    start: 'madriguera',
    tunel: 'guardia',
    tunnel: 'guardia',
    guardia: 'guardia',
    explorador: 'explorador',
    explorer: 'explorador',
    vigia: 'vigia',
    cristal: 'vigia',
    juramento: 'juramento',
    sombra: 'juramento',
    mitico: 'mitico',
    mythic: 'mitico'
  };
  if (aliases[key]) {
    key = aliases[key];
  }
  return cunimobLootTierByKey(key);
}

function cuniitemSelector(rawType) {
  var type = String(rawType || '').trim().toLowerCase();
  var selector = { kind: type, slot: '', role: '', family: '' };
  if (type === 'armadura' || type === 'armor' || type === 'set') selector.kind = 'armor';
  if (type === 'arma' || type === 'weapon') selector.kind = 'weapon';
  if (type === 'herramienta' || type === 'tool') selector.kind = 'tool';
  if (type === 'casco' || type === 'helmet' || type === 'head') { selector.kind = 'armor'; selector.slot = 'head'; }
  if (type === 'pechera' || type === 'chest' || type === 'chestplate') { selector.kind = 'armor'; selector.slot = 'chest'; }
  if (type === 'pantalon' || type === 'pantalones' || type === 'legs' || type === 'leggings') { selector.kind = 'armor'; selector.slot = 'legs'; }
  if (type === 'botas' || type === 'boots' || type === 'feet') { selector.kind = 'armor'; selector.slot = 'feet'; }
  if (type === 'pico' || type === 'pickaxe' || type === 'minero' || type === 'miner') { selector.kind = 'tool'; selector.role = 'miner'; }
  if (type === 'hacha' || type === 'axe' || type === 'lenador' || type === 'wood') { selector.kind = 'tool'; selector.role = 'wood'; }
  if (type === 'pala' || type === 'shovel' || type === 'excavador' || type === 'dig') { selector.kind = 'tool'; selector.role = 'dig'; }
  if (type === 'azada' || type === 'hoe' || type === 'granjero' || type === 'farm') { selector.kind = 'tool'; selector.role = 'farm'; }
  if (type === 'cana' || type === 'caña' || type === 'fishing' || type === 'fish') { selector.kind = 'tool'; selector.role = 'fish'; }
  if (type === 'arco' || type === 'bow') { selector.kind = 'weapon'; selector.family = 'bow'; }
  if (type === 'ballesta' || type === 'crossbow') { selector.kind = 'weapon'; selector.family = 'crossbow'; }
  if (type === 'daga' || type === 'dagger') { selector.kind = 'weapon'; selector.family = 'dagger'; }
  if (type === 'lanza' || type === 'spear') { selector.kind = 'weapon'; selector.family = 'spear'; }
  if (type === 'baston' || type === 'staff') { selector.kind = 'weapon'; selector.family = 'staff'; }
  if (type === 'pesada' || type === 'heavy' || type === 'martillo' || type === 'hammer' || type === 'maza' || type === 'mace') { selector.kind = 'weapon'; selector.family = 'heavy'; }
  if (type === 'nudillos' || type === 'knuckle') { selector.kind = 'weapon'; selector.family = 'knuckle'; }
  if (type === 'espada' || type === 'sword' || type === 'blade') { selector.kind = 'weapon'; selector.family = 'blade'; }
  if (type === 'especial' || type === 'special' || type === 'artifact' || type === 'artefacto') selector.kind = 'special';
  return selector;
}

function cuniitemArmorSlot(entry) {
  var id = String(entry && entry.id || '').toLowerCase();
  if (id.indexOf('_helmet') >= 0 || id.indexOf('_head') >= 0 || id.indexOf('hood') >= 0 || id.indexOf('hat') >= 0) return 'head';
  if (id.indexOf('_chestplate') >= 0 || id.indexOf('_chest') >= 0 || id.indexOf('robe') >= 0 || id.indexOf('tunic') >= 0) return 'chest';
  if (id.indexOf('_leggings') >= 0 || id.indexOf('_legs') >= 0 || id.indexOf('pants') >= 0) return 'legs';
  if (id.indexOf('_boots') >= 0 || id.indexOf('_feet') >= 0 || id.indexOf('shoes') >= 0) return 'feet';
  return '';
}

function cuniitemEntryMatchesSelector(entry, selector) {
  if (!entry || !entry.id || !selector) {
    return false;
  }
  if (selector.kind === 'armor') {
    return !selector.slot || cuniitemArmorSlot(entry) === selector.slot;
  }
  if (selector.kind === 'tool') {
    return !selector.role || String(entry.role || '').toLowerCase() === selector.role;
  }
  if (selector.kind === 'weapon') {
    return !selector.family || cunimobWeaponFamily(entry.id) === selector.family;
  }
  return false;
}

function cuniitemEntriesForSelector(tier, selector) {
  if (!tier || !selector) {
    return [];
  }
  var source = [];
  if (selector.kind === 'armor') source = tier.armor || [];
  if (selector.kind === 'tool') source = tier.tools || [];
  if (selector.kind === 'weapon') source = tier.weapons || [];
  var matches = [];
  for (var i = 0; i < source.length; i++) {
    if (cuniitemEntryMatchesSelector(source[i], selector)) {
      matches.push(source[i]);
    }
  }
  return matches.length ? matches : source;
}

function cuniitemBuildFromEntry(entry, tier, selector, level, itemRarityKey, mobId, forcedMiningShape) {
  if (!entry || !entry.id || !tier || !selector) {
    return '';
  }
  var safeLevel = Math.max(1, Math.floor(Number(level || tier.min || 1)));
  var itemRarity = cunimobApothItemRarityByKey(itemRarityKey || 'common');
  var mobProfile = cunimobRarityProfileByKey(itemRarity.key);
  var kind = selector.kind || (cunimobIsArmorItem(entry.id) ? 'armor' : (cunimobIsToolItem(entry.id) ? 'tool' : 'weapon'));
  var enchants = cunimobEnchantmentsForDrop(entry.id, safeLevel, tier, mobId || 'minecraft:zombie', kind, mobProfile, itemRarity);
  var data = {
    cuniculum_tier: tier.key,
    cuniculum_kind: kind,
    cuniculum_rarity: mobProfile.key,
    cuniculum_apotheosis_rarity: itemRarity.key,
    cuniculum_test_item: true
  };
  if (kind === 'armor') {
    data.cuniculum_set = tier.key;
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'armor', '', '', entry.id), safeLevel, tier, itemRarity);
  } else if (kind === 'tool') {
    data.cuniculum_tool = entry.role || selector.role || 'utility';
    var miningShape = forcedMiningShape || cunimobMiningShapeForDrop(safeLevel, tier, itemRarity, data.cuniculum_tool);
    if (miningShape) {
      data.cuniculum_mining_shape = miningShape;
    }
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'tool', data.cuniculum_tool, '', entry.id), safeLevel, tier, itemRarity);
  } else {
    var family = cunimobWeaponFamily(entry.id);
    data.cuniculum_family = family;
    data.cuniculum_slayer = cunimobWeaponEnchantForMob(mobId || 'minecraft:zombie', entry.id);
    cunimobAssignDropTraits(data, cunimobRollDropTraits(safeLevel, tier, itemRarity, 'weapon', '', family, entry.id), safeLevel, tier, itemRarity);
  }
  return cunimobBuildDropItem(entry.id, cunimobDecoratedName(entry.name, tier, mobId || 'minecraft:zombie', kind), itemRarity.color, enchants, data);
}

function cuniitemGiveRaw(server, playerName, itemText, label) {
  var safeName = cunihordeSafePlayer(playerName);
  if (!server || !safeName || !itemText) {
    return false;
  }
  server.runCommandSilent('give ' + safeName + ' ' + itemText);
  cuniitemFeedback(server, safeName, 'Entregado: ' + (label || 'item especial') + '.', 'gold');
  return true;
}

function cuniitemGiveFromSource(source, rawTier, rawType, rawItemRarity, rawLevel, rawMobId) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }
  var safeName = cunihordeSafePlayer(player.username);
  var tier = cuniitemTierByKey(rawTier);
  var selector = cuniitemSelector(rawType);
  if (!tier || !selector || selector.kind === 'special') {
    cuniitemFeedback(server, safeName, 'Uso: /cuniitem give <tier> <tipo> <rareza_item> <nivel>. Tipo invalido.', 'red');
    return 0;
  }
  var entries = cuniitemEntriesForSelector(tier, selector);
  var entry = cunimobRandomChoice(entries);
  if (!entry) {
    cuniitemFeedback(server, safeName, 'No hay items para tier ' + tier.key + ' y tipo ' + rawType + '.', 'red');
    return 0;
  }
  var itemText = cuniitemBuildFromEntry(entry, tier, selector, rawLevel, rawItemRarity, cunimobNormalizeMobId(rawMobId || 'zombie'), '');
  return cuniitemGiveRaw(server, safeName, itemText, tier.label + ' / ' + selector.kind + ' / ' + rawItemRarity) ? 1 : 0;
}

function cuniitemGiveSetFromSource(source, rawTier, rawItemRarity, rawLevel) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }
  var safeName = cunihordeSafePlayer(player.username);
  var tier = cuniitemTierByKey(rawTier);
  var slots = ['head', 'chest', 'legs', 'feet'];
  var count = 0;
  for (var i = 0; i < slots.length; i++) {
    var selector = { kind: 'armor', slot: slots[i], role: '', family: '' };
    var entry = cunimobRandomChoice(cuniitemEntriesForSelector(tier, selector));
    if (!entry) {
      continue;
    }
    var itemText = cuniitemBuildFromEntry(entry, tier, selector, rawLevel, rawItemRarity, 'minecraft:zombie', '');
    if (cuniitemGiveRaw(server, safeName, itemText, tier.label + ' / pieza ' + slots[i])) {
      count++;
    }
  }
  cuniitemFeedback(server, safeName, 'Set de prueba entregado. Piezas: ' + count + '/4.', count === 4 ? 'green' : 'yellow');
  return count > 0 ? 1 : 0;
}

function cuniitemGiveMiningFromSource(source, rawTier, rawItemRarity, rawShape, rawLevel) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }
  var safeName = cunihordeSafePlayer(player.username);
  var shape = String(rawShape || '').toLowerCase();
  var valid = ['1x2', '1x3', '2x2', '2x3', '3x2', '3x3'];
  if (valid.indexOf(shape) < 0) {
    cuniitemFeedback(server, safeName, 'Forma invalida. Usa 1x2, 1x3, 2x2, 2x3, 3x2 o 3x3.', 'red');
    return 0;
  }
  var tier = cuniitemTierByKey(rawTier);
  var selector = { kind: 'tool', slot: '', role: 'miner', family: '' };
  var entry = cunimobRandomChoice(cuniitemEntriesForSelector(tier, selector));
  if (!entry) {
    cuniitemFeedback(server, safeName, 'No hay pico/herramienta minera para ese tier.', 'red');
    return 0;
  }
  var itemText = cuniitemBuildFromEntry(entry, tier, selector, rawLevel || Math.max(1, tier.min || 1), rawItemRarity, 'minecraft:zombie', shape);
  return cuniitemGiveRaw(server, safeName, itemText, tier.label + ' / mineria ' + shape) ? 1 : 0;
}

function cuniitemGiveSpecialFromSource(source, rawIndex) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }
  var safeName = cunihordeSafePlayer(player.username);
  var index = Math.floor(Number(rawIndex || 0)) - 1;
  if (index < 0 || index >= CUNIMOB_RPG_CATEGORY_DROPS.length) {
    cuniitemFeedback(server, safeName, 'Indice invalido. Usa /cuniitem list para ver rangos; el .md tiene la lista completa.', 'red');
    return 0;
  }
  var drop = CUNIMOB_RPG_CATEGORY_DROPS[index];
  return cuniitemGiveRaw(server, safeName, cunimobSpecialDropItemWithApothData(drop.item, drop.apoth), 'especial #' + (index + 1) + ' nivel ' + drop.min) ? 1 : 0;
}

function cuniitemGiveSampleFromSource(source, rawTier, rawItemRarity, rawLevel) {
  var server = source ? source.getServer() : null;
  var player = null;
  try { player = source.getPlayer(); } catch (ignored) { }
  if (!server || !player) {
    return 0;
  }
  var safeName = cunihordeSafePlayer(player.username);
  var selectors = [
    { kind: 'weapon', slot: '', role: '', family: '' },
    { kind: 'tool', slot: '', role: '', family: '' },
    { kind: 'armor', slot: '', role: '', family: '' }
  ];
  var tier = cuniitemTierByKey(rawTier);
  var count = 0;
  for (var i = 0; i < selectors.length; i++) {
    var entry = cunimobRandomChoice(cuniitemEntriesForSelector(tier, selectors[i]));
    if (!entry) {
      continue;
    }
    var itemText = cuniitemBuildFromEntry(entry, tier, selectors[i], rawLevel, rawItemRarity, 'minecraft:zombie', '');
    if (cuniitemGiveRaw(server, safeName, itemText, tier.label + ' / muestra ' + selectors[i].kind)) {
      count++;
    }
  }
  cuniitemFeedback(server, safeName, 'Muestra de loot entregada. Items: ' + count + '/3.', 'green');
  return count > 0 ? 1 : 0;
}

ServerEvents.commandRegistry(event => {
  var { commands, arguments: args } = event;
  var playerArg = () => commands.argument('jugador', args.STRING.create(event));

  event.register(
    commands.literal('cunihorde')
      .requires(source => source.hasPermission(2))
      .executes(ctx => {
        var server = ctx.getSource().getServer();
        cunihordeFeedback(server, 'Uso: cunihorde start <small|medium|advanced> <jugador> | stop | status | auto <on|off> | reload.', 'gold');
        return 1;
      })
      .then(commands.literal('start')
        .then(commands.literal('small')
          .then(playerArg()
            .executes(ctx => cunihordeSummon(ctx.getSource().getServer(), args.STRING.getResult(ctx, 'jugador'), 'small'))))
        .then(commands.literal('medium')
          .then(playerArg()
            .executes(ctx => cunihordeSummon(ctx.getSource().getServer(), args.STRING.getResult(ctx, 'jugador'), 'medium'))))
        .then(commands.literal('advanced')
          .then(playerArg()
            .executes(ctx => cunihordeSummon(ctx.getSource().getServer(), args.STRING.getResult(ctx, 'jugador'), 'advanced')))))
      .then(commands.literal('stop')
        .executes(ctx => {
          var server = ctx.getSource().getServer();
          server.runCommandSilent('kill @e[tag=cuniculum_horde]');
          cunihordeClearActive(server);
          cunihordeFeedback(server, 'Hordas activas limpiadas.', 'yellow');
          return 1;
        }))
      .then(commands.literal('status')
        .executes(ctx => {
          var server = ctx.getSource().getServer();
          cunihordeFeedback(server, `Auto=${cunihordeAutoEnabled(server) ? 'on' : 'off'}; activa=${cunihordeActive(server) ? 'si' : 'no'}; radio seguro=${CUNIHORDE_SAFE_RADIUS}; cooldown global=${Math.floor(CUNIHORDE_AUTO_COOLDOWN_MS / 60000)} min; scan natural=${Math.floor(CUNIMOB_NATURAL_SCAN_TICKS / 20)} s.`, 'gold');
          return 1;
        }))
      .then(commands.literal('reload')
        .executes(ctx => {
          var server = ctx.getSource().getServer();
          cunihordeClearActive(server);
          cunihordeFeedback(server, 'Estado temporal de hordas recargado. Para recargar scripts usa kubejs reload server-scripts.', 'gold');
          return 1;
        }))
      .then(commands.literal('auto')
        .then(commands.literal('on')
          .executes(ctx => {
            var server = ctx.getSource().getServer();
            cunihordeSetAuto(server, true);
            cunihordeFeedback(server, 'Hordas automaticas activadas con azar y cooldown conservador.', 'gold');
            return 1;
          }))
        .then(commands.literal('off')
          .executes(ctx => {
            var server = ctx.getSource().getServer();
            cunihordeSetAuto(server, false);
            cunihordeFeedback(server, 'Hordas automaticas desactivadas. Los comandos manuales siguen disponibles.', 'yellow');
            return 1;
          })))
  );

  event.register(
    commands.literal('cunimob')
      .then(commands.literal('status')
        .executes(ctx => {
          var source = ctx.getSource();
          var server = source.getServer();
          var player = null;
          try { player = source.getPlayer(); } catch (ignoredPlayer) { }
          if (!player) {
            try {
              if (CUNIMOB_COMPONENT_CLASS) {
                source.sendSystemMessage(CUNIMOB_COMPONENT_CLASS.literal('[CUNICULUM] /cunimob status debe ejecutarse como jugador.'));
              }
            } catch (ignoredConsoleStatus) { }
            return 0;
          }
          var dimension = cunimobDimensionFromLevel(player.level);
          var equipment = cunimobPlayerEquipmentScore(player);
          var progress = cunimobPlayerProgressScore(player);
          var sample = cunimobLevelForPlayer(player, player.level, dimension, 'natural', 0);
          var cap = cunimobPlayerLevelCap(player, dimension, 'natural', progress, equipment);
          var day = cunimobDay(player.level);
          var dayBonus = cunimobDayBonus(day);
          var dimensionBonus = cunimobDimensionBonus(dimension);
          var dimensionProfile = cunimobDimensionProfile(dimension);
          var minimum = cunimobDimensionMinimumLevel(dimension);
          var worldTier = cunimobEffectiveWorldTierForPlayer(player, dimension);
          var maxLoot = cunimobMaxLootTierForWorldTier(worldTier);
          var maxApoth = cunimobWorldTierProfileByKey(worldTier).maxApoth;
          var capText = cap >= CUNIMOB_NATURAL_MAX_LEVEL ? 'sin limite' : String(cap);
          var safeName = cunihordeSafePlayer(player.username);
          var lines = [
            { text: '[CUNICULUM] Estado de escalado de mobs', color: 'gold' },
            { text: 'Tu nivel estimado: ' + sample + ' | cap: ' + capText + ' | dimension: ' + dimensionProfile.label + ' (' + dimension + ')', color: 'yellow' },
            { text: 'Progreso: ' + progress + ' | equipo: ' + equipment + ' | dia: ' + day + ' (+' + dayBonus + ') | bonus dimension: +' + dimensionBonus, color: 'yellow' },
            { text: 'Multiplicadores dimension: vida mob x' + dimensionProfile.healthMultiplier + ' | dano mob x' + dimensionProfile.outgoingDamageMultiplier + ' | resistencia mob x' + (1 / dimensionProfile.incomingDamageMultiplier).toFixed(2), color: 'dark_aqua' },
            { text: 'World Tier: ' + cunimobWorldTierLabel(worldTier) + ' | botin max: ' + maxLoot.label + ' | rareza Apotheosis max: ' + maxApoth, color: 'aqua' },
            { text: 'Formula natural:', color: 'gold' },
            { text: 'base = 1 + floor(progreso*1.35) + floor(equipo*0.28) + bonusDia + bonusDimension + azar(0-3)', color: 'gray' },
            { text: 'nivel = min(cap, ceil(' + minimum + ' + (base-' + minimum + ')*' + CUNIMOB_LEVEL_MULTIPLIER + '))', color: 'gray' },
            { text: 'Hordas usan progreso*1.75, equipo*0.42 y azar(0-6). Nether inicia en nv 4; End inicia en nv 8.', color: 'dark_aqua' },
            { text: 'Rarezas base: Comun 86.8%, Incomun 10.4%, Raro 2.4%, Epico 0.26%, Legendario 0.05%, Mitico 0.007%. Suben levemente con nivel alto.', color: 'green' },
            { text: 'Categorias: Normal; Elite desde complejidad 18; Lider desde 35. Jefes vanilla/mod siempre son Lider.', color: 'light_purple' },
            { text: 'Defensa extra desde nivel ' + CUNIMOB_ARMOR_GATE_LEVEL + '. Radio de lectura de jugadores: ' + CUNIMOB_PLAYER_SCALING_RADIUS + ' bloques.', color: 'gold' }
          ];
          for (var lineIndex = 0; lineIndex < lines.length; lineIndex++) {
            server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson(lines[lineIndex].text, lines[lineIndex].color));
          }
          return 1;
        }))
      .then(commands.literal('spawn')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('mob', args.STRING.create(event))
          .then(commands.argument('nivel', args.STRING.create(event))
            .executes(ctx => cunimobSpawnManualFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'mob'), args.STRING.getResult(ctx, 'nivel'), 'common', CUNIMOB_CATEGORY_NORMAL)))))
      .then(commands.literal('spawnrarity')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('mob', args.STRING.create(event))
          .then(commands.argument('nivel', args.STRING.create(event))
            .then(commands.argument('rareza', args.STRING.create(event))
              .executes(ctx => cunimobSpawnManualFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'mob'), args.STRING.getResult(ctx, 'nivel'), args.STRING.getResult(ctx, 'rareza'), CUNIMOB_CATEGORY_NORMAL))))))
      .then(commands.literal('elite')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('mob', args.STRING.create(event))
          .then(commands.argument('nivel', args.STRING.create(event))
            .executes(ctx => cunimobSpawnManualFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'mob'), args.STRING.getResult(ctx, 'nivel'), 'rare', CUNIMOB_CATEGORY_ELITE)))))
      .then(commands.literal('boss')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('mob', args.STRING.create(event))
          .then(commands.argument('nivel', args.STRING.create(event))
            .executes(ctx => cunimobSpawnManualFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'mob'), args.STRING.getResult(ctx, 'nivel'), 'mythic', CUNIMOB_CATEGORY_BOSS)))))
      .then(commands.literal('spawnfull')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('mob', args.STRING.create(event))
          .then(commands.argument('nivel', args.STRING.create(event))
            .then(commands.argument('rareza', args.STRING.create(event))
              .then(commands.argument('categoria', args.STRING.create(event))
                .executes(ctx => cunimobSpawnManualFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'mob'), args.STRING.getResult(ctx, 'nivel'), args.STRING.getResult(ctx, 'rareza'), args.STRING.getResult(ctx, 'categoria'))))))))
      .then(commands.literal('refresh')
        .requires(source => source.hasPermission(2))
        .executes(ctx => {
          var source = ctx.getSource();
          var server = source.getServer();
          var player = source.getPlayer();
          var safeName = cunihordeSafePlayer(player.username);
          for (var i = 0; i < CUNIMOB_NATURAL_TYPES.length; i++) {
            var mobId = CUNIMOB_NATURAL_TYPES[i].id;
            if (!cunimobIsVisualTarget(mobId) || mobId.indexOf('#') === 0 || cunimobIsBossMob(mobId)) {
              continue;
            }
            var scanRadius = cunimobScanRadiusForMob(mobId);
            var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + ']';
            server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_LEVEL_TAG);
            server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_GEAR_TAG);
            for (var level = 1; level <= 512; level++) {
              server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s remove cuniculum_level_' + level);
            }
          }
          cunimobApplyNaturalNearPlayer(server, player, player.level);
          server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Mobs cercanos recalculados con tu progreso/equipo actual.', 'gold'));
          return 1;
        }))
      .then(commands.literal('progress')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('valor', args.STRING.create(event))
          .executes(ctx => {
            var source = ctx.getSource();
            var server = source.getServer();
            var player = source.getPlayer();
            var safeName = cunihordeSafePlayer(player.username);
            var rawValue = args.STRING.getResult(ctx, 'valor');
            var value = Math.max(0, Math.floor(cunimobSafeNumber(rawValue || 0, 0)));
            try {
              player.persistentData.cuniculum_progress_score = value;
              player.persistentData.cuniculum_progress_manual = true;
            } catch (ignored) {
            }
            server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Progreso manual de mobs fijado en ' + value + '. Usa /cunimob resetprogress para volver al calculo natural.', 'gold'));
            return 1;
          })))
      .then(commands.literal('resetprogress')
        .requires(source => source.hasPermission(2))
        .executes(ctx => {
          var source = ctx.getSource();
          var server = source.getServer();
          var player = source.getPlayer();
          var safeName = cunihordeSafePlayer(player.username);
          try {
            player.persistentData.cuniculum_progress_score = 0;
            player.persistentData.cuniculum_progress_manual = false;
          } catch (ignored) {
          }
          server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Progreso manual de mobs reiniciado.', 'yellow'));
          return 1;
        }))
      .then(commands.literal('force')
        .requires(source => source.hasPermission(2))
        .then(commands.argument('nivel', args.STRING.create(event))
          .executes(ctx => {
            var source = ctx.getSource();
            var server = source.getServer();
            var player = source.getPlayer();
            var safeName = cunihordeSafePlayer(player.username);
            var rawLevel = args.STRING.getResult(ctx, 'nivel');
            var forcedLevel = Math.max(1, Math.floor(Number(rawLevel || 1)));
            var changed = 0;
            for (var i = 0; i < CUNIMOB_NATURAL_TYPES.length; i++) {
              var mobId = CUNIMOB_NATURAL_TYPES[i].id;
              if (!cunimobIsVisualTarget(mobId) || mobId.indexOf('#') === 0 || cunimobIsBossMob(mobId)) {
                continue;
              }
              var scanRadius = cunimobScanRadiusForMob(mobId);
              var scanLimit = cunimobScanLimitForMob(mobId);
              var selector = '@e[type=' + mobId + ',distance=..' + scanRadius + ',limit=' + scanLimit + ',sort=nearest]';
              var rarity = cunimobRollRarityProfile(forcedLevel, mobId, 'natural');
              var category = cunimobRollCategory(forcedLevel, mobId, 'natural', rarity);
              rarity = cunimobBossMinimumRarity(mobId, rarity, category);
              server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_LEVEL_TAG);
              server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s remove ' + CUNIMOB_GEAR_TAG);
              server.runCommandSilent('execute at ' + safeName + ' as ' + selector + ' run tag @s add ' + CUNIMOB_SCAN_TAG);
              server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s add ' + CUNIMOB_LEVEL_TAG);
              server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s add cuniculum_level_' + forcedLevel);
              var rarityPositioned = 'execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest]';
              cunimobClearRarityTags(server, rarityPositioned);
              server.runCommandSilent(rarityPositioned + ' run tag @s add ' + CUNIMOB_RARITY_TAG_PREFIX + rarity.key);
              cunimobClearCategoryTags(server, rarityPositioned);
              server.runCommandSilent(rarityPositioned + ' run tag @s add ' + CUNIMOB_CATEGORY_TAG_PREFIX + category);
              server.runCommandSilent(rarityPositioned + ' run data merge entity @s {CustomName:\'' + cunimobLevelNameJson(forcedLevel, mobId, 'natural', rarity, category, cunimobDimensionFromLevel(player.level)) + '\',CustomNameVisible:0b}');
              cunimobApplyEquipmentAndTraitsNearPlayer(server, safeName, mobId, forcedLevel, scanRadius, CUNIMOB_SCAN_TAG, rarity, category, cunimobDimensionFromLevel(player.level));
              server.runCommandSilent('execute at ' + safeName + ' as @e[type=' + mobId + ',distance=..' + scanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=' + scanLimit + ',sort=nearest] run tag @s remove ' + CUNIMOB_SCAN_TAG);
              changed++;
            }
            server.runCommandSilent('tellraw ' + safeName + ' ' + cunihordeJson('[CUNICULUM] Forzado nivel ' + forcedLevel + ' en tipos cercanos procesados: ' + changed + '.', 'gold'));
            return 1;
          })))
  );

  event.register(
    commands.literal('cuniitem')
      .requires(source => source.hasPermission(2))
      .executes(ctx => {
        var source = ctx.getSource();
        var server = source.getServer();
        var player = source.getPlayer();
        cuniitemFeedback(server, player.username, 'Uso: /cuniitem give|set|mining|special|sample|list. Revisa COMANDOS_ITEMS_MOBS_CUNICULUM.md para la matriz completa.', 'gold');
        return 1;
      })
      .then(commands.literal('list')
        .executes(ctx => {
          var source = ctx.getSource();
          var server = source.getServer();
          var player = source.getPlayer();
          var safeName = cunihordeSafePlayer(player.username);
          var lines = [
            'Tiers: madriguera, guardia, explorador, vigia, juramento, mitico.',
            'Tipos: arma, armadura, herramienta, casco, pechera, pantalones, botas, pico, hacha, pala, azada, arco, ballesta, daga, lanza, baston, martillo.',
            'Rareza item: common/comun, uncommon/incomun, rare/raro, epic/epico, mythic/mitico.',
            'Mobdrop: /cuniitem mobdrop <tier> <tipo> <rareza_item> <nivel> <mob> para probar encantamiento segun criatura.',
            'Mobs: /cunimob spawnfull Zombie 80 legendario jefe | /cunimob elite Skeleton 50 | /cunimob boss Zombie 120.',
            'Especiales indexados: usa /cuniitem special <numero>; el .md contiene todos los indices.'
          ];
          for (var i = 0; i < lines.length; i++) {
            cuniitemFeedback(server, safeName, lines[i], i === 0 ? 'gold' : 'yellow');
          }
          return 1;
        }))
      .then(commands.literal('give')
        .then(commands.argument('tier', args.STRING.create(event))
          .then(commands.argument('tipo', args.STRING.create(event))
            .then(commands.argument('rareza_item', args.STRING.create(event))
              .then(commands.argument('nivel', args.STRING.create(event))
                .executes(ctx => cuniitemGiveFromSource(
                  ctx.getSource(),
                  args.STRING.getResult(ctx, 'tier'),
                  args.STRING.getResult(ctx, 'tipo'),
                  args.STRING.getResult(ctx, 'rareza_item'),
                  args.STRING.getResult(ctx, 'nivel'),
                  'zombie'
                )))))))
      .then(commands.literal('mobdrop')
        .then(commands.argument('tier', args.STRING.create(event))
          .then(commands.argument('tipo', args.STRING.create(event))
            .then(commands.argument('rareza_item', args.STRING.create(event))
              .then(commands.argument('nivel', args.STRING.create(event))
                .then(commands.argument('mob', args.STRING.create(event))
                  .executes(ctx => cuniitemGiveFromSource(
                    ctx.getSource(),
                    args.STRING.getResult(ctx, 'tier'),
                    args.STRING.getResult(ctx, 'tipo'),
                    args.STRING.getResult(ctx, 'rareza_item'),
                    args.STRING.getResult(ctx, 'nivel'),
                    args.STRING.getResult(ctx, 'mob')
                  ))))))))
      .then(commands.literal('set')
        .then(commands.argument('tier', args.STRING.create(event))
          .then(commands.argument('rareza_item', args.STRING.create(event))
            .then(commands.argument('nivel', args.STRING.create(event))
              .executes(ctx => cuniitemGiveSetFromSource(
                ctx.getSource(),
                args.STRING.getResult(ctx, 'tier'),
                args.STRING.getResult(ctx, 'rareza_item'),
                args.STRING.getResult(ctx, 'nivel')
              ))))))
      .then(commands.literal('mining')
        .then(commands.argument('tier', args.STRING.create(event))
          .then(commands.argument('rareza_item', args.STRING.create(event))
            .then(commands.argument('forma', args.STRING.create(event))
              .then(commands.argument('nivel', args.STRING.create(event))
                .executes(ctx => cuniitemGiveMiningFromSource(
                  ctx.getSource(),
                  args.STRING.getResult(ctx, 'tier'),
                  args.STRING.getResult(ctx, 'rareza_item'),
                  args.STRING.getResult(ctx, 'forma'),
                  args.STRING.getResult(ctx, 'nivel')
                )))))))
      .then(commands.literal('special')
        .then(commands.argument('indice', args.STRING.create(event))
          .executes(ctx => cuniitemGiveSpecialFromSource(ctx.getSource(), args.STRING.getResult(ctx, 'indice')))))
      .then(commands.literal('sample')
        .then(commands.argument('tier', args.STRING.create(event))
          .then(commands.argument('rareza_item', args.STRING.create(event))
            .then(commands.argument('nivel', args.STRING.create(event))
              .executes(ctx => cuniitemGiveSampleFromSource(
                ctx.getSource(),
                args.STRING.getResult(ctx, 'tier'),
                args.STRING.getResult(ctx, 'rareza_item'),
                args.STRING.getResult(ctx, 'nivel')
              ))))))
  );
});

EntityEvents.drops(event => {
  var entity = event.entity;
  if (!entity) {
    return;
  }

  if (cunimobEntityHasTag(entity, CUNIMOB_ELITE_MINION_TAG)) {
    try { event.cancel(); } catch (ignoredMinionDropsCancel) { }
    return;
  }

  var mobId = cunimobEntityTypeId(entity);
  if (!cunimobIsVisualTarget(mobId)) {
    return;
  }
  if (cunimobIsPassivePeacefulMob(mobId)) {
    return;
  }
  if (mobId === 'minecraft:iron_golem') {
    return;
  }
  if (cunimobEntityHasTag(entity, CUNIMOB_NO_RPG_REWARD_TAG) || cunimobEntityHasTag(entity, CUNIMOB_SPAWNER_MOB_TAG)) {
    return;
  }

  try {
    if (entity.persistentData[CUNIMOB_REWARD_DROP_DONE_KEY]) {
      return;
    }
    entity.persistentData[CUNIMOB_REWARD_DROP_DONE_KEY] = true;
  } catch (ignored) {
  }

  var level = cunimobLevelFromEntity(entity);
  var rarity = cunimobRarityProfileFromEntity(entity);
  var category = cunimobCategoryFromEntity(entity);
  rarity = cunimobBossMinimumRarity(mobId, rarity, category);
  var dropWorldTier = cunimobDropWorldTierFromEntity(entity);
  var killer = cunimobDropKiller(event, entity);
  var playerClass = cunimobPlayerClassAffinity(killer);
  cunimobDropCoins(event, mobId, level, rarity, category);
  cunimobDropRpgRewards(event, mobId, level, rarity, category, dropWorldTier, playerClass);
  cunimobSpawnDeathPoison(event, entity, mobId, level, rarity, category);
});

EntityEvents.beforeHurt(function (event) {
  var entity = event.entity;
  if (!entity) {
    return;
  }

  if (!cunimobIsPlayerEntity(entity) && cunimobIsFallDamage(event)) {
    try { event.cancel(); } catch (ignoredFallCancel) { }
    return;
  }

  var dimension = cunimobDimensionFromEvent(event, entity);
  if (!cunimobIsCombatDimension(dimension)) {
    return;
  }

  if (!cunimobIsPlayerEntity(entity)) {
    var fireMobId = cunimobEntityTypeId(entity);
    if (cunimobIsVisualTarget(fireMobId) && cunimobShouldIgnoreFireDamage(fireMobId, dimension) && cunimobIsFireDamage(event)) {
      try { event.cancel(); } catch (ignoredFireCancel) { }
      return;
    }
  }

  if (cunimobIsPlayerEntity(entity)) {
    var sourceMob = cunimobDamageSourceEntity(event);
    var sourceMobId = cunimobEntityTypeId(sourceMob);
    if (!sourceMob || !cunimobIsVisualTarget(sourceMobId)) {
      return;
    }
    var sourceLevel = cunimobEnsureMobLeveledForPlayerHit(event, sourceMob, entity, dimension, sourceMobId);
    var sourceServer = cunimobServerFromEvent(event, entity, sourceMob);
    cunimobRememberDropWorldTier(sourceMob, entity, dimension);
    cunimobMarkCombatEntity(sourceServer, sourceMob);
    cunimobTryBreakObstruction(sourceServer, sourceMob, entity, dimension, sourceMobId, sourceLevel);
    cunimobBoostCreeperExplosionDamage(event, entity, sourceMobId, sourceLevel);
    cunimobApplyDimensionMobDamage(event, dimension, sourceLevel);
    cunimobIncreaseDamageWithoutArmor(event, entity, sourceMob, sourceMobId, sourceLevel);
    cunimobUseEliteHitSkills(event, entity, sourceMob, sourceMobId, sourceLevel, dimension);
    return;
  }

  var mobId = cunimobEntityTypeId(entity);
  if (!cunimobIsVisualTarget(mobId)) {
    return;
  }
  if (cunimobIsPassivePeacefulMob(mobId)) {
    return;
  }

  var attacker = cunimobDamageAttacker(event);
  if (!cunimobIsPlayerEntity(attacker)) {
    return;
  }

  var level = cunimobEnsureLeveledFromAttacker(event, entity, attacker, dimension, mobId);
  var combatServer = cunimobServerFromEvent(event, entity, attacker);
  cunimobMarkCombatEntity(combatServer, entity);
  cunimobTryBreakObstruction(combatServer, entity, attacker, dimension, mobId, level);
  cunimobRetargetLastPlayerHit(entity, attacker);
  cunimobRememberDropWorldTier(entity, attacker, dimension);
  var hitRarity = cunimobRarityProfileFromEntity(entity);
  if (cunimobTryBlockIncomingAttack(event, entity, attacker, mobId, level, hitRarity)) {
    return;
  }
  cunimobReduceDamageWithoutEnchant(event, entity, attacker, mobId, level);
  cunimobApplyElementalWeaknessDamage(event, entity, attacker, mobId, level);
  cunimobApplyDimensionMobResistance(event, dimension, level);
  cunimobTryBleedMob(combatServer, entity, dimension, mobId, level, hitRarity);
  cunimobTryBreakMobEquipment(combatServer, entity, dimension, mobId, level, hitRarity);
  cunimobUseEliteCombatSkills(event, entity, attacker, mobId, level, dimension);
});

EntityEvents.checkSpawn(event => {
  var entity = event.entity;
  if (!entity) {
    return;
  }

  var dimension = cunimobDimensionFromEvent(event, entity);
  if (!cunimobIsCombatDimension(dimension)) {
    return;
  }

  var mobId = cunimobEntityTypeId(entity);
  if (!cunimobIsVisualTarget(mobId)) {
    return;
  }
  if (cunimobIsPassivePeacefulMob(mobId)) {
    return;
  }
  if (!cunimobEntityHasTag(entity, CUNIMOB_MANUAL_SPAWN_TAG)
    && !cunimobEntityHasTag(entity, CUNIMOB_ELITE_MINION_TAG)
    && cunimobIsNaturalSpawnReason(event)
    && !cunimobDimensionAllowsNaturalSpawn(mobId, dimension)) {
    try { event.cancel(); } catch (ignoredDimensionCancel) { }
    return;
  }
  if (cunimobIsSpawnerSpawn(event) && Math.random() < 0.50) {
    try { event.cancel(); } catch (ignored) { }
  }
});

EntityEvents.spawned(event => {
  var entity = event.entity;
  if (!entity) {
    return;
  }

  var dimension = cunimobDimensionFromEvent(event, entity);
  if (!cunimobIsCombatDimension(dimension)) {
    return;
  }

  var mobId = cunimobEntityTypeId(entity);
  if (!cunimobIsVisualTarget(mobId)) {
    return;
  }
  if (cunimobIsPassivePeacefulMob(mobId)) {
    return;
  }
  if (cunimobIsSpawnerSpawn(event)) {
    var sx = Math.round(Number(entity.x) * 100) / 100;
    var sy = Math.round(Number(entity.y) * 100) / 100;
    var sz = Math.round(Number(entity.z) * 100) / 100;
    var spawnServer = cunimobServerFromEvent(event, entity, null);
    cunimobMarkSpawnerMob(spawnServer, entity, dimension, mobId, sx, sy, sz);
  }
  if (cunimobEntityHasTag(entity, CUNIMOB_MANUAL_SPAWN_TAG)) {
    return;
  }

  var server = null;
  try { server = event.server; } catch (ignored) { }
  try { if (!server) { server = entity.server; } } catch (ignored) { }
  if (!server) {
    return;
  }

  var x = Math.round(Number(entity.x) * 100) / 100;
  var y = Math.round(Number(entity.y) * 100) / 100;
  var z = Math.round(Number(entity.z) * 100) / 100;
  var nearestPlayer = cunimobNearestPlayer(server, dimension, x, y, z, CUNIMOB_PLAYER_SCALING_RADIUS);
  var levelObj = event.level || (nearestPlayer ? nearestPlayer.level : entity.level);
  var mobBonus = cunimobLevelBonusForMob(mobId);
  var level = nearestPlayer
    ? cunimobLevelForPlayer(nearestPlayer, levelObj, dimension, 'natural', mobBonus)
    : cunimobWorldLevelFor(levelObj, dimension, 'natural', mobBonus);
  level = cunimobAdjustLevelForMob(mobId, level);
  var spawnScanRadius = mobId === 'minecraft:blaze' ? 8 : 4;
  try { entity.addTag(CUNIMOB_SCAN_TAG); } catch (ignored) { }
  server.runCommandSilent('execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as @e[type=' + mobId + ',distance=..' + spawnScanRadius + ',tag=!' + CUNIMOB_LEVEL_TAG + ',limit=1,sort=nearest] run tag @s add ' + CUNIMOB_SCAN_TAG);
  server.scheduleInTicks(4, () => {
    cunimobApplyVisualNameAt(server, dimension, x, y, z, mobId, level, 'natural', spawnScanRadius, CUNIMOB_SCAN_TAG);
    server.runCommandSilent('execute in ' + dimension + ' positioned ' + x + ' ' + y + ' ' + z + ' as @e[type=' + mobId + ',distance=..' + spawnScanRadius + ',tag=' + CUNIMOB_SCAN_TAG + ',limit=1,sort=nearest] run tag @s remove ' + CUNIMOB_SCAN_TAG);
  });
});

function cunimobStackHasLootKey(stack, key) {
  var text = cunimobStackText(stack);
  if (!text || !key) {
    return false;
  }
  var safeKey = String(key).toLowerCase();
  return text.indexOf('cuniculum_set:"' + safeKey + '"') >= 0
    || text.indexOf('cuniculum_set:' + safeKey) >= 0
    || text.indexOf('cuniculum_tier:"' + safeKey + '"') >= 0
    || text.indexOf(safeKey) >= 0;
}

function cunimobPlayerFullLootSet(player) {
  var armorSlots = [
    ['headArmorItem', 'getHeadArmorItem', 'helmetItem'],
    ['chestArmorItem', 'getChestArmorItem', 'chestplateItem'],
    ['legsArmorItem', 'getLegsArmorItem', 'leggingsItem'],
    ['feetArmorItem', 'getFeetArmorItem', 'bootsItem']
  ];

  for (var i = CUNIMOB_RPG_LOOT_TIERS.length - 1; i >= 0; i--) {
    var tier = CUNIMOB_RPG_LOOT_TIERS[i];
    var matches = true;
    for (var slot = 0; slot < armorSlots.length; slot++) {
      var stack = cunimobReadStack(player, armorSlots[slot]);
      if (!cunimobStackHasLootKey(stack, tier.key)) {
        matches = false;
        break;
      }
    }
    if (matches) {
      return tier;
    }
  }

  return null;
}

function cunimobLootSetSummary(player) {
  var armorSlots = [
    ['headArmorItem', 'getHeadArmorItem', 'helmetItem'],
    ['chestArmorItem', 'getChestArmorItem', 'chestplateItem'],
    ['legsArmorItem', 'getLegsArmorItem', 'leggingsItem'],
    ['feetArmorItem', 'getFeetArmorItem', 'bootsItem']
  ];
  var counts = {};
  var totalPieces = 0;

  for (var slot = 0; slot < armorSlots.length; slot++) {
    var stack = cunimobReadStack(player, armorSlots[slot]);
    if (!stack) {
      continue;
    }
    for (var i = CUNIMOB_RPG_LOOT_TIERS.length - 1; i >= 0; i--) {
      var tier = CUNIMOB_RPG_LOOT_TIERS[i];
      if (cunimobStackHasLootKey(stack, tier.key)) {
        counts[tier.key] = (counts[tier.key] || 0) + 1;
        totalPieces++;
        break;
      }
    }
  }

  var bestTier = null;
  var bestCount = 0;
  for (var j = CUNIMOB_RPG_LOOT_TIERS.length - 1; j >= 0; j--) {
    var candidate = CUNIMOB_RPG_LOOT_TIERS[j];
    var count = counts[candidate.key] || 0;
    if (count > bestCount || (count === bestCount && count > 0 && !bestTier)) {
      bestTier = candidate;
      bestCount = count;
    }
  }

  return {
    pieces: totalPieces,
    bestTier: bestTier,
    bestCount: bestCount
  };
}

function cunimobGivePlayerEffect(server, playerName, effectId, seconds, amp) {
  var safeName = cunihordeSafePlayer(playerName);
  if (!server || !safeName || !effectId) {
    return;
  }
  server.runCommandSilent('effect give ' + safeName + ' ' + effectId + ' ' + Math.max(1, Math.floor(seconds || 8)) + ' ' + Math.max(0, Math.floor(amp || 0)) + ' true');
}

function cunimobTextHasTrait(text, trait) {
  var value = String(text || '').toLowerCase();
  var key = String(trait || '').toLowerCase();
  return key && (value.indexOf('cuniculum_trait:"' + key + '"') >= 0
    || value.indexOf('cuniculum_trait:' + key) >= 0
    || value.indexOf('cuniculum_trait2:"' + key + '"') >= 0
    || value.indexOf('cuniculum_trait2:' + key) >= 0
    || value.indexOf('cuniculum_trait3:"' + key + '"') >= 0
    || value.indexOf('cuniculum_trait3:' + key) >= 0);
}

function cunimobTraitPowerFromText(text, fallback) {
  var value = String(text || '');
  var match = value.match(/cuniculum_trait_power:(\d+)/);
  if (match && match[1]) {
    return Math.max(1, Math.min(5, Number(match[1]) || 1));
  }
  return Math.max(1, Math.min(5, Number(fallback || 1)));
}

function cunimobApplyTraitEffectsFromText(server, safeName, text, itemPowerIndex) {
  if (!server || !safeName || !text) {
    return;
  }
  var traitPower = cunimobTraitPowerFromText(text, Math.max(1, itemPowerIndex || 1));
  var lowAmp = traitPower >= 4 ? 1 : 0;
  var highAmp = traitPower >= 5 ? 2 : (traitPower >= 3 ? 1 : 0);

  if (cunimobTextHasTrait(text, 'tunelero')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 7, highAmp);
  }
  if (cunimobTextHasTrait(text, 'prospero')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'vigia')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
  }
  if (cunimobTextHasTrait(text, 'ligero')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, highAmp);
  }
  if (cunimobTextHasTrait(text, 'baluarte')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'sanguino')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:regeneration', 7, traitPower >= 5 ? 1 : 0);
  }
  if (cunimobTextHasTrait(text, 'arcano')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:fire_resistance', 7, 0);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:regeneration', 5, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'devastador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'cosechador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, lowAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:saturation', 3, 0);
  }
  if (cunimobTextHasTrait(text, 'salto')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:jump_boost', 7, highAmp);
  }
  if (cunimobTextHasTrait(text, 'quebrantador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, traitPower >= 5 ? 2 : 1);
  }
  if (cunimobTextHasTrait(text, 'ojo_halcon')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'estable')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, 0);
  }
  if (cunimobTextHasTrait(text, 'excavador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, lowAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'lenador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 7, lowAmp);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'pescador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:water_breathing', 8, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:dolphins_grace', 5, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'prismal')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, lowAmp);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:fire_resistance', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'eco_pradera')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:health_boost', 8, lowAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:saturation', 3, 0);
  }
  if (cunimobTextHasTrait(text, 'bruma')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, highAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:jump_boost', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'cazador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, lowAmp);
    if (traitPower >= 5) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'respirador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:water_breathing', 9, 0);
    if (traitPower >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'termico')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, lowAmp);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:fire_resistance', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'ignifugo')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:fire_resistance', 8, 0);
    if (traitPower >= 5) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'pluma')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:slow_falling', 5, 0);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:jump_boost', 7, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'nadador')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:dolphins_grace', 5, lowAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:water_breathing', 8, 0);
  }
  if (cunimobTextHasTrait(text, 'zancada')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, highAmp);
  }
  if (cunimobTextHasTrait(text, 'centinela')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, lowAmp);
  }
  if (cunimobTextHasTrait(text, 'marea')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:water_breathing', 9, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:dolphins_grace', 6, highAmp);
  }
  if (cunimobTextHasTrait(text, 'escarcha')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, lowAmp);
    if (traitPower >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:slow_falling', 5, 0);
    }
  }
  if (cunimobTextHasTrait(text, 'aereo')) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:slow_falling', 5, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, lowAmp);
  }
}

function cunimobHeldTierFromText(text) {
  var value = String(text || '').toLowerCase();
  for (var i = CUNIMOB_RPG_LOOT_TIERS.length - 1; i >= 0; i--) {
    var key = CUNIMOB_RPG_LOOT_TIERS[i].key;
    if (value.indexOf('cuniculum_tier:"' + key + '"') >= 0
      || value.indexOf('cuniculum_tier:' + key) >= 0
      || value.indexOf('cuniculum_set:"' + key + '"') >= 0
      || value.indexOf(key) >= 0) {
      return CUNIMOB_RPG_LOOT_TIERS[i];
    }
  }
  return null;
}

function cunimobTierPowerIndex(tier) {
  if (!tier) {
    return 0;
  }
  for (var i = 0; i < CUNIMOB_RPG_LOOT_TIERS.length; i++) {
    if (CUNIMOB_RPG_LOOT_TIERS[i].key === tier.key) {
      return i;
    }
  }
  return 0;
}

function cunimobTextHasAny(text, values) {
  var value = String(text || '').toLowerCase();
  for (var i = 0; i < values.length; i++) {
    if (value.indexOf(String(values[i]).toLowerCase()) >= 0) {
      return true;
    }
  }
  return false;
}

function cunimobEquippedArmorTexts(player) {
  var armorSlots = [
    ['headArmorItem', 'getHeadArmorItem', 'helmetItem'],
    ['chestArmorItem', 'getChestArmorItem', 'chestplateItem'],
    ['legsArmorItem', 'getLegsArmorItem', 'leggingsItem'],
    ['feetArmorItem', 'getFeetArmorItem', 'bootsItem']
  ];
  var parts = [];
  for (var slot = 0; slot < armorSlots.length; slot++) {
    var stack = cunimobReadStack(player, armorSlots[slot]);
    var text = cunimobStackText(stack);
    if (text) {
      parts.push(text);
    }
  }
  return parts;
}

function cunimobEquippedArmorText(player) {
  var parts = cunimobEquippedArmorTexts(player);
  return parts.join(' ');
}

function cunimobArmorPieceCountMatching(player, values) {
  var pieces = cunimobEquippedArmorTexts(player);
  var count = 0;
  for (var i = 0; i < pieces.length; i++) {
    if (cunimobTextHasAny(pieces[i], values)) {
      count++;
    }
  }
  return count;
}

function cunimobApplySetEffectPlan(server, safeName, effectPlan, power) {
  if (!effectPlan) {
    return;
  }
  for (var i = 0; i < effectPlan.length; i++) {
    var entry = effectPlan[i];
    if (!entry || !entry.effect) {
      continue;
    }
    var amp = Math.max(0, Math.floor(Number(entry.amp || 0)));
    if (entry.powerAmp) {
      amp += Math.max(0, Math.floor(Number(power || 0) / Number(entry.powerAmp || 10)));
    }
    var maxAmp = entry.maxAmp === 0 || entry.maxAmp ? entry.maxAmp : 3;
    amp = Math.min(Math.max(0, Math.floor(Number(maxAmp))), amp);
    cunimobGivePlayerEffect(server, safeName, entry.effect, entry.seconds || 7, amp);
  }
}

function cunimobApplyClassSetBonuses(server, safeName, player, armorPower) {
  var rules = [
    {
      match: ['archers:', 'archers_expansion:', 'ranger', 'bowman'],
      thresholds: [
        { pieces: 2, effects: [{ effect: 'minecraft:speed', seconds: 7, amp: 0, powerAmp: 5, maxAmp: 1 }, { effect: 'minecraft:night_vision', seconds: 12, amp: 0, maxAmp: 0 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:luck', seconds: 7, amp: 0, powerAmp: 4, maxAmp: 1 }, { effect: 'minecraft:strength', seconds: 7, amp: 0, maxAmp: 0 }] }
      ]
    },
    {
      match: ['rogues:', 'rogues_rpg:', 'assassin', 'picaro'],
      thresholds: [
        { pieces: 1, effects: [{ effect: 'minecraft:speed', seconds: 7, amp: 0, maxAmp: 0 }] },
        { pieces: 2, effects: [{ effect: 'minecraft:jump_boost', seconds: 7, amp: 0, maxAmp: 0 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:speed', seconds: 7, amp: 0, powerAmp: 4, maxAmp: 2 }, { effect: 'minecraft:strength', seconds: 7, amp: 0, powerAmp: 5, maxAmp: 1 }] }
      ]
    },
    {
      match: ['paladins:', 'paladins_and_priests:', 'priests:', 'cleric', 'paladin'],
      thresholds: [
        { pieces: 3, effects: [{ effect: 'minecraft:resistance', seconds: 7, amp: 0, powerAmp: 5, maxAmp: 1 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:fire_resistance', seconds: 8, amp: 0, maxAmp: 0 }, { effect: 'minecraft:absorption', seconds: 7, amp: 0, powerAmp: 5, maxAmp: 1 }] }
      ]
    },
    {
      match: ['wizards:', 'elemental_wizards_rpg:', 'druid', 'druids:', 'spellblades:', 'arcane'],
      thresholds: [
        { pieces: 1, effects: [{ effect: 'minecraft:regeneration', seconds: 5, amp: 0, maxAmp: 0 }] },
        { pieces: 3, effects: [{ effect: 'minecraft:fire_resistance', seconds: 7, amp: 0, maxAmp: 0 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:resistance', seconds: 7, amp: 0, maxAmp: 0 }, { effect: 'minecraft:regeneration', seconds: 5, amp: 0, powerAmp: 6, maxAmp: 1 }] }
      ]
    },
    {
      match: ['bards_rpg:', 'bard', 'musico'],
      thresholds: [
        { pieces: 2, effects: [{ effect: 'minecraft:luck', seconds: 7, amp: 0, powerAmp: 4, maxAmp: 2 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:saturation', seconds: 3, amp: 0, maxAmp: 0 }, { effect: 'minecraft:regeneration', seconds: 5, amp: 0, maxAmp: 0 }] }
      ]
    },
    {
      match: ['berserker_rpg:', 'forcemaster_rpg:', 'warrior', 'berserker'],
      thresholds: [
        { pieces: 2, effects: [{ effect: 'minecraft:strength', seconds: 7, amp: 0, powerAmp: 4, maxAmp: 2 }] },
        { pieces: 3, effects: [{ effect: 'minecraft:speed', seconds: 7, amp: 0, maxAmp: 0 }] },
        { pieces: 4, effects: [{ effect: 'minecraft:resistance', seconds: 7, amp: 0, powerAmp: 5, maxAmp: 1 }] }
      ]
    }
  ];

  for (var ruleIndex = 0; ruleIndex < rules.length; ruleIndex++) {
    var rule = rules[ruleIndex];
    var pieces = cunimobArmorPieceCountMatching(player, rule.match);
    if (pieces <= 0) {
      continue;
    }
    for (var thresholdIndex = 0; thresholdIndex < rule.thresholds.length; thresholdIndex++) {
      var threshold = rule.thresholds[thresholdIndex];
      if (pieces >= threshold.pieces) {
        cunimobApplySetEffectPlan(server, safeName, threshold.effects, armorPower);
      }
    }
  }
}

function cunimobApplyLootSetBonuses(server, player) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!server || !player || !safeName) {
    return;
  }

  var summary = cunimobLootSetSummary(player);
  if (summary.pieces > 0) {
    var healthAmp = Math.max(0, Math.min(3, summary.pieces - 1));
    if (summary.bestCount >= 4) {
      healthAmp = Math.min(5, healthAmp + 1 + Math.floor(cunimobTierPowerIndex(summary.bestTier) / 3));
    }
    cunimobGivePlayerEffect(server, safeName, 'minecraft:health_boost', CUNIMOB_SET_HEALTH_BOOST_SECONDS, healthAmp);
    if (summary.bestCount >= 2) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, Math.min(1, Math.floor(cunimobTierPowerIndex(summary.bestTier) / 4)));
    }
    if (summary.bestCount >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:saturation', 3, 0);
    }
  }

  var armorText = cunimobEquippedArmorText(player);
  if (armorText) {
    var armorPower = Math.max(cunimobTierPowerIndex(summary.bestTier), cunimobItemQualityIndexFromText(armorText));
    cunimobApplyTraitEffectsFromText(server, safeName, armorText, armorPower);
    cunimobApplyClassSetBonuses(server, safeName, player, armorPower);
  }

  var tier = cunimobPlayerFullLootSet(player);
  if (!tier) {
    return;
  }

  if (tier.key === 'madriguera') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 8, 0);
  } else if (tier.key === 'guardia') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 8, 0);
  } else if (tier.key === 'explorador') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 8, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
  } else if (tier.key === 'vigia') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 8, 1);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 8, 0);
  } else if (tier.key === 'juramento') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 8, 1);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 8, 1);
  } else if (tier.key === 'mitico') {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:regeneration', 8, 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 8, 2);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 8, 1);
  }
}

function cunimobApplyLootToolBonuses(server, player) {
  var safeName = cunihordeSafePlayer(player ? player.username : '');
  if (!server || !player || !safeName) {
    return;
  }

  var main = cunimobReadStack(player, ['mainHandItem', 'getMainHandItem', 'heldItem']);
  var off = cunimobReadStack(player, ['offHandItem', 'getOffHandItem']);
  var text = String(cunimobStackText(main) + ' ' + cunimobStackText(off)).toLowerCase();
  var tier = cunimobHeldTierFromText(text);
  var tierIndex = cunimobTierPowerIndex(tier);
  var qualityIndex = cunimobItemQualityIndexFromText(text);
  var itemPowerIndex = Math.max(tierIndex, qualityIndex);
  var speedAmp = itemPowerIndex >= 5 ? 2 : (itemPowerIndex >= 3 ? 1 : 0);

  if (text.indexOf('cuniculum_tool:"miner"') >= 0 || text.indexOf('pico') >= 0 || text.indexOf('pickaxe') >= 0) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 7, itemPowerIndex >= 5 ? 2 : (itemPowerIndex >= 2 ? 1 : 0));
    if (itemPowerIndex >= 2 || text.indexOf('fortuna') >= 0 || text.indexOf('fortune') >= 0) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, itemPowerIndex >= 5 ? 1 : 0);
    }
  }

  if (text.indexOf('cuniculum_tool:"wood"') >= 0 || text.indexOf('hacha') >= 0 || text.indexOf('axe') >= 0) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:haste', 7, itemPowerIndex >= 4 ? 1 : 0);
    if (itemPowerIndex >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, 0);
    }
  }

  if (text.indexOf('cuniculum_tool:"dig"') >= 0 || text.indexOf('pala') >= 0 || text.indexOf('shovel') >= 0) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, Math.min(2, speedAmp));
  }

  if (text.indexOf('cuniculum_tool:"farm"') >= 0 || text.indexOf('azada') >= 0 || text.indexOf('hoe') >= 0) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, itemPowerIndex >= 4 ? 1 : 0);
    if (itemPowerIndex >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:saturation', 3, 0);
    }
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"bow"', 'cuniculum_family:bow', 'longbow', 'arco', 'bow'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, Math.min(2, speedAmp));
    if (itemPowerIndex >= 2) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:night_vision', 12, 0);
    }
    if (itemPowerIndex >= 4) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:luck', 7, qualityIndex >= 5 ? 1 : 0);
    }
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"crossbow"', 'cuniculum_family:crossbow', 'ballesta', 'crossbow'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, itemPowerIndex >= 5 ? 1 : 0);
    if (itemPowerIndex >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, 0);
    }
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"dagger"', 'cuniculum_family:dagger', 'daga', 'dagger'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, Math.min(2, speedAmp + 1));
    if (itemPowerIndex >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:jump_boost', 7, 0);
    }
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"heavy"', 'cuniculum_family:heavy', 'martillo', 'maza', 'hammer', 'mace'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, itemPowerIndex >= 4 ? 1 : 0);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:resistance', 7, itemPowerIndex >= 5 ? 1 : 0);
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"staff"', 'cuniculum_family:staff', 'baston', 'staff'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:regeneration', 7, itemPowerIndex >= 5 ? 1 : 0);
    if (itemPowerIndex >= 3) {
      cunimobGivePlayerEffect(server, safeName, 'minecraft:fire_resistance', 7, 0);
    }
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"spear"', 'cuniculum_family:spear', 'lanza', 'spear'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, speedAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, itemPowerIndex >= 4 ? 1 : 0);
  }

  if (cunimobTextHasAny(text, ['cuniculum_family:"knuckle"', 'cuniculum_family:knuckle', 'nudillos', 'knuckle'])) {
    cunimobGivePlayerEffect(server, safeName, 'minecraft:speed', 7, speedAmp);
    cunimobGivePlayerEffect(server, safeName, 'minecraft:strength', 7, itemPowerIndex >= 3 ? 1 : 0);
  }

  cunimobApplyTraitEffectsFromText(server, safeName, text, itemPowerIndex);
}

function cunimobHeldMiningShape(player) {
  if (!player) {
    return '';
  }
  var main = cunimobReadStack(player, ['mainHandItem', 'getMainHandItem', 'heldItem']);
  var text = String(cunimobStackText(main)).toLowerCase();
  if (text.indexOf('cuniculum_mining_shape:"3x3"') >= 0 || text.indexOf('cuniculum_mining_shape:3x3') >= 0
    || text.indexOf('cuniculum_mining_shape=3x3') >= 0 || text.indexOf('mineria especial: area 3x3') >= 0
    || text.indexOf('area 3x3') >= 0 || text.indexOf('3x3') >= 0) {
    return '3x3';
  }
  if (text.indexOf('cuniculum_mining_shape:"2x3"') >= 0 || text.indexOf('cuniculum_mining_shape:2x3') >= 0
    || text.indexOf('cuniculum_mining_shape=2x3') >= 0 || text.indexOf('mineria especial: area 2x3') >= 0
    || text.indexOf('area 2x3') >= 0 || text.indexOf('2x3') >= 0) {
    return '2x3';
  }
  if (text.indexOf('cuniculum_mining_shape:"3x2"') >= 0 || text.indexOf('cuniculum_mining_shape:3x2') >= 0
    || text.indexOf('cuniculum_mining_shape=3x2') >= 0 || text.indexOf('mineria especial: area 3x2') >= 0
    || text.indexOf('area 3x2') >= 0 || text.indexOf('3x2') >= 0) {
    return '3x2';
  }
  if (text.indexOf('cuniculum_mining_shape:"2x2"') >= 0 || text.indexOf('cuniculum_mining_shape:2x2') >= 0
    || text.indexOf('cuniculum_mining_shape=2x2') >= 0 || text.indexOf('mineria especial: area 2x2') >= 0
    || text.indexOf('area 2x2') >= 0 || text.indexOf('2x2') >= 0) {
    return '2x2';
  }
  if (text.indexOf('cuniculum_mining_shape:"1x3"') >= 0 || text.indexOf('cuniculum_mining_shape:1x3') >= 0
    || text.indexOf('cuniculum_mining_shape=1x3') >= 0 || text.indexOf('mineria especial: linea 1x3') >= 0
    || text.indexOf('linea 1x3') >= 0 || text.indexOf('1x3') >= 0) {
    return '1x3';
  }
  if (text.indexOf('cuniculum_mining_shape:"1x2"') >= 0 || text.indexOf('cuniculum_mining_shape:1x2') >= 0
    || text.indexOf('cuniculum_mining_shape=1x2') >= 0 || text.indexOf('mineria especial: linea 1x2') >= 0
    || text.indexOf('linea 1x2') >= 0 || text.indexOf('1x2') >= 0) {
    return '1x2';
  }
  return '';
}

function cunimobBlockPosition(event) {
  var block = event ? event.block : null;
  var pos = { x: 0, y: 0, z: 0, ok: false };
  if (!block) {
    return pos;
  }
  try {
    pos.x = Math.floor(Number(block.x));
    pos.y = Math.floor(Number(block.y));
    pos.z = Math.floor(Number(block.z));
    pos.ok = true;
    return pos;
  } catch (ignored) { }
  try {
    pos.x = Math.floor(Number(block.pos.x));
    pos.y = Math.floor(Number(block.pos.y));
    pos.z = Math.floor(Number(block.pos.z));
    pos.ok = true;
    return pos;
  } catch (ignored2) { }
  return pos;
}

function cunimobAreaMineBounds(shape, pos) {
  if (shape === '3x3') {
    return { x1: pos.x - 1, y1: pos.y, z1: pos.z - 1, x2: pos.x + 1, y2: pos.y, z2: pos.z + 1 };
  }
  if (shape === '2x3') {
    return { x1: pos.x, y1: pos.y, z1: pos.z - 1, x2: pos.x + 1, y2: pos.y, z2: pos.z + 1 };
  }
  if (shape === '3x2') {
    return { x1: pos.x - 1, y1: pos.y, z1: pos.z, x2: pos.x + 1, y2: pos.y, z2: pos.z + 1 };
  }
  if (shape === '2x2') {
    return { x1: pos.x, y1: pos.y, z1: pos.z, x2: pos.x + 1, y2: pos.y, z2: pos.z + 1 };
  }
  if (shape === '1x3') {
    return { x1: pos.x - 1, y1: pos.y, z1: pos.z, x2: pos.x + 1, y2: pos.y, z2: pos.z };
  }
  if (shape === '1x2') {
    return { x1: pos.x, y1: pos.y, z1: pos.z, x2: pos.x, y2: pos.y, z2: pos.z + 1 };
  }
  return null;
}

function cunimobTryAreaMine(event) {
  var player = event ? event.player : null;
  if (!event || !player) {
    return false;
  }
  var shape = cunimobHeldMiningShape(player);
  if (!shape) {
    return false;
  }
  var dimension = cunimobDimensionFromEvent(event, player);
  if (!cunimobIsCombatDimension(dimension) || dimension === CUNIMOB_SPAWN_DIMENSION) {
    return false;
  }
  var now = Date.now();
  try {
    if (Number(player.persistentData.cuniculum_area_mine_ms || 0) + CUNIMOB_AREA_MINE_COOLDOWN_MS > now) {
      return false;
    }
    player.persistentData.cuniculum_area_mine_ms = now;
  } catch (ignored) { }
  var pos = cunimobBlockPosition(event);
  if (!pos.ok) {
    return false;
  }
  var bounds = cunimobAreaMineBounds(shape, pos);
  if (!bounds) {
    return false;
  }
  var server = null;
  try { server = event.server; } catch (ignored2) { }
  try { if (!server) { server = player.server; } } catch (ignored3) { }
  if (!server) {
    return false;
  }
  server.runCommandSilent('execute in ' + dimension + ' run fill ' + bounds.x1 + ' ' + bounds.y1 + ' ' + bounds.z1 + ' ' + bounds.x2 + ' ' + bounds.y2 + ' ' + bounds.z2 + ' minecraft:air destroy');
  return true;
}

function cunimobAutoSmeltResult(blockId) {
  var id = String(blockId || '').toLowerCase();
  if (id === 'minecraft:iron_ore' || id === 'minecraft:deepslate_iron_ore' || id === 'minecraft:raw_iron_block') {
    return { item: 'minecraft:iron_ingot', raw: 'minecraft:raw_iron', amount: id.indexOf('block') >= 0 ? 9 : 1 };
  }
  if (id === 'minecraft:gold_ore' || id === 'minecraft:deepslate_gold_ore' || id === 'minecraft:nether_gold_ore' || id === 'minecraft:raw_gold_block') {
    return { item: 'minecraft:gold_ingot', raw: 'minecraft:raw_gold', amount: id.indexOf('block') >= 0 ? 9 : 1 };
  }
  if (id === 'minecraft:copper_ore' || id === 'minecraft:deepslate_copper_ore' || id === 'minecraft:raw_copper_block') {
    return { item: 'minecraft:copper_ingot', raw: 'minecraft:raw_copper', amount: id.indexOf('block') >= 0 ? 9 : 2 };
  }
  if (id === 'minecraft:ancient_debris') {
    return { item: 'minecraft:netherite_scrap', raw: 'minecraft:ancient_debris', amount: 1 };
  }
  if (id === 'minecraft:cobblestone') {
    return { item: 'minecraft:stone', raw: 'minecraft:cobblestone', amount: 1 };
  }
  if (id === 'minecraft:sand' || id === 'minecraft:red_sand') {
    return { item: 'minecraft:glass', raw: id, amount: 1 };
  }
  if (id === 'minecraft:clay') {
    return { item: 'minecraft:terracotta', raw: 'minecraft:clay_ball', amount: 1 };
  }
  if (id.indexOf('_log') >= 0 || id.indexOf('_wood') >= 0 || id.indexOf('_stem') >= 0 || id.indexOf('_hyphae') >= 0) {
    return { item: 'minecraft:charcoal', raw: id, amount: 1 };
  }
  return null;
}

function cunimobTryAutoSmelt(event) {
  var player = event ? event.player : null;
  if (!event || !player) {
    return false;
  }
  var main = cunimobReadStack(player, ['mainHandItem', 'getMainHandItem', 'heldItem']);
  var text = String(cunimobStackText(main)).toLowerCase();
  if (!cunimobTextHasTrait(text, 'fundidor')) {
    return false;
  }
  var blockId = '';
  try { blockId = String(event.block.id || '').toLowerCase(); } catch (ignored) { }
  var result = cunimobAutoSmeltResult(blockId);
  if (!result) {
    return false;
  }
  var traitPower = cunimobTraitPowerFromText(text, 1);
  var chance = Math.min(0.46, 0.10 + traitPower * 0.065);
  if (Math.random() > chance) {
    return false;
  }
  var server = null;
  try { server = event.server; } catch (ignored2) { }
  try { if (!server) { server = player.server; } } catch (ignored3) { }
  if (!server) {
    return false;
  }
  var dimension = cunimobDimensionFromEvent(event, player);
  var pos = cunimobBlockPosition(event);
  var safeName = cunihordeSafePlayer(player.username);
  if (!dimension || !pos.ok || !safeName) {
    return false;
  }
  try { event.cancel(); } catch (ignored4) { }
  server.runCommandSilent('execute in ' + dimension + ' run setblock ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' minecraft:air replace');
  server.scheduleInTicks(1, function () {
    server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run kill @e[type=minecraft:item,distance=..2,nbt={Item:{id:"' + result.raw + '"}}]');
    server.runCommandSilent('give ' + safeName + ' ' + result.item + ' ' + Math.max(1, Math.floor(result.amount || 1)));
    server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run particle minecraft:flame ~ ~0.4 ~ 0.25 0.20 0.25 0.01 8 force');
    server.runCommandSilent('execute in ' + dimension + ' positioned ' + pos.x + ' ' + pos.y + ' ' + pos.z + ' run playsound minecraft:block.furnace.fire_crackle block @a[distance=..12] ~ ~ ~ 0.35 1.35');
  });
  return true;
}

BlockEvents.broken(function (event) {
  cunimobTryAreaMine(event);
  if (cunimobTryAutoSmelt(event)) {
    return;
  }
});

PlayerEvents.tick(event => {
  var player = event.player;
  var server = event.server;
  if (!player || !server) {
    return;
  }

  if (Number(player.age || 0) % 100 === 0) {
    cunimobApplyLootSetBonuses(server, player);
    cunimobApplyLootToolBonuses(server, player);
  }

  var dimension = cunimobDimension(event) || cunimobDimensionFromLevel(player.level);
  if (!cunimobIsCombatDimension(dimension)) {
    return;
  }

  if (Number(player.age || 0) % 80 === 0) {
    cunimobRenderNearbyAuras(server, player.username);
  }

  if (player.age % CUNIMOB_NATURAL_SCAN_TICKS === 0) {
    cunimobApplyNaturalNearPlayer(server, player, event.level || player.level);
    cunimobControlIronGolemDensity(server, cunihordeSafePlayer(player.username));
  }

  if (Number(player.age || 0) % 200 === 0) {
    cunimobCleanupOldDisplayLabels(server, cunihordeSafePlayer(player.username));
    cunimobLimitTamedWolves(server, player);
  }

  if (CUNIMOB_OUT_OF_COMBAT_REGEN_ENABLED && Number(player.age || 0) % 100 === 0) {
    cunimobRegenerateOutOfCombat(server, cunihordeSafePlayer(player.username));
  }

  // CUNICULUM scales unlabeled natural mobs from the nearest player's gear/progress.
  if (dimension !== 'minecraft:overworld' || player.age % CUNIHORDE_AUTO_CHECK_TICKS !== 0) {
    return;
  }

  if (!cunihordeAutoEnabled(server) || !cunihordeCanAutoRun(server) || cunihordeActive(server)) {
    return;
  }

  if (Number(player.age || 0) < 2400 || !cunihordePlayerReady(player)) {
    return;
  }

  if (cunimobDistanceFromSpawn(player) < CUNIHORDE_SAFE_RADIUS) {
    return;
  }

  if (!cunihordeIsNight(event.level)) {
    return;
  }

  if (Math.random() > 0.12) {
    return;
  }

  var type = cunihordeRandomType(player);
  var level = cunimobLevelForPlayer(player, event.level || player.level, dimension, 'horde', CUNIHORDE_TYPES[type].bonus);
  cunihordeMarkAutoRun(server);
  cunihordeMarkPlayer(player);
  cunihordeMarkActive(server);
  cunihordeFeedback(server, 'Se sienten pasos en la oscuridad...', 'dark_red');
  server.scheduleInTicks(20 * 45, () => {
    cunihordeFeedback(server, 'Una amenaza se acerca. Preparate.', 'red');
  });
  server.scheduleInTicks(20 * 75, () => {
    cunihordeSummon(server, player.username, type, level);
  });
});

