//tqm
import {world,  system,  ItemStack} from '@minecraft/server';
import {list, spawnEnt, lc, durabilidad, dispararP, timer} from './main.js';

/*system.runInterval(()=>{
  for (const e of world.getDimension('overworld').getEntities()) {
    if (e.typeId === 'minecraft:player') {
      const t = e.getComponent('inventory').container.getItem(e.selectedSlotIndex);
      e.onScreenDisplay.setActionBar(`${t?.typeId}`)
      if (t?.typeId === 'minecraft:redstone') e.applyKnockback(0, 0, 0.5, 2)
    }
  }
});*/

world.afterEvents.entityHurt.subscribe(data=>{
  const fuente = data.damageSource.damagingEntity;
  const qm = data.hurtEntity;
  //const salud = qm.getComponent('health');
  //qm.nameTag = `${Math.floor(salud.currentValue)} / ${salud.defaultValue}`
  if (fuente?.typeId.includes("parasitesap:")) {
    try {
      const entity = fuente.dimension.getEntities({location:{ x: fuente.location.x, y: fuente.location.y, z: fuente.location.z},  maxDistance: 5});
      for (const ent of entity) {
        if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) ent.addTag('parasite')
      }
    } catch(error){}finally{}
  }
  if (fuente?.typeId === "parasitesap:devourer") {
    fuente.clearVelocity();
  }
});

system.afterEvents.scriptEventReceive.subscribe(emd=>{
  const ev = emd.id;
  const ent = emd.sourceEntity;
  if (ev === 'parasitesap:remains') {
    const entity = ent.location;
    const e = ent.dimension.getEntities({location:entity, type: "parasitesap:remains",  maxDistance: 2});
    for(const nop of e) {
      const victima = nop.location;
      const Vx = victima.x - entity.x
      const Vy = victima.y - entity.y
      const Vz = victima.z - entity.z
      const V = Math.sqrt(Math.pow(Vx, 2) + Math.pow(Vy, 2) + Math.pow(Vz, 2));
      nop.applyImpulse({x: Vx/V*0.8, y: Vy/V*0.7, z: Vz/V*0.8})
    }
  }
  if (ev === 'parasitesap:wardenb') {
    const tL = ent.target?.location;
    ent.lookAt({x: tL.x, y: tL.y+1, z: tL.z});
    const v = ent.getViewDirection();
    ent.applyImpulse({x: v.x*0.4, y: v.y*0.4, z: v.z*0.4});
  }
  if (ev === 'parasitesap:wardenc') {
    const tL = ent.target?.location;
    ent.lookAt({x: tL.x, y: tL.y+7, z: tL.z});
    const v = ent.getViewDirection();
    ent.applyImpulse({x: v.x*0.4, y: v.y*0.4, z: v.z*0.4});
  }
  if (ev === 'parasitesap:c') {
    system.run(()=>{
      if (ent.hasTag('parasitesap_lanzar')) {
        const t = ent.target
        const v = ent.getViewDirection();
        ent.removeTag('parasitesap_lanzar');
        if (t.typeId === 'minecraft:player') return t.applyKnockback (v.x, v.z, 3, 2)
        t.applyImpulse({x: v.x*3, y: 2, z: v.z*3});
      }
      if (ent.hasTag('parasitesap_salto')) {
        const eL = ent.location;
        const tL = ent.target?.location ?? null;
        if (tL === null) return ent.applyImpulse({x: 0, y: 2, z: 0})
        const bx = tL.x - eL.x;
        const by = tL.y - eL.y;
        const bz = tL.z - eL.z;
        const r = Math.sqrt(Math.pow(bx, 2) + Math.pow(by, 2) + Math.pow(bz, 2))
        ent.applyImpulse({
          x: bx/r*r*0.25,
          y: by/r*r*0.13,
          z: bz/r*r*0.25
        });
        ent.removeTag('parasitesap_salto');
      }
      if (ent.hasTag('parasitesap_aplicar')) {
        ent.clearVelocity();
        const t = ent.target
        ent.lookAt({x: t.location.x, y: t.location.y, z: t.location.z})
        const v = ent.getViewDirection();
        ent.removeTag('parasitesap_aplicar');
        t.applyDamage(15, {cause: "entityAttack", damagingEntity: ent});
        if (t.typeId === 'minecraft:player') return t.applyKnockback(v.x, v.z, 3, -2);
        t.applyImpulse({x: v.x*3, y: -2, z: v.z*3});
      }
    });
  }
  if (ev === 'parasitesap:p') {
    const entity = ent.location;
    const e = ent.dimension.getEntities({location:entity, excludeFamilies: ["parasitesap", "inanimate"], excludeTypes: ["minecraft:xp_orb", "minecraft:item"],  maxDistance: 8});
    for(const nop of e) {
      const victima = nop.location;
      const Vx = victima.x - entity.x
      const Vy = victima.y - entity.y
      const Vz = victima.z - entity.z
      const V = Math.sqrt(Math.pow(Vx, 2) + Math.pow(Vy, 2) + Math.pow(Vz, 2));
      if (nop.typeId === 'minecraft:player') {
        if (!nop.matches({gameMode: 'creative'}) && !nop.matches({gameMode: 'spectator'})) {
          nop.applyKnockback(-Vx/V, -Vz/V, 1.8, -Vy/V);
        }
      }
      else if (nop.typeId !== 'minecraft:player') {
        nop.applyImpulse({x: -Vx/V*1.2, y: -Vy/V*1.2, z: -Vz/V*1.2})
      }
    }
  }
  if (ev === 'parasitesap:salto') {
    const hola = 'auausjs'
    const eL = ent.location;
    const tL = ent.target?.location ?? hola;
    const e = ent.getViewDirection();
    if (ent.typeId ==='parasitesap:mutated_meat_tracker') {
      if (tL === hola) return ent.applyImpulse({x: 0, y: 0.6, z: 0});
      ent.lookAt({x: tL.x, y: tL.y, z: tL.z});
      const getV = ent.getViewDirection();
      ent.applyImpulse({
        x: getV.x*5,
        y: 0.6,
        z: getV.z*5
      });
      /*const empX = tL.x - eL.x
      const empZ = tL.z - eL.z
      const b = 5
      ent.applyImpulse({
        x: empX/b,
        y: 0.6,
        z: empZ/b
      });*/
    }
    if (ent.typeId.includes('parasitesap:mut_inf')) ent.applyKnockback(tL.x - eL.x, tL.z - eL.z, 6, 0.9);
  }
  if (ev === 'parasitesap:infectar') {
    const bloque = ent.dimension.getBlock({x: ent.location.x, y: ent.location.y - 1, z: ent.location.z});
    if (bloque.hasTag('dirt') || bloque.hasTag('grass') || bloque.hasTag('sand')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_dirt`);
    }
    else if (bloque.typeId.includes('stone') && bloque.typeId.includes('minecraft:') || bloque.hasTag('stone') || bloque.typeId.includes('deepslate') || bloque.typeId.includes('netherrack')) {
      ent.dimension.runCommandAsync(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infested_stone`);
    }
    else if (bloque.hasTag('log') || bloque.typeId.includes('log')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_trunk`);
    }
    else if (bloque.hasTag('wood') || bloque.typeId.includes('planks') && !bloque.hasTag('log') && !bloque.typeId.includes('log')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_planks`);
    }
  }
  if (ev === 'parasitesap:fase') {
    const dim = world.getDimension(ent.dimension.id).id;
    if (ent.typeId === 'parasitesap:kdjfje') world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 3);
    if (ent.typeId.includes('parasitesap:infected')) world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 10);
    if (ent.typeId === 'parasitesap:growing_flesh') world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 20);
    if (ent.typeId.startsWith('parasitesap:nu_')) world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 50);
  }
  if (ev === 'parasitesap:s') {
    const objetivo = ent.target
    salto(ent, objetivo);
  }
});

