/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2017 Grégory Van den Borre
 *
 * More infos available: https://www.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

package be.yildiz.shared.entity.action;

import be.yildiz.common.id.EntityId;
import be.yildiz.common.vector.Point3D;
import be.yildiz.shared.entity.fields.Target;
import lombok.Setter;

import java.util.Optional;

/**
 * @author Grégory Van den Borre
 */
public final class Follow extends Action {

    private final Move move;

    private Optional<Target> target;

    @Setter
    private float distance;

    /**
     * Create a new Follow action.
     *
     * @param move   Move action used to follow a target.
     * @param entity Entity doing this action.
     */
    public Follow(final Move move, final EntityId entity) {
        super(entity, false);
        this.move = move;
        this.target = Optional.empty();
    }

    @Override
    public boolean checkPrerequisite() {
        return this.target.isPresent() && !this.target.get().isZeroHp();
    }

    @Override
    public void runImpl(final long time) {
        this.target.ifPresent(t -> {
            this.move.setDestination(t.getPosition());
            this.move.run(time);
        });
    }

    @Override
    public void setTarget(final Target target) {
        this.target = Optional.of(target);
    }

    @Override
    public Point3D getDestination() {
        return this.target.get().getPosition();
    }

    @Override
    public void setDestination(final Point3D destination) {
    }

    @Override
    public EntityId getTargetId() {
        return this.target.get().getId();
    }

    @Override
    public void stopImpl() {
        this.move.stop();
    }

    @Override
    public void initImpl() {
        this.move.init();
        this.move.setDistance(this.distance);
    }

    @Override
    public void delete() {

    }
}

@@ -1607,24 +1607,14 @@
 ate 
-Optional%3C
 Target
-%3E
  tar
@@ -1943,48 +1943,8 @@
 ve;%0A
-        this.target = Optional.empty();%0A
     
@@ -2031,20 +2031,16 @@
 rget
-.isPresent()
+ != null
  && 
@@ -2052,22 +2052,16 @@
 .target.
-get().
 isZeroHp
@@ -2128,32 +2128,52 @@
 time) %7B%0A        
+Optional.ofNullable(
 this.target.ifPr
@@ -2167,16 +2167,17 @@
 s.target
+)
 .ifPrese
@@ -2382,27 +2382,14 @@
 t = 
-Optional.of(
 target
-)
 ;%0A  
@@ -2460,32 +2460,90 @@
  return 
-this.target.get(
+Optional.ofNullable(this.target).orElseThrow(IllegalArgumentException::new
 ).getPos
@@ -2628,24 +2628,43 @@
 tination) %7B%0A
+        // Unused.%0A
     %7D%0A%0A    @
@@ -2727,24 +2727,82 @@
 urn 
-this.target.get(
+Optional.ofNullable(this.target).orElseThrow(IllegalArgumentException::new
 ).ge
@@ -3054,16 +3054,33 @@
 ete() %7B%0A
+        //Unused.
 %0A    %7D%0A%7D

Improve optional usage.