<commit_before>package BluebellAdventures.Actions;

import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import BluebellAdventures.Characters.Character;
import BluebellAdventures.Characters.Enemy;
import BluebellAdventures.Characters.GameMap;

import Megumin.Actions.MoveTo;
import Megumin.Nodes.Director;
import Megumin.Nodes.Scene;
import Megumin.Nodes.Sprite;
import Megumin.Point;

public class EnemyMove extends MoveTo {
    private CopyOnWriteArrayList<CopyOnWriteArrayList<Sprite>> sprites;
    private Point position;
    private Point size;
    private int speed;
    private int mode;
    private Sprite characterSprite;
    private int[] possibleDirection;
    private Random random;
    private Sprite chaseArea;

    public EnemyMove(int speed, Point position, Point size) {
        super(speed, 0);
        this.speed = speed;
        this.position = position;
        this.size = size;
        sprites = new CopyOnWriteArrayList<>();
        mode = 0;
        possibleDirection = new int[]{-1, 0, 1};
        random = new Random();

        //create chase detection area
        chaseArea = new Enemy();
        chaseArea.setPosition(position);
        chaseArea.setSize(size);
    }

    public void addSprites(CopyOnWriteArrayList<Sprite> sprites){
        this.sprites.add(sprites);
    }

    @Override
    public void update(Sprite sprite) {
        int[] direction = sprite.getDirection();
        int x = sprite.getPosition().getX() + direction[0] * speed;
        int y = sprite.getPosition().getY() + direction[1] * speed;
        int w = sprite.getSize().getX();
        int h = sprite.getSize().getY();

        // In Pursuit
        if (mode == 1) {
            Point characterPosition = GameMap.getInstance().getPosition();

            if (sprite.getPosition().getX() > -characterPosition.getX() + characterSprite.getPosition().getX()) {
                direction[0] = -1;
            } else {
                direction[0] = 1;
            }

            if (sprite.getPosition().getY() > -characterPosition.getY() + characterSprite.getPosition().getY()) {
                direction[1] = -1;
            } else {
                direction[1] = 1;
            }

            setX(direction[0] * speed);
            setY(direction[1] * speed);

            if (GameMap.enemyCrash(sprite, direction[0] * speed, direction[1] * speed)) {
                direction[0] = possibleDirection[random.nextInt(3)];
                direction[1] = possibleDirection[random.nextInt(3)];
                while (direction[0] == 0 && direction[1] == 0) {
                    direction[0] = possibleDirection[random.nextInt(3)];
                    direction[1] = possibleDirection[random.nextInt(3)];
                }
                setX(direction[0] * speed);
                setY(direction[1] * speed);
            } else {
                super.update(sprite);
            }
            if ((x + w) > position.getX() + size.getX()
                || (y + h) > position.getY() + size.getY()
                || x < position.getX()
                || y < position.getY()) {
                mode = 0;
            } 
        }

        // Patrolling
        if (mode == 0){
            if (GameMap.enemyCrash(sprite, direction[0] * speed, direction[1] * speed)
                || (x + w) > position.getX() + size.getX()
                || (y + h) > position.getY() + size.getY()
                || x < position.getX()
                || y < position.getY()) {
                direction[0] = possibleDirection[random.nextInt(3)];
                direction[1] = possibleDirection[random.nextInt(3)];
                while (direction[0] == 0 && direction[1] == 0) {
                    direction[0] = possibleDirection[random.nextInt(3)];
                    direction[1] = possibleDirection[random.nextInt(3)];
                }

                setX(direction[0] * speed);
                setY(direction[1] * speed);
            }
            else {
                super.update(sprite);
            }<commit_msg>smooth enemy move<commit_after>package BluebellAdventures.Actions;

import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import BluebellAdventures.Characters.Character;
import BluebellAdventures.Characters.Enemy;
import BluebellAdventures.Characters.GameMap;

import Megumin.Actions.MoveTo;
import Megumin.Nodes.Director;
import Megumin.Nodes.Scene;
import Megumin.Nodes.Sprite;
import Megumin.Point;

public class EnemyMove extends MoveTo {
    private CopyOnWriteArrayList<CopyOnWriteArrayList<Sprite>> sprites;
    private Point position;
    private Point size;
    private int speed;
    private int mode;
    private Sprite characterSprite;
    private int[] possibleDirection;
    private Random random;
    private Sprite chaseArea;

    public EnemyMove(int speed, Point position, Point size) {
        super(speed, 0);
        this.speed = speed;
        this.position = position;
        this.size = size;
        sprites = new CopyOnWriteArrayList<>();
        mode = 0;
        possibleDirection = new int[]{-1, 0, 1};
        random = new Random();

        //create chase detection area
        chaseArea = new Enemy();
        chaseArea.setPosition(position);
        chaseArea.setSize(size);
    }

    public void addSprites(CopyOnWriteArrayList<Sprite> sprites){
        this.sprites.add(sprites);
    }

    @Override
    public void update(Sprite sprite) {
        System.out.println(mode);
        int[] direction = sprite.getDirection();
        int x = sprite.getPosition().getX() + direction[0] * speed;
        int y = sprite.getPosition().getY() + direction[1] * speed;
        int w = sprite.getSize().getX();
        int h = sprite.getSize().getY();
        boolean walkable = false;

        // In Pursuit
        if (mode == 1) {
            Point characterPosition = GameMap.getInstance().getPosition();

            if (sprite.getPosition().getX() - characterSprite.getSize().getX() > -characterPosition.getX() + characterSprite.getPosition().getX()) {
                direction[0] = -1;
            }
            else if (sprite.getPosition().getX() + characterSprite.getSize().getX() < -characterPosition.getX() + characterSprite.getPosition().getX()) {
                direction[0] = 1;
            }
            else {
                direction[0] = 0;
            }

            if (sprite.getPosition().getY() - characterSprite.getSize().getY() > -characterPosition.getY() + characterSprite.getPosition().getY()) {
                direction[1] = -1;
            }
            else if (sprite.getPosition().getY() + characterSprite.getSize().getY() < -characterPosition.getY() + characterSprite.getPosition().getY()) {
                direction[1] = 1;
            }
            else {
                direction[1] = 0;
            }

            setX(direction[0] * speed);
            setY(direction[1] * speed);

            boolean xCrash = GameMap.enemyCrash(sprite, direction[0] * speed, 0);
            boolean yCrash = GameMap.enemyCrash(sprite, 0, direction[1] * speed);
            if (xCrash || yCrash) {
                if (xCrash && !yCrash) {
                    setX(0);
                    if (sprite.getPosition().getY() > -characterPosition.getY() + characterSprite.getPosition().getY()) {
                        setY(-1 * speed);
                    }
                    else if (sprite.getPosition().getY() <= -characterPosition.getY() + characterSprite.getPosition().getY()) {
                        setY(1 * speed);
                    }
                }
                else if (!xCrash && yCrash) {
                    if (sprite.getPosition().getX() > -characterPosition.getX() + characterSprite.getPosition().getX()) {
                        setX(-1 * speed);
                    }
                    else if (sprite.getPosition().getX() <= -characterPosition.getX() + characterSprite.getPosition().getX()) {
                        setX(1 * speed);
                    }
                    setY(0);
                }
                else if (xCrash && yCrash) {
                    setX(-direction[0] * speed);
                    setY(-direction[1] * speed);
                }
                walkable = true;
            } else {
                walkable = true;
            }
            if ((x + w) + direction[0] * speed > position.getX() + size.getX()
                || (y + h) + direction[1] * speed > position.getY() + size.getY()
                || x + direction[0] * speed < position.getX()
                || y + direction[1] * speed < position.getY()) {
                mode = 0;
            } 
        }

        // Patrolling
        if (mode == 0){
            if (GameMap.enemyCrash(sprite, direction[0] * speed, direction[1] * speed)
                || (x + w) + direction[0] * speed > position.getX() + size.getX()
                || (y + h) + direction[1] * speed > position.getY() + size.getY()
                || x + direction[0] * speed < position.getX()
                || y + direction[1] * speed < position.getY()) {
                direction[0] = possibleDirection[random.nextInt(3)];
                direction[1] = possibleDirection[random.nextInt(3)];
                while (direction[0] == 0 && direction[1] == 0) {
                    direction[0] = possibleDirection[random.nextInt(3)];
                    direction[1] = possibleDirection[random.nextInt(3)];
                }

                setX(direction[0] * speed);
                setY(direction[1] * speed);
            }
            else {
                walkable = true;
            }
        }

        if (walkable) {
            super.update(sprite);
{'fraction_non_alphanumeric': 0.12903891813771035, 'fraction_numerical': 0.011561887065138846, 'mean_word_length': 1.7991909852643744, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, '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': '1878590', 'n_tokens_mistral': 2797, 'n_tokens_neox': 2660, 'n_words': 544}