world.afterEvents.entityDie.subscribe(muerte=>{
  const idTransformation = [
    "parasitesap:unknown_worm",
    "parasitesap:parasite",
    "_remains"
  ];
  const muert = muerte.deadEntity;
  const cause = muerte.damageSource?.damagingEntity;
  function muerte1(m1) {
    m1.dimension.spawnEntity(`parasitesap:infected_zombie`, {x: m1.location.x, y: m1.location.y, z: m1.location.z});
    m1.dimension.spawnParticle('parasitesap:parasite', {x: m1.location.x, y: m1.location.y, z: m1.location.z});
    m1.remove();
  }
  function muerte2(m1) {}
  if (cause?.typeId.includes('parasitesap:' || muert.typeId.includes('parasitesap:'))) {
    try {
      if (cause?.typeId.startsWith("parasitesap:")) {
        const entity = cause?.dimension?.getEntities();
        for (const entidad of entity) {
          if (entidad !== undefined && entidad.typeId.includes('parasitesap:nu_')) entidad.triggerEvent("parasitesap:nu_s");
          if (entidad !== undefined && entidad.typeId == 'parasitesap:growing_flesh') entidad.triggerEvent('parasitesap:ccgf')
        }
        const puntos = world.scoreboard.getObjective('parasitephasegs');
        const dim = world.getDimension(cause?.dimension.id).id;
        let p;
        const salud = cause?.getComponent('health').effectiveMax
        const tileEntity = world
        .getDimension(cause.dimension.id)
        .getEntities({ type: "parasitesap:booster" })[0];
        if (tileEntity === undefined) p = 1;
        if (tileEntity !== undefined) p = 4;
        if (tileEntity !== undefined) {
          for(const s of idTransformation) {
            if (cause.typeId.includes(s)) {
              spawnEnt(muert, tileEntity);
              lc(muert);
              return;
            }
            else return lc(muert);
          }
        }
        if (cause?.typeId == 'parasitesap:unknown_worm') puntos.addScore(`parasitesaphase_${dim}`, 5 * p);
        if (cause?.typeId == 'parasitesap:parasite') puntos.addScore(`parasitesaphase_${dim}`, 2 * p);
        if (cause?.typeId.includes('parasitesap:infected') && !cause?.typeId.includes('remains')) puntos.addScore(`parasitesaphase_${dim}`, 3 * p);
        if (cause?.typeId.includes('parasitesap:mut_inf')) {
          puntos.addScore(`parasitesaphase_${dim}`, 5 * p);
          if (!cause?.typeId.includes('bat')) {
            const limite = cause?.getProperty('parasitesap:limit');
            if (limite < 3 && cause.hasTag('parasitephase2')) {
              cause.dimension.spawnParticle('add_points', {x: cause.location.x, y: cause.location.y + 1, z: cause.location.z});
              const propiedad = cause?.getProperty('parasitesap:puntos');
              cause.triggerEvent('parasitesap:puntos');
              //cause.setProperty('parasitesap:puntos', +1)
              if (propiedad > 14) {
                cause.dimension.spawnEntity('parasitesap:growing_flesh', {x: cause.location.x, y: cause.location.y, z: cause.location.z});
                cause.triggerEvent('parasitesap:limit');
                //cause.setProperty('parasitesap:limit', +1)
                cause.setProperty('parasitesap:puntos', 0);
              }
            }
          }
        }
        if (cause?.typeId.includes('parasitesap:mutated_')) puntos.addScore(`parasitesaphase_${dim}`, 8 * p);
        if (cause?.typeId === ('parasitesap:hhc')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:devourer')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:pgt')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:warden')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        else puntos.addScore(`parasitesaphase_${dim}`, 1 * p);
      } 
      if (muert.typeId.startsWith('parasitesap:')) {
        if (muert.typeId.includes('parasitesap:oth_b')) return;
        const dim = world.getDimension(muert?.dimension?.id)?.id;
        const puntos = world.scoreboard.getObjective('parasitephasegs');
        if (muert?.typeId == 'parasitesap:parasite') puntos.addScore(`parasitesaphase_${dim}`, - 1);
        if (muert?.typeId.includes('parasitesap:infected')) puntos.addScore(`parasitesaphase_${dim}`, - 2);
        if (muert?.typeId.includes('parasitesap:mut_inf')) puntos.addScore(`parasitesaphase_${dim}`, - 3);
        if (muert?.typeId.includes('parasitesap:mutated_')) puntos.addScore(`parasitesaphase_${dim}`, - 6);
        if (muert?.typeId == 'parasitesap:lc') puntos.addScore(`parasitesaphase_${dim}`, - 2);
        if (muert?.typeId == 'parasitesap:nu_1') puntos.addScore(`parasitesaphase_${dim}`, - 1);
        if (muert?.typeId == 'parasitesap:nu_2') puntos.addScore(`parasitesaphase_${dim}`, - 2);
        if (muert?.typeId == 'parasitesap:nu_3') puntos.addScore(`parasitesaphase_${dim}`, - 3);
        if (muert?.typeId == 'parasitesap:nu_4') puntos.addScore(`parasitesaphase_${dim}`, - 4);
        else puntos.addScore(`parasitesaphase_${dim}`, - 1);
      }
    }catch(error){}finally{}
  }
  if (true) {
    for (const jg of list) {
      for (const eow of idTransformation) {
        if (muert.typeId == jg && muert.hasTag('parasite') || cause?.typeId.includes(eow)) {
          const tileEntity = world
          .getDimension(cause.dimension.id)
          .getEntities({ type: "parasitesap:booster" })[0];
          spawnEnt(muert, tileEntity);
        }
      }
      return;
    }
  }
  //EXPERIMENTAL
  else if (muert.typeId.includes('zombie') && (muert.hasTag('parasite') || cause?.typeId.startsWith('parasitesap:'))) {
    const sns = [muerte1, muerte2, muerte2, muerte2];
    const snsbb = Math.floor(Math.random() * sns.length);
    sns[snsbb](muert);
  }
  else if (muert.typeId.includes('human') || muert.nameTag.toLowerCase().includes("human") && (muert.hasTag('parasite') || cause?.typeId.startsWith('parasitesap:'))) {
    muert.dimension.spawnEntity(`parasitesap:infected_human`, { x: muert.location.x, y: muert.location.y, z: muert.location.z });
    muert.dimension.spawnParticle('parasitesap:parasite', { x: muert.location.x, y: muert.location.y, z: muert.location.z });
    muert.remove();
  }
  return;
});

