Package games.stendhal.server.entity.creature.impl.attack

Source Code of games.stendhal.server.entity.creature.impl.attack.RangeAttack

/* $Id: RangeAttack.java,v 1.3 2011/02/11 17:14:37 kiheru Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.entity.creature.impl.attack;

import games.stendhal.common.MathHelper;
import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.entity.RPEntity;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.Entity;

public class RangeAttack implements AttackStrategy {
  /** Maximum range at which the archer will consider a target valid, squared. */
  private static final int MAX_RANGE_SQUARED = 144;
  /** Archer range, if not specified otherwise. */
  private static final int DEFAULT_RANGE = 7;
  private final int range;
 
  RangeAttack(String range) {
    this.range = MathHelper.parseIntDefault(range, DEFAULT_RANGE);
  }

  public void attack(final Creature creature) {

    if ((SingletonRepository.getRuleProcessor().getTurn() % 5 == creature.getAttackTurn())) {
      creature.attack();
      creature.tryToPoison();
    }
  }

  public boolean canAttackNow(final Creature creature) {
    if (creature.getAttackTarget() != null) {

      return !((creature.squaredDistance(creature.getAttackTarget()) > range * range) || creature.getZone().collidesOnLine(creature.getX(),
          creature.getY(), creature.getAttackTarget().getX(), creature.getAttackTarget().getY()));
    } else {
      return false;
    }
  }

  public void findNewTarget(final Creature creature) {
    final RPEntity enemy = creature.getNearestEnemy(creature.getPerceptionRange()+2);
    if (enemy != null) {
      creature.setTarget(enemy);
    }
  }

  public void getBetterAttackPosition(final Creature creature) {
    final Entity target = creature.getAttackTarget();
    final double distance = creature.squaredDistance(target);
    // if too far away from enemy
    if (distance > longRangeSquared()) {
      creature.setMovement(target, 0, 1, creature.getMovementRange());
      creature.faceToward(creature.getAttackTarget());
    // if too close to enemy
    } else if (distance < shortRangeSquared()) {
      // turn creature around
      creature.faceToward(creature.getAttackTarget());
      creature.setDirection(creature.getDirection().oppositeDirection());
      // check if creature cant move away from enemy
      if (creature.getZone().collides(creature, creature.getX() + creature.getDirection().getdx(), creature.getY() + creature.getDirection().getdy(), true)) {
        if (!canAttackNow(creature)) {
          // go back to enemy
          creature.setMovement(target, 0, 1, creature.getMovementRange()*0.75);
          creature.faceToward(creature.getAttackTarget());
        } else {
          // will attack from here
          creature.clearPath();
          creature.stop();
          creature.faceToward(creature.getAttackTarget());
        }
      } else {
        // give to creature good kick
        creature.setSpeed(creature.getBaseSpeed());
      }
    // good distance to attack
    } else {
      // cant attack enemy, going to him
      if (!canAttackNow(creature)) {
        creature.setMovement(target, 0, 1, creature.getMovementRange());
        creature.faceToward(creature.getAttackTarget());
      } else {
        // this is good position to attack enemy
        creature.clearPath();
        creature.stop();
        creature.faceToward(creature.getAttackTarget());
      }
    }
  }

  public boolean hasValidTarget(final Creature creature) {
    if (!creature.isAttacking()) {
      return false;
    }

    final RPEntity victim = creature.getAttackTarget();
    if (victim.isInvisibleToCreatures()) {
      return false;
    }
    if (!victim.getZone().equals(creature.getZone())) {
      return false;
    }

    if (!creature.getZone().has(victim.getID())) {
      return false;
    }
    return creature.squaredDistance(victim) < MAX_RANGE_SQUARED;
  }

  /**
   * Get the shortest range that is considered optimal.
   *
   * @return shortest optimal range
   */
  private int shortRangeSquared() {
    int tmp = range / 2 + (range % 2);
   
    return tmp * tmp;
  }
 
  /**
   * Get the longest range that is considered optimal.
   *
   * @return longest optimal range
   */
  private int longRangeSquared() {
    int tmp = range / 2 + (range % 2) + 1;
   
    return tmp * tmp;
  }
 
  public int getRange() {
    return range;
  }
}
TOP

Related Classes of games.stendhal.server.entity.creature.impl.attack.RangeAttack

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.