<commit_before>package info.faceland.strife.util;

import static info.faceland.strife.attributes.StrifeAttribute.HP_ON_HIT;
import static info.faceland.strife.util.StatUtil.getArmorMult;
import static info.faceland.strife.util.StatUtil.getFireResist;
import static info.faceland.strife.util.StatUtil.getIceResist;
import static info.faceland.strife.util.StatUtil.getLightningResist;
import static info.faceland.strife.util.StatUtil.getShadowResist;
import static info.faceland.strife.util.StatUtil.getWardingMult;

import com.tealcube.minecraft.bukkit.TextUtils;
import gyurix.spigotlib.ChatAPI;
import info.faceland.strife.StrifePlugin;
import info.faceland.strife.attributes.StrifeAttribute;
import info.faceland.strife.data.AttributedEntity;
import info.faceland.strife.events.BlockEvent;
import info.faceland.strife.events.CriticalEvent;
import info.faceland.strife.events.EvadeEvent;
import info.faceland.strife.managers.BlockManager;
import info.faceland.strife.managers.DarknessManager;
import java.util.Collection;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.material.MaterialData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

public class DamageUtil {

  private static final String ATTACK_MISSED = TextUtils.color("&f&lMiss!");
  private static final String ATTACK_BLOCKED = TextUtils.color("&f&lBlocked!");
  private static final String ATTACK_DODGED = TextUtils.color("&f&lDodge!");
  private static final Random RANDOM = new Random(System.currentTimeMillis());

  public static final int BLEED_TICK_RATE = 12;
  public static final int BLEED_TICKS_PER_5_SEC = (int) ((5D * 20D) / BLEED_TICK_RATE);

  public static double dealDirectDamage(AttributedEntity attacker, AttributedEntity defender,
      double damage, DamageType damageType) {
    LogUtil.printDebug("[Pre-Mitigation] Dealing " + damage + " of type " + damageType);
    switch (damageType) {
      case PHYSICAL:
        damage *= getArmorMult(attacker, defender);
        break;
      case MAGICAL:
        damage *= getWardingMult(attacker, defender);
        break;
      case FIRE:
        damage *= 1 - getFireResist(defender) / 100;
        break;
      case ICE:
        damage *= 1 - getIceResist(defender) / 100;
        break;
      case LIGHTNING:
        damage *= 1 - getLightningResist(defender) / 100;
        break;
      case DARK:
        damage *= 1 - getShadowResist(defender) / 100;
        break;
    }
    damage = StrifePlugin.getInstance().getBarrierManager().damageBarrier(defender, damage);
    defender.getEntity().setHealth(defender.getEntity().getHealth() - damage);
    defender.getEntity().damage(-1, attacker.getEntity());
    LogUtil.printDebug("[Post-Mitigation] Dealing " + damage + " of type " + damageType);
    return damage;
  }