world.afterEvents.projectileHitEntity.subscribe(proyectil=>{
  const proj = proyectil.source;
  const pr = proyectil.projectile;
  const victima = proyectil.getEntityHit().entity;
  /*if (proj.typeId == 'parasitesap:mutated_arachnid') {
  }*/
  /*if (pr.typeId == 'parasitesap:flecha') {
    const perforacion = pr.nameTag;
    const score = world.scoreboard.getObjective('flecha_parasitesap');
    score.addScore(pr, 1);
    const s = world.scoreboard.getObjective("flecha_parasitesap").getScore(pr);
    if (s == perforacion) pr.remove();
  }*/
  if (pr.typeId == 'parasitesap:pa') {
    const {location, dimension} = proyectil;
    const tileEntity = world
    .getDimension(pr.dimension.id)
    .getEntities({ type: "parasitesap:booster" })[0];
    const entity = proyectil.dimension.getEntities({location:{ x: proyectil.location.x, y: proyectil.location.y, z: proyectil.location.z},  maxDistance: 4});
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
    for (const ent of entity) {
      if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:player' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) {
        spawnEnt(ent, tileEntity);
        lc(ent);
      }
    }
    pr.remove();
  }
  if (pr.typeId == 'parasitesap:potion_a') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
  }
  if (pr.typeId == 'parasitesap:potion_c') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
  }
  return;
});

