<commit_before>package com.elmakers.mine.bukkit.action.builtin;

import com.elmakers.mine.bukkit.action.CompoundAction;
import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.effect.EffectPlay;
import com.elmakers.mine.bukkit.api.effect.EffectPlayer;
import com.elmakers.mine.bukkit.api.spell.Spell;
import com.elmakers.mine.bukkit.api.spell.SpellResult;
import com.elmakers.mine.bukkit.spell.BaseSpell;
import com.elmakers.mine.bukkit.utility.BoundingBox;
import com.elmakers.mine.bukkit.utility.CompatibilityUtils;
import de.slikey.effectlib.util.DynamicLocation;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class CustomProjectileAction extends CompoundAction
{
    private int interval;
    private int lifetime;
    private double speed;
    private int startDistance;
    private String projectileEffectKey;
    private String hitEffectKey;
    private String tickEffectKey;
    private boolean targetEntities;
    private double radius;
    private double gravity;
    private double drag;
    private double tickSize;
    private boolean reorient;
    private boolean useWandLocation;
    private boolean useEyeLocation;

    private boolean hasTickEffects;
    private long lastUpdate;
    private long nextUpdate;
    private long deadline;
    private boolean hit = false;
    private Vector velocity = null;
    private DynamicLocation effectLocation = null;
    private Collection<EffectPlay> activeProjectileEffects;

    private class CandidateEntity {
        public final Entity entity;
        public final BoundingBox bounds;

        public CandidateEntity(Entity entity) {
            this.entity = entity;
            this.bounds = CompatibilityUtils.getHitbox(entity).expand(radius);
        }
    }

    @Override
    public void prepare(CastContext context, ConfigurationSection parameters) {
        super.prepare(context, parameters);
        interval = parameters.getInt("interval", 1);
        lifetime = parameters.getInt("lifetime", 5000);
        speed = parameters.getDouble("speed", 0.1);
        startDistance = parameters.getInt("start", 0);
        projectileEffectKey = parameters.getString("projectile_effects", "projectile");
        hitEffectKey = parameters.getString("hit_effects", "hit");
        tickEffectKey = parameters.getString("tick_effects", "tick");
        targetEntities = parameters.getBoolean("target_entities", true);
        radius = parameters.getDouble("size", 1) / 2;
        gravity = parameters.getDouble("gravity", 0);
        drag = parameters.getDouble("drag", 0);
        tickSize = parameters.getDouble("tick_size", 0.5);
        hasTickEffects = context.getEffects(tickEffectKey).size() > 0;
        reorient = parameters.getBoolean("reorient", false);
        useWandLocation = parameters.getBoolean("use_wand_location", true);
        useEyeLocation = parameters.getBoolean("use_eye_location", true);
    }

    @Override
    public void reset(CastContext context)
    {
        super.reset(context);
        long now = System.currentTimeMillis();
        nextUpdate = 0;
        lastUpdate = now;
        deadline =  now + lifetime;
        hit = false;
        effectLocation = null;
        velocity = null;
        activeProjectileEffects = null;
    }

	@Override
	public SpellResult perform(CastContext context) {
        long now = System.currentTimeMillis();
        if (now < nextUpdate)
        {
            return SpellResult.PENDING;
        }
        if (now > deadline)
        {
            return hit(context);
        }
        if (hit)
        {
            return super.perform(context);
        }
        nextUpdate = now + interval;

        // Check for initialization required
        Location targetLocation = context.getTargetLocation();
        if (targetLocation == null) {
            if (useWandLocation) {
                targetLocation = context.getWandLocation().clone();
            } else if (useEyeLocation) {
                targetLocation = context.getEyeLocation().clone();
            } else {
                targetLocation = context.getLocation().clone();<commit_msg>Don't repeat hit FX when projectile is past its lifetime<commit_after>package com.elmakers.mine.bukkit.action.builtin;

import com.elmakers.mine.bukkit.action.CompoundAction;
import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.effect.EffectPlay;
import com.elmakers.mine.bukkit.api.effect.EffectPlayer;
import com.elmakers.mine.bukkit.api.spell.Spell;
import com.elmakers.mine.bukkit.api.spell.SpellResult;
import com.elmakers.mine.bukkit.spell.BaseSpell;
import com.elmakers.mine.bukkit.utility.BoundingBox;
import com.elmakers.mine.bukkit.utility.CompatibilityUtils;
import de.slikey.effectlib.util.DynamicLocation;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class CustomProjectileAction extends CompoundAction
{
    private int interval;
    private int lifetime;
    private double speed;
    private int startDistance;
    private String projectileEffectKey;
    private String hitEffectKey;
    private String tickEffectKey;
    private boolean targetEntities;
    private double radius;
    private double gravity;
    private double drag;
    private double tickSize;
    private boolean reorient;
    private boolean useWandLocation;
    private boolean useEyeLocation;

    private boolean hasTickEffects;
    private long lastUpdate;
    private long nextUpdate;
    private long deadline;
    private boolean hit = false;
    private Vector velocity = null;
    private DynamicLocation effectLocation = null;
    private Collection<EffectPlay> activeProjectileEffects;

    private class CandidateEntity {
        public final Entity entity;
        public final BoundingBox bounds;

        public CandidateEntity(Entity entity) {
            this.entity = entity;
            this.bounds = CompatibilityUtils.getHitbox(entity).expand(radius);
        }
    }

    @Override
    public void prepare(CastContext context, ConfigurationSection parameters) {
        super.prepare(context, parameters);
        interval = parameters.getInt("interval", 1);
        lifetime = parameters.getInt("lifetime", 5000);
        speed = parameters.getDouble("speed", 0.1);
        startDistance = parameters.getInt("start", 0);
        projectileEffectKey = parameters.getString("projectile_effects", "projectile");
        hitEffectKey = parameters.getString("hit_effects", "hit");
        tickEffectKey = parameters.getString("tick_effects", "tick");
        targetEntities = parameters.getBoolean("target_entities", true);
        radius = parameters.getDouble("size", 1) / 2;
        gravity = parameters.getDouble("gravity", 0);
        drag = parameters.getDouble("drag", 0);
        tickSize = parameters.getDouble("tick_size", 0.5);
        hasTickEffects = context.getEffects(tickEffectKey).size() > 0;
        reorient = parameters.getBoolean("reorient", false);
        useWandLocation = parameters.getBoolean("use_wand_location", true);
        useEyeLocation = parameters.getBoolean("use_eye_location", true);
    }

    @Override
    public void reset(CastContext context)
    {
        super.reset(context);
        long now = System.currentTimeMillis();
        nextUpdate = 0;
        lastUpdate = now;
        deadline =  now + lifetime;
        hit = false;
        effectLocation = null;
        velocity = null;
        activeProjectileEffects = null;
    }

	@Override
	public SpellResult perform(CastContext context) {
        long now = System.currentTimeMillis();
        if (now < nextUpdate)
        {
            return SpellResult.PENDING;
        }
        if (hit)
        {
            return super.perform(context);
        }
        if (now > deadline)
        {
            return hit(context);
        }
        nextUpdate = now + interval;

        // Check for initialization required
        Location targetLocation = context.getTargetLocation();
        if (targetLocation == null) {
            if (useWandLocation) {
                targetLocation = context.getWandLocation().clone();
            } else if (useEyeLocation) {
                targetLocation = context.getEyeLocation().clone();
            } else {
                targetLocation = context.getLocation().clone();
{'fraction_non_alphanumeric': 0.09383194618629574, 'fraction_numerical': 0.0036483867289932733, 'mean_word_length': 3.0238532110091745, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, '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': '2657235', 'n_tokens_mistral': 2366, 'n_tokens_neox': 2305, 'n_words': 536}