  public static double attemptIgnite(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.IGNITE_CHANCE) / 100) {
      return 0D;
    }
    double bonusDamage = defender.getFireTicks() > 0 ? damage : 1D;
    defender.setFireTicks(Math.max(60 + (int) damage, defender.getFireTicks()));
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 1f, 1f);
    defender.getWorld()
        .spawnParticle(Particle.FLAME, defender.getEyeLocation(), 6 + (int) damage / 2,
            0.3, 0.3, 0.3, 0.03);
    return bonusDamage;
  }

  public static double attemptShock(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.SHOCK_CHANCE) / 100) {
      return 0D;
    }
    double multiplier = 0.5;
    double percentHealth =
        defender.getHealth() / defender.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
    if (percentHealth < 0.5) {
      multiplier = 1 / Math.max(0.16, percentHealth * 2);
    }
    double particles = damage * multiplier * 0.5;
    double particleRange = 0.8 + multiplier * 0.2;
    defender.getWorld()
        .playSound(defender.getEyeLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 0.7f, 2f);
    defender.getWorld()
        .spawnParticle(Particle.CRIT_MAGIC, defender.getEyeLocation(), 10 + (int) particles,
            particleRange, particleRange, particleRange, 0.12);
    if (defender instanceof Creeper) {
      ((Creeper) defender).setPowered(true);
    }
    return damage * multiplier;
  }

  public static double attemptFreeze(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.FREEZE_CHANCE) / 100) {
      return 0D;
    }
    double multiplier = 0.25 + 0.25 * (StatUtil.getHealth(attacker) / 100);
    if (!defender.hasPotionEffect(PotionEffectType.SLOW)) {
      defender.getActivePotionEffects().add(new PotionEffect(PotionEffectType.SLOW, 30, 1));
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.BLOCK_GLASS_BREAK, 1f, 1.0f);
    defender.getWorld()
        .spawnParticle(Particle.SNOWBALL, defender.getEyeLocation(), 4 + (int) damage / 2,
            0.3, 0.3, 0.2, 0.0);
    return damage * multiplier;
  }

  public static double consumeEarthRunes(double damage, AttributedEntity attacker, LivingEntity defender) {
    if (damage == 0) {
      return 0;
    }
    int runes = getBlockManager().getEarthRunes(attacker.getEntity().getUniqueId());
    getBlockManager().setEarthRunes(attacker.getEntity().getUniqueId(), 0);
    if (runes == 0) {
      return 0;
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.BLOCK_GRASS_BREAK, 1f, 0.8f);
    defender.getWorld().spawnParticle(
        Particle.BLOCK_CRACK,
        defender.getEyeLocation().clone().add(0, -0.7, 0),
        20,
        0.0, 0.0, 0.0,
        new MaterialData(Material.DIRT)
    );
    return damage * 0.5 * runes;
  }

  public static double getLightBonus(double damage, AttributedEntity attacker, LivingEntity defender) {
    if (damage == 0) {
      return 0;
    }
    double light = attacker.getEntity().getLocation().getBlock().getLightLevel();
    double multiplier = (light - 4) / 10;
    if (multiplier >= 0.5) {
      defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_FIREWORK_TWINKLE, 1f, 2f);
      defender.getWorld().spawnParticle(
          Particle.FIREWORKS_SPARK,
          defender.getEyeLocation(),
          (int)(8 * multiplier),
          0.4, 0.4, 0.5,
          0.18
      );
    }
    return damage * multiplier;
  }

  public static boolean attemptCorrupt(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0
        || rollDouble() >= attacker.getAttribute(StrifeAttribute.CORRUPT_CHANCE) / 100) {
      return false;
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_WITHER_SHOOT, 0.7f, 2f);
    defender.getWorld()
        .spawnParticle(Particle.SMOKE_NORMAL, defender.getEyeLocation(), 10, 0.4, 0.4, 0.5, 0.1);
    getDarknessManager().applyCorruptionStacks(defender, damage);
    return true;
  }

  public static void doEvasion(LivingEntity attacker, LivingEntity defender) {
    callEvadeEvent(defender, attacker);
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_GHAST_SHOOT, 0.5f, 2f);
    if (defender instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_DODGED, (Player) defender);
    }
    if (attacker instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_MISSED, (Player) attacker);
    }
  }

  public static void doBlock(LivingEntity attacker, LivingEntity defender) {
    callBlockEvent(defender, attacker);
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ITEM_SHIELD_BLOCK, 1f, 1f);
    if (defender instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_BLOCKED, (Player) defender);
    }
    if (attacker instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_BLOCKED, (Player) attacker);
    }
  }

  public static double getPotionMult(LivingEntity attacker, LivingEntity defender) {
    double potionMult = 1.0;
    Collection<PotionEffect> attackerEffects = attacker.getActivePotionEffects();
    Collection<PotionEffect> defenderEffects = defender.getActivePotionEffects();
    for (PotionEffect effect : attackerEffects) {
      if (effect.getType().equals(PotionEffectType.INCREASE_DAMAGE)) {
        potionMult += 0.1 * (effect.getAmplifier() + 1);
        continue;
      }
      if (effect.getType().equals(PotionEffectType.WEAKNESS)) {
        potionMult -= 0.1 * (effect.getAmplifier() + 1);
        continue;
      }
    }

    for (PotionEffect effect : defenderEffects) {
      if (effect.getType().equals(PotionEffectType.WITHER)) {
        potionMult += 0.15 * (effect.getAmplifier() + 1);
        continue;
      }
      if (effect.getType().equals(PotionEffectType.DAMAGE_RESISTANCE)) {
        potionMult -= 0.1 * (effect.getAmplifier() + 1);
        continue;<commit_msg>Updating block display to show earth runes stored<commit_after>package info.faceland.strife.util;

import static info.faceland.strife.attributes.StrifeAttribute.HP_ON_HIT;
import static info.faceland.strife.util.StatUtil.getArmorMult;
import static info.faceland.strife.util.StatUtil.getFireResist;
import static info.faceland.strife.util.StatUtil.getIceResist;
import static info.faceland.strife.util.StatUtil.getLightningResist;
import static info.faceland.strife.util.StatUtil.getShadowResist;
import static info.faceland.strife.util.StatUtil.getWardingMult;

import com.tealcube.minecraft.bukkit.TextUtils;
import gyurix.spigotlib.ChatAPI;
import info.faceland.strife.StrifePlugin;
import info.faceland.strife.attributes.StrifeAttribute;
import info.faceland.strife.data.AttributedEntity;
import info.faceland.strife.events.BlockEvent;
import info.faceland.strife.events.CriticalEvent;
import info.faceland.strife.events.EvadeEvent;
import info.faceland.strife.managers.BlockManager;
import info.faceland.strife.managers.DarknessManager;
import java.util.Collection;
import java.util.Random;
import java.util.stream.IntStream;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.material.MaterialData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

public class DamageUtil {

  private static final String ATTACK_MISSED = TextUtils.color("&f&lMiss!");
  private static final String ATTACK_BLOCKED = TextUtils.color("&f&lBlocked!");
  private static final String ATTACK_DODGED = TextUtils.color("&f&lDodge!");
  private static final Random RANDOM = new Random(System.currentTimeMillis());

  public static final int BLEED_TICK_RATE = 12;
  public static final int BLEED_TICKS_PER_5_SEC = (int) ((5D * 20D) / BLEED_TICK_RATE);

  public static double dealDirectDamage(AttributedEntity attacker, AttributedEntity defender,
      double damage, DamageType damageType) {
    LogUtil.printDebug("[Pre-Mitigation] Dealing " + damage + " of type " + damageType);
    switch (damageType) {
      case PHYSICAL:
        damage *= getArmorMult(attacker, defender);
        break;
      case MAGICAL:
        damage *= getWardingMult(attacker, defender);
        break;
      case FIRE:
        damage *= 1 - getFireResist(defender) / 100;
        break;
      case ICE:
        damage *= 1 - getIceResist(defender) / 100;
        break;
      case LIGHTNING:
        damage *= 1 - getLightningResist(defender) / 100;
        break;
      case DARK:
        damage *= 1 - getShadowResist(defender) / 100;
        break;
    }
    damage = StrifePlugin.getInstance().getBarrierManager().damageBarrier(defender, damage);
    defender.getEntity().setHealth(defender.getEntity().getHealth() - damage);
    defender.getEntity().damage(-1, attacker.getEntity());
    LogUtil.printDebug("[Post-Mitigation] Dealing " + damage + " of type " + damageType);
    return damage;
  }

  public static double attemptIgnite(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.IGNITE_CHANCE) / 100) {
      return 0D;
    }
    double bonusDamage = defender.getFireTicks() > 0 ? damage : 1D;
    defender.setFireTicks(Math.max(60 + (int) damage, defender.getFireTicks()));
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 1f, 1f);
    defender.getWorld()
        .spawnParticle(Particle.FLAME, defender.getEyeLocation(), 6 + (int) damage / 2,
            0.3, 0.3, 0.3, 0.03);
    return bonusDamage;
  }

  public static double attemptShock(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.SHOCK_CHANCE) / 100) {
      return 0D;
    }
    double multiplier = 0.5;
    double percentHealth =
        defender.getHealth() / defender.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
    if (percentHealth < 0.5) {
      multiplier = 1 / Math.max(0.16, percentHealth * 2);
    }
    double particles = damage * multiplier * 0.5;
    double particleRange = 0.8 + multiplier * 0.2;
    defender.getWorld()
        .playSound(defender.getEyeLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 0.7f, 2f);
    defender.getWorld()
        .spawnParticle(Particle.CRIT_MAGIC, defender.getEyeLocation(), 10 + (int) particles,
            particleRange, particleRange, particleRange, 0.12);
    if (defender instanceof Creeper) {
      ((Creeper) defender).setPowered(true);
    }
    return damage * multiplier;
  }

  public static double attemptFreeze(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0 || rollDouble() >= attacker.getAttribute(StrifeAttribute.FREEZE_CHANCE) / 100) {
      return 0D;
    }
    double multiplier = 0.25 + 0.25 * (StatUtil.getHealth(attacker) / 100);
    if (!defender.hasPotionEffect(PotionEffectType.SLOW)) {
      defender.getActivePotionEffects().add(new PotionEffect(PotionEffectType.SLOW, 30, 1));
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.BLOCK_GLASS_BREAK, 1f, 1.0f);
    defender.getWorld()
        .spawnParticle(Particle.SNOWBALL, defender.getEyeLocation(), 4 + (int) damage / 2,
            0.3, 0.3, 0.2, 0.0);
    return damage * multiplier;
  }

  public static double consumeEarthRunes(double damage, AttributedEntity attacker, LivingEntity defender) {
    if (damage == 0) {
      return 0;
    }
    int runes = getBlockManager().getEarthRunes(attacker.getEntity().getUniqueId());
    getBlockManager().setEarthRunes(attacker.getEntity().getUniqueId(), 0);
    if (runes == 0) {
      return 0;
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.BLOCK_GRASS_BREAK, 1f, 0.8f);
    defender.getWorld().spawnParticle(
        Particle.BLOCK_CRACK,
        defender.getEyeLocation().clone().add(0, -0.7, 0),
        20,
        0.0, 0.0, 0.0,
        new MaterialData(Material.DIRT)
    );
    return damage * 0.5 * runes;
  }

  public static double getLightBonus(double damage, AttributedEntity attacker, LivingEntity defender) {
    if (damage == 0) {
      return 0;
    }
    double light = attacker.getEntity().getLocation().getBlock().getLightLevel();
    double multiplier = (light - 4) / 10;
    if (multiplier >= 0.5) {
      defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_FIREWORK_TWINKLE, 1f, 2f);
      defender.getWorld().spawnParticle(
          Particle.FIREWORKS_SPARK,
          defender.getEyeLocation(),
          (int)(8 * multiplier),
          0.4, 0.4, 0.5,
          0.18
      );
    }
    return damage * multiplier;
  }

  public static boolean attemptCorrupt(double damage, AttributedEntity attacker,
      LivingEntity defender) {
    if (damage == 0
        || rollDouble() >= attacker.getAttribute(StrifeAttribute.CORRUPT_CHANCE) / 100) {
      return false;
    }
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_WITHER_SHOOT, 0.7f, 2f);
    defender.getWorld()
        .spawnParticle(Particle.SMOKE_NORMAL, defender.getEyeLocation(), 10, 0.4, 0.4, 0.5, 0.1);
    getDarknessManager().applyCorruptionStacks(defender, damage);
    return true;
  }

  public static void doEvasion(LivingEntity attacker, LivingEntity defender) {
    callEvadeEvent(defender, attacker);
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ENTITY_GHAST_SHOOT, 0.5f, 2f);
    if (defender instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_DODGED, (Player) defender);
    }
    if (attacker instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_MISSED, (Player) attacker);
    }
  }

  public static void doBlock(LivingEntity attacker, LivingEntity defender) {
    callBlockEvent(defender, attacker);
    defender.getWorld().playSound(defender.getEyeLocation(), Sound.ITEM_SHIELD_BLOCK, 1f, 1f);
    String defenderBar = ATTACK_BLOCKED;
    int runes = getBlockManager().getEarthRunes(defender.getUniqueId());
    if (runes > 0) {
      StringBuilder sb = new StringBuilder(defenderBar);
      sb.append("&2 ").append(IntStream.range(0, runes).mapToObj(i -> "▼"));
      defenderBar = sb.toString();
    }
    if (defender instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, defenderBar, (Player) defender);
    }
    if (attacker instanceof Player) {
      ChatAPI.sendJsonMsg(ChatAPI.ChatMessageType.ACTION_BAR, ATTACK_BLOCKED, (Player) attacker);
    }
  }

  public static double getPotionMult(LivingEntity attacker, LivingEntity defender) {
    double potionMult = 1.0;
    Collection<PotionEffect> attackerEffects = attacker.getActivePotionEffects();
    Collection<PotionEffect> defenderEffects = defender.getActivePotionEffects();
    for (PotionEffect effect : attackerEffects) {
      if (effect.getType().equals(PotionEffectType.INCREASE_DAMAGE)) {
        potionMult += 0.1 * (effect.getAmplifier() + 1);
        continue;
      }
      if (effect.getType().equals(PotionEffectType.WEAKNESS)) {
        potionMult -= 0.1 * (effect.getAmplifier() + 1);
        continue;
      }
    }

    for (PotionEffect effect : defenderEffects) {
      if (effect.getType().equals(PotionEffectType.WITHER)) {
        potionMult += 0.15 * (effect.getAmplifier() + 1);
        continue;
      }
      if (effect.getType().equals(PotionEffectType.DAMAGE_RESISTANCE)) {
        potionMult -= 0.1 * (effect.getAmplifier() + 1);
        continue;
{'fraction_non_alphanumeric': 0.11760386067981536, 'fraction_numerical': 0.01914603441040705, 'mean_word_length': 3.7027627035027133, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '252657', 'n_tokens_mistral': 6556, 'n_tokens_neox': 6054, 'n_words': 1167}