world.afterEvents.projectileHitBlock.subscribe(proyectil=>{
  const proj = proyectil.source;
  const pr = proyectil.projectile;
  /*if (proj.typeId == 'parasitesap:mutated_arachnid') {
    
  }*/
  if (pr.typeId == 'parasitesap:flecha') {
    try {
      if (pr.hasTag('parasitesap:remover')) {
        system.runTimeout(()=>{
          pr.remove();
        }, 4);
      }
    } catch(error){} finally{}
  }
  if (pr.typeId == 'parasitesap:pa') {
    const {location, dimension} = proyectil;
    const tileEntity = world
    .getDimension(pr.dimension.id)
    .getEntities({ type: "parasitesap:booster" })[0];
    const entity = proyectil.dimension.getEntities({location:{ x: proyectil.location.x, y: proyectil.location.y, z: proyectil.location.z},  maxDistance: 4});
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    for (const ent of entity) {
      if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:player' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) {
        spawnEnt(ent, tileEntity);
        lc(ent);
      }
    }
    pr.remove();
  }
  if (pr.typeId == 'parasitesap:potion_a') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    return;
  }
  if (pr.typeId == 'parasitesap:potion_c') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    return;
  }
  return;
});

world.afterEvents.itemCompleteUse.subscribe(({itemStack, source}) => {
  if (itemStack.typeId === "parasitesap:potion_b") {
    source.removeTag("parasite");
  }
  return;
});

world.beforeEvents.worldInitialize.subscribe(customC => {
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:caer', {
    onEntityFallOn: boca => {
      const gs = boca.block;
      const ent = boca.entity;
      const ob = gs.permutation.getState('parasitesap:dientes')
      if (ob <= 0) return;
      const est = gs.permutation.withState("parasitesap:pisar", true);
      gs.setPermutation(est);
      if (!ent.typeId.includes('parasitesap:') && ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item') ent.applyDamage(1);
    },
  });
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:pisar', {
    onStepOn: boca => {
      const gs = boca.block;
      const ent = boca.entity;
      const ob = gs.permutation.getState('parasitesap:dientes')
      if (ob <= 0) return;
      const est = gs.permutation.withState("parasitesap:pisar", true);
      gs.setPermutation(est);
      if (!ent.typeId.includes('parasitesap:') && ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item') ent.applyDamage(1);
    },
  });
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:dejar_de_pisar', {
    onStepOff: boca => {
      const gs = boca.block;
      const est = gs.permutation.withState("parasitesap:pisar", false);
      gs.setPermutation(est);
    },
  });
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:pisando', {
    onTick: boca => {
      const gs = boca.block;
      const ob = gs.permutation.getState('parasitesap:dientes')
      if (ob <= 0) {
        const kxhs = gs.permutation.withState("parasitesap:pisar", false);
        gs.setPermutation(kxhs);
      }
      const entity = gs.dimension.getEntities({location:{ x: gs.location.x, y: gs.location.y, z: gs.location.z},  maxDistance: 1.1});
      for (const ent of entity) {
        if (!ent.typeId.includes('parasitesap:') && ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item') ent.applyDamage(1);
      }
    },
  });
//
  customC.blockComponentRegistry.registerCustomComponent("parasitesap:int", {
    onPlayerInteract: dientes => {
      const bloque = dientes.block;
      const ge = dientes.player;
      let item = ge.getComponent('inventory').container;
      const ob = bloque.permutation.getState('parasitesap:dientes');
      if (item.getItem(ge.selectedSlotIndex)?.typeId == 'minecraft:shears') {
        if (ob === 4) {
          bloque.dimension.spawnItem(new ItemStack('parasitesap:oth_b'), {x: bloque.location.x, y: bloque.location.y + 1, z: bloque.location.z});
          const est = bloque.permutation.withState("parasitesap:dientes", 3);
          bloque.setPermutation(est);
        }
        if (ob === 3) {
          bloque.dimension.spawnItem(new ItemStack('parasitesap:oth_b'), {x: bloque.location.x, y: bloque.location.y + 1, z: bloque.location.z});
          const est = bloque.permutation.withState("parasitesap:dientes", 2);
          bloque.setPermutation(est);
        }
        if (ob === 2) {
          bloque.dimension.spawnItem(new ItemStack('parasitesap:oth_b'), {x: bloque.location.x, y: bloque.location.y + 1, z: bloque.location.z});
          const est = bloque.permutation.withState("parasitesap:dientes", 1);
          bloque.setPermutation(est);
        }
        if (ob === 1) {
          bloque.dimension.spawnItem(new ItemStack('parasitesap:oth_b'), {x: bloque.location.x, y: bloque.location.y + 1, z: bloque.location.z});
          const est = bloque.permutation.withState("parasitesap:dientes", 0);
          bloque.setPermutation(est);
        }
        if (ob > 0 && !ge.matches({gameMode: "creative"})) {
          const sl = item.getItem(ge.selectedSlotIndex);
          const o = 1;
          durabilidad(ge, sl, o);
        }
      }
      if (item.getItem(ge.selectedSlotIndex)?.typeId == 'parasitesap:oth_b') {
        const kxhs = bloque.permutation.withState("parasitesap:pisar", false);
        if (ob < 4 && !ge.matches({gameMode: "creative"})) {
          ge.runCommand('clear @s parasitesap:oth_b 0 1');
        }
        if (ob === 3) {
          const est = bloque.permutation.withState("parasitesap:dientes", 4);
          bloque.setPermutation(kxhs);
          bloque.setPermutation(est);
        }
        if (ob === 2) {
          const est = bloque.permutation.withState("parasitesap:dientes", 3);
          bloque.setPermutation(kxhs);
          bloque.setPermutation(est);
        }
        if (ob === 1) {
          const est = bloque.permutation.withState("parasitesap:dientes", 2);
          bloque.setPermutation(kxhs);
          bloque.setPermutation(est);
        }
        if (ob === 0) {
          const est = bloque.permutation.withState("parasitesap:dientes", 1);
          bloque.setPermutation(est);
        }
      }
    },
  });
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:infectar_bloques', {
    onTick: ma => {
      try {
        const blo = ma.block;
        const tileEntity = world
        .getDimension(blo.dimension.id)
        .getEntities({ families: ["spiowwjdixj"] })[0];
        if (tileEntity === undefined) {
          if (blo.typeId.includes('dirt')) {
            blo.setType('minecraft:dirt');
          }
          else if (blo.typeId.includes('stone')) {
            const dim = world.getDimension(blo.dimension.id);
            if (dim.id === 'minecraft:overworld') blo.setType('minecraft:cobblestone');
            else if (dim.id === 'minecraft:nether') blo.setType('minecraft:netherrack');
            else if (dim.id === 'minecraft:the_end') blo.setType('minecraft:end_stone');
            else blo.setType('minecraft:cobblestone');
          }
          else if (blo.typeId.includes('trunk')) {
            blo.setType('minecraft:oak_wood');
          }
          else if (blo.typeId.includes('planks')) {
            blo.setType('minecraft:oak_planks');
          }
          return;
        }
        //
        const ob_y = blo.dimension.getBlock({x: blo.location.x, y: blo.location.y + 1, z: blo.location.z});
        if (ob_y.typeId.includes('stone') && ob_y.typeId.includes('minecraft:') || ob_y.hasTag('dirt') || ob_y.hasTag('grass') || ob_y.hasTag('sand') || ob_y.hasTag('stone') || ob_y.typeId.includes('deepslate') || ob_y.hasTag('log') || ob_y.typeId.includes('log') || ob_y.hasTag('wood') || ob_y.typeId.includes('planks') || ob_y.typeId.includes('netherrack')) {
          if (ob_y.hasTag('dirt') || ob_y.hasTag('grass') || ob_y.hasTag('sand')) {
            blo.above(1).setType('parasitesap:infected_dirt');
          }
          else if (ob_y.typeId.includes('stone') && ob_y.typeId.includes('minecraft:') || ob_y.hasTag('stone') || ob_y.typeId.includes('deepslate') || ob_y.typeId.includes('netherrack')) {
            blo.above(1).setType('parasitesap:infested_stone');
          }
          else if (ob_y.hasTag('log') || ob_y.typeId.includes('log')) {
            blo.above(1).setType('parasitesap:infected_trunk');
          }
          else if (ob_y.hasTag('wood') || ob_y.typeId.includes('planks') && !ob_y.hasTag('log') && !ob_y.typeId.includes('log')) {
            blo.above(1).setType('parasitesap:infected_planks');
          }
        }
        //
        const oby = blo.dimension.getBlock({x: blo.location.x, y: blo.location.y - 1, z: blo.location.z});
        if (oby.typeId.includes('stone') && oby.typeId.includes('minecraft:') || oby.hasTag('dirt') || oby.hasTag('grass') || oby.hasTag('sand') || oby.hasTag('stone') || oby.typeId.includes('deepslate') || oby.hasTag('log') || oby.typeId.includes('log') || oby.hasTag('wood') || oby.typeId.includes('planks') || oby.typeId.includes('netherrack')) {
          if (oby.hasTag('dirt') || oby.hasTag('grass') || oby.hasTag('sand')) {
            blo.below(1).setType('parasitesap:infected_dirt');
          }
          else if (oby.typeId.includes('stone') && oby.typeId.includes('minecraft:') || oby.hasTag('stone') || oby.typeId.includes('deepslate') || oby.typeId.includes('netherrack') ) {
            blo.below(1).setType('parasitesap:infested_stone');
          }
          else if (oby.hasTag('log') || oby.typeId.includes('log')) {
            blo.below(1).setType('parasitesap:infected_trunk');
          }
          else if (oby.hasTag('wood') || oby.typeId.includes('planks') && !oby.hasTag('log') && !oby.typeId.includes('log')) {
            blo.below(1).setType('parasitesap:infected_planks');
          }
        }
        //
        const obx = blo.dimension.getBlock({x: blo.location.x + 1, y: blo.location.y, z: blo.location.z});
        if (obx.typeId.includes('stone') && obx.typeId.includes('minecraft:') || obx.hasTag('dirt') || obx.hasTag('grass') || obx.hasTag('sand') || obx.hasTag('stone') || obx.typeId.includes('deepslate') || obx.hasTag('log') || obx.typeId.includes('log') || obx.hasTag('wood') || obx.typeId.includes('planks') || obx.typeId.includes('netherrack')) {
          if (obx.hasTag('dirt') || obx.hasTag('grass') || obx.hasTag('sand')) {
            blo.east(1).setType('parasitesap:infected_dirt');
          }
          else if (obx.typeId.includes('stone') && obx.typeId.includes('minecraft:') || obx.hasTag('stone') || obx.typeId.includes('deepslate') || obx.typeId.includes('netherrack')) {
            blo.east(1).setType('parasitesap:infested_stone');
          }
          else if (obx.hasTag('log') || obx.typeId.includes('log')) {
            blo.east(1).setType('parasitesap:infected_trunk');
          }
          else if (obx.hasTag('wood') || obx.typeId.includes('planks') && !obx.hasTag('log') && !obx.typeId.includes('log')) {
            blo.east(1).setType('parasitesap:infected_planks');
          }
        }
        //
        const ob_x = blo.dimension.getBlock({x: blo.location.x - 1, y: blo.location.y, z: blo.location.z});
        if (ob_x.typeId.includes('stone') && ob_x.typeId.includes('minecraft:') || ob_x.hasTag('dirt') || ob_x.hasTag('grass') || ob_x.hasTag('sand') || ob_x.hasTag('stone') || ob_x.typeId.includes('deepslate') || ob_x.hasTag('log') || ob_x.typeId.includes('log') || ob_x.hasTag('wood') || ob_x.typeId.includes('planks') || ob_x.typeId.includes('netherrack')) {
          if (ob_x.hasTag('dirt') || ob_x.hasTag('grass') || ob_x.hasTag('sand')) {
            blo.west(1).setType('parasitesap:infected_dirt');
          }
          else if (ob_x.typeId.includes('stone') && ob_x.typeId.includes('minecraft:') || ob_x.hasTag('stone') || ob_x.typeId.includes('deepslate') || ob_x.typeId.includes('netherrack')) {
            blo.west(1).setType('parasitesap:infested_stone');
          }
          else if (ob_x.hasTag('log') || ob_x.typeId.includes('log')) {
            blo.west(1).setType('parasitesap:infected_trunk');
          }
          else if (ob_x.hasTag('wood') || ob_x.typeId.includes('planks') && !ob_x.hasTag('log') && !ob_x.typeId.includes('log')) {
            blo.west(1).setType('parasitesap:infected_planks');
          }
        }
        //
        const ob_z = blo.dimension.getBlock({x: blo.location.x, y: blo.location.y, z: blo.location.z + 1})
        if (ob_z.typeId.includes('stone') && ob_z.typeId.includes('minecraft:') || ob_z.hasTag('dirt') || ob_z.hasTag('grass') || ob_z.hasTag('sand') || ob_z.hasTag('stone') || ob_z.typeId.includes('deepslate') || ob_z.hasTag('log') || ob_z.typeId.includes('log') || ob_z.hasTag('wood') || ob_z.typeId.includes('planks') || ob_z.typeId.includes('netherrack')) {
          if (ob_z.hasTag('dirt') || ob_z.hasTag('grass') || ob_z.hasTag('sand')) {
            blo.south(1).setType('parasitesap:infected_dirt');
          }
          else if (ob_z.typeId.includes('stone') && ob_z.typeId.includes('minecraft:') || ob_z.hasTag('stone') || ob_z.typeId.includes('deepslate') || ob_z.typeId.includes('netherrack')) {
            blo.south(1).setType('parasitesap:infested_stone');
          }
          else if (ob_z.hasTag('log') || ob_z.typeId.includes('log')) {
            blo.south(1).setType('parasitesap:infected_trunk');
          }
          else if (ob_z.hasTag('wood') || ob_z.typeId.includes('planks') && !ob_z.hasTag('log') && !ob_z.typeId.includes('log')) {
            blo.south(1).setType('parasitesap:infected_planks');
          }
        }
        //
        const obz = blo.dimension.getBlock({x: blo.location.x, y: blo.location.y, z: blo.location.z - 1});
        if (obz.typeId.includes('stone') && obz.typeId.includes('minecraft:') || obz.hasTag('dirt') || obz.hasTag('grass') || obz.hasTag('sand') || obz.hasTag('stone') || obz.typeId.includes('deepslate') || obz.hasTag('log') || obz.typeId.includes('log') || obz.hasTag('wood') || obz.typeId.includes('planks') || obz.typeId.includes('netherrack')) {
          if (obz.hasTag('dirt') || obz.hasTag('grass') || obz.hasTag('sand')) {
            blo.north(1).setType('parasitesap:infected_dirt');
          }
          else if (obz.typeId.includes('stone') && obz.typeId.includes('minecraft:') || obz.hasTag('stone') || obz.typeId.includes('netherrack') || obz.typeId.includes('deepslate')) {
            blo.north(1).setType('parasitesap:infested_stone');
          }
          else if (obz.hasTag('log') || obz.typeId.includes('log')) {
            blo.north(1).setType('parasitesap:infected_trunk');
          }
          else if (obz.hasTag('wood') || obz.typeId.includes('planks') && !obz.hasTag('log') && !obz.typeId.includes('log')) {
            blo.north(1).setType('parasitesap:infected_planks');
          }
        }
        return;
      } catch(error){}finally{}
    },
  });
  customC.blockComponentRegistry.registerCustomComponent('parasitesap:piso', {
    onTick: ma => {
      const blo = ma.block;
      blo.setType('minecraft:air');
    },
  });
  customC.blockComponentRegistry.registerCustomComponent("parasitesap:grass", {
    onRandomTick: cb => {
      const blo = cb.block;
      const loc = blo.dimension.getBlock({x: blo.location.x, y: blo.location.y + 1, z: blo.location.z});
      if (loc.typeId !== "minecraft:air") {
        const est = blo.permutation.withState('parasitesap:pi', false);
        blo.setPermutation(est)
      }
      else {
        function pasto0(p) {
          const est = p.permutation.withState('parasitesap:pi', false);
          p.setPermutation(est);
        }
        function pasto1(p) {
          p.above(1).setType('parasitesap:pg');
          const est = p.permutation.withState('parasitesap:pi', false);
          p.setPermutation(est);
        }
        const sr = [pasto0, pasto1];
        const sb = Math.floor(Math.random() * sr.length);
        sr[sb](blo);
      }
    },
  });
//
  customC.itemComponentRegistry.registerCustomComponent("parasitesap:t", {
    onHitEntity: hit => {
      const gs = hit.hitEntity
      const tileEntity = world
      .getDimension(gs.dimension.id)
      .getEntities({ type: "parasitesap:booster" })[0];
      if (gs.typeId.includes('parasitesap:') || gs.typeId == 'minecraft:player') return;
      spawnEnt(gs, tileEntity);
      lc(gs);
      return;
    },
  });
  customC.itemComponentRegistry.registerCustomComponent("parasitesap:phase_indicator", {
    onUse: p => {
      const item = p.source
      const dim = world.getDimension(item.dimension.id).id;
      const sc = world.scoreboard.getObjective("parasitephasegs").getScore(`parasitesaphase_${dim}_num`);
      item.onScreenDisplay.setActionBar(`${sc}`);
    },
  });
  customC.itemComponentRegistry.registerCustomComponent("parasitesap:b", {
    onUse: b => {
      const ballesta = "parasitic_crossbow"
      const item = b.source;
      const inventory = item.getComponent("minecraft:inventory").container;
      let at = false;
      function ggg() {
        at = true;
        item.playSound('crossbow.loading.start', {location: item.location});
      }
      for (let i = 0; i < inventory.size; i++) {
        const flecha = inventory.getItem(i);
        const offHand = item.getComponent("minecraft:equippable").getEquipmentSlot(`Offhand`).getItem();
        if (flecha?.typeId === "minecraft:arrow" && at == false) ggg();
        else if (offHand?.typeId === 'minecraft:arrow' && at == false) ggg();
        else if (item.matches({gameMode: 'creative'}) && at == false) ggg();
      }
    },
    onCompleteUse: b => {
      const ballesta = "parasitic_crossbow"
      const item2 = b.itemStack;
      const source = b.source;
      const nombre = item2.nameTag;
      let c = item2.getComponent('minecraft:durability').damage;
      const inventory = source.getComponent("minecraft:inventory").container;
      let at = false;
      const enchantment = item2.getComponent("enchantable")?.getEnchantments();
      function cargar() {
        at = true;
        if (!source.matches({gameMode: 'creative'})) source.runCommandAsync(`clear @s arrow -1 1`);
        source.playSound('crossbow.loading.middle', {location: source.location});
        system.runTimeout(()=>{
          source.playSound('crossbow.quick_charge.middle', {location: source.location});
        }, 12);
        const item = new ItemStack("parasitesap:parasitic_crossbow_charged", 1);
        let durability = item.getComponent("minecraft:durability");
        
        if (enchantment) item.getComponent('enchantable')?.addEnchantments(enchantment);
        if (source.matches({gameMode: 'creative'})) {
          durability.damage = c;
          item.setLore([`§7${durability.maxDurability - durability.damage}/${durability.maxDurability}`]);
          item.nameTag = nombre;
          source.getComponent('inventory').container.setItem(source.selectedSlotIndex, item);
        }
        else if (!source.matches({gameMode: 'creative'})) {
          const durabi = item2?.getComponent("durability");
          const lvl = item2?.getComponent('enchantable').getEnchantment('unbreaking')?.level ?? 0;
          const breakingP = 100 / (lvl + 1);
          const breakingR = (Math.random() * 100);
          if (breakingP < breakingR) {
            durability.damage = c;
            item.setLore([`§7${durability.maxDurability - durability.damage}/${durability.maxDurability}`]);
            item.nameTag = nombre;
            source.getComponent('inventory').container.setItem(source.selectedSlotIndex, item);
            return;
          }
          else if (durabi.damage < durabi.maxDurability) {
            durability.damage = c+1;
          }
          else if (durabi.damage >= durabi.maxDurability) {
            source.getComponent('inventory').container.setItem(source.selectedSlotIndex, new ItemStack('minecraft:air'));
            source.playSound('random.break', source.location);
            return;
          }
          item.setLore([`§7${durability.maxDurability - durability.damage}/${durability.maxDurability}`]);
          item.nameTag = nombre;
          source.getComponent('inventory').container.setItem(source.selectedSlotIndex, item);
        }
      }
      for (let i = 0; i < inventory.size; i++) {
        const flecha = inventory.getItem(i);
        const offHand = source.getComponent("minecraft:equippable").getEquipmentSlot(`Offhand`).getItem();
        if (flecha?.typeId == "minecraft:arrow" && at == false) cargar();
        else if (offHand?.typeId === 'minecraft:arrow' && at == false) cargar();
        else if (source.matches({gameMode: 'creative'}) && at == false) cargar();
      }
    },
  });
  customC.itemComponentRegistry.registerCustomComponent("parasitesap:b_g", {
    onCompleteUse: g => {
      /*try {
        world.scoreboard.addObjective("flecha_parasitesap", "flecha_parasitesap");
      } catch (error){} finally{}*/
      const ballesta = "parasitic_crossbow_charged"
      const sisj = g.itemStack;
      const source = g.source;
      const encantamientos = sisj.getComponent('enchantable').getEnchantments();
      const nombre = sisj.nameTag;
      const c =sisj.getComponent('minecraft:durability').damage;
      dispararP(source, 'parasitesap:flecha', 8)
      //
      const multi = sisj.getComponent("enchantable")?.getEnchantment('multishot') ?? 0;
      const enchantment = sisj.getComponent("enchantable")?.getEnchantments();
      //
      if (multi !=0) {
        const sourceRot = source.getRotation();
        //
        const sp1 = source.dimension.spawnEntity('parasitesap:flecha', source.getHeadLocation());
        sp1.addTag('parasitesap:remover');
        const component1 = sp1.getComponent('minecraft:projectile');
        sp1.setRotation({x: sourceRot.x, y: sourceRot.y - 9.5})
        const view1 = sp1.getViewDirection();
        component1.owner = source;
        component1.shoot({x: view1.x*8, y: view.y*8, z: view1.z*8});
        //
        const sp2 = source.dimension.spawnEntity('parasitesap:flecha', source.getHeadLocation());
        sp2.addTag('parasitesap:remover');
        const component2 = sp2.getComponent('minecraft:projectile');
        sp2.setRotation({x: sourceRot.x, y: sourceRot.y + 9.5});
        const view2 = sp2.getViewDirection();
        component2.owner = source;
        component2.shoot({x: view2.x*8, y: view.y*8, z: view2.z*8});
        //
      }
      source.playSound('crossbow.shoot', {location: source.location});
      const item = new ItemStack('parasitesap:parasitic_crossbow', 1);
      //
      if (enchantment) item.getComponent('enchantable')?.addEnchantments(enchantment)
      //
      let durability = item.getComponent("minecraft:durability");
      durability.damage = c;
      item.nameTag = nombre;
      item.setLore([`§7${durability.maxDurability - durability.damage}/${durability.maxDurability}`]);
      source.getComponent('minecraft:inventory').container.setItem(source.selectedSlotIndex, item);
    },
  });
});

system.beforeEvents.watchdogTerminate.subscribe(et=>{
  et.cancel = true;
});

world.afterEvents.dataDrivenEntityTrigger.subscribe(s=>{
  const e = s.entity;
  const n = s.eventId;
  if (e.typeId === 'parasitesap:b_w') {
    if (n === 'parasitesap:explosion') {
      e.dimension.spawnParticle('parasitesap:explosion_de_sangre3', { x: e.location.x, y: e.location.y, z: e.location.z})
      const entity = e.dimension.getEntities({location:{ x: e.location.x, y: e.location.y, z: e.location.z},  maxDistance: 4});
      for (const ent of entity) {
        if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.startsWith('parasitesap:')) {
          ent.applyDamage(11);
          ent.addEffect('poison', timer.s*10);
        }
      }
      e.remove();
    }
  }
});

function salto(entidad, objetivo) {
    const posicionEntidad = entidad.location;
    const posicionObjetivo = objetivo.location;
    const dX = posicionObjetivo.x - posicionEntidad.x;
    const dZ = posicionObjetivo.z - posicionEntidad.z;
    const distanciaTotal = Math.sqrt(dX ** 2 + dZ ** 2);
    const fuerzaImpulso = distanciaTotal*0.16;
    entidad.applyImpulse({
      x: dX / distanciaTotal * fuerzaImpulso,
      y: +1.4,
      z: dZ / distanciaTotal * fuerzaImpulso
    });
}

/*function salto2(entidad, objetivo) {
  const posicionEntidad = entidad.location;
  const posicionObjetivo = objetivo.location;
  const distanciaX = posicionObjetivo.x - posicionEntidad.x;
  const distanciaY = posicionObjetivo.y - posicionEntidad.y;
  const distanciaZ = posicionObjetivo.z - posicionEntidad.z;
  const distanciaTotal = Math.sqrt(distanciaX ** 2 + distanciaY ** 2 + distanciaZ ** 2);
  const direccion = {
    x: distanciaX / distanciaTotal,
    y: distanciaY / distanciaTotal,
    z: distanciaZ / distanciaTotal
  };
  const fuerzaImpulso = distanciaTotal*0.15;
  entidad.applyImpulse({
    x: direccion.x * fuerzaImpulso,
    y: direccion.y * fuerzaImpulso +1.2,
    z: direccion.z * fuerzaImpulso
  });
}*/