Package de.creepsmash.client.tower

Source Code of de.creepsmash.client.tower.AbstractTower

/**
   Creep Smash, a multiplayer towerdefence game
   created as a project at the Hochschule fuer
   Technik Stuttgart (University of Applied Science)
   http://www.hft-stuttgart.de
  
   Copyright (C) 2008 by     
    * Andreas Wittig
    * Bernd Hietler
    * Christoph Fritz
    * Fabian Kessel
    * Levin Fritz
    * Nikolaj Langner
    * Philipp Schulte-Hubbert
    * Robert Rapczynski
    * Ron Trautsch
    * Sven Supper
    http://creepsmash.sf.net/

    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 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/


package de.creepsmash.client.tower;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import de.creepsmash.client.creep.Creep;
import de.creepsmash.client.creep.Creep.DamageType;
import de.creepsmash.client.game.GameContext;
import de.creepsmash.client.game.PlayerContext;
import de.creepsmash.client.grid.Grid;
import de.creepsmash.client.sound.SoundManagement;
import de.creepsmash.client.util.Cache;
import de.creepsmash.common.IConstants;

/**
* Implements the basic methods for a tower.
*
* @author Philipp
*
*/
public abstract class AbstractTower implements Tower {
  private IConstants.Towers type;
  private GameContext context;
  private boolean selected = false;
  private int price;
  private int totalPrice;

  private int coolDown;
  private int coolDownNow = 0;

  private int id;

  //private int level;
  private int damage;
  private int damageNow;
  private DamageType damageType;
  private double slowRate;
  private int slowTime;

  private int splashRadius;
  // reduction of the damage
  // the damage at the radius is 1 - damageReductionAtRadius
  private double damageReductionAtRadius;

  private float range;

  private Grid grid;

  //private Color buildColor = new Color(255, 200, 0);
  private Color towerColor;

  private int buildTime;
  private boolean building;
  private int upgradeTime;
  private int sellTime;
  private int changeStrategyTime;
  private boolean active = false;
  private boolean upgrading = false;
  private boolean selling = false;
  private boolean changingStrategy = false;

  private BufferedImage image;

  private AffineTransform translation = new AffineTransform();

  private Creep target = null;
  private ArrayList<Creep> targets = new ArrayList<Creep>();

  public static boolean ALPHA = false;

  private AlphaComposite myAlpha = AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, 0.1f);
  private AlphaComposite noAlpha = AlphaComposite.getInstance(
      AlphaComposite.SRC_OVER, 1.0f);

  private FindCreepStrategy strategy;
  private FindCreepStrategy selectedStrategy;

  /**
   * SoundManagement is public because every kind of tower calculates on its
   * own when/if it shoots. So sound has to played there.
   */
  SoundManagement sound;

  /**
   * @return the strategy
   */
  public FindCreepStrategy getStrategy() {
    return strategy;
  }

  /**
   * @param strategy
   *            the strategy to set
   */
  public void setStrategy(FindCreepStrategy strategy) {
    this.strategy = strategy;
  }

  /**
   * @return the sellTime
   */
  public int getSellTime() {
    return sellTime;
  }

  /**
   * @param sellTime
   *            the sellTime to set
   */
  public void setSellTime(int sellTime) {
    this.sellTime = sellTime;
  }
 
  public void setSelectedStrategy(FindCreepStrategy fcs) {
    this.selectedStrategy = fcs;
    this.changingStrategy = true;
  }
 
  /**
   * This method is used to update the panel info.
   * @param fcs
   */
  public void UpdateSelectedStrategy(FindCreepStrategy fcs) {
    this.selectedStrategy = fcs;
  }
 
  /**
   * @return gets the selected strategy
   */
  public FindCreepStrategy getSelectedStrategy() {
    return this.selectedStrategy;
  }
 
  /**
   *
   * @return gets the change strategy time
   */
  public int getChangeStrategyTime() {
    return this.changeStrategyTime;
  }
  /**
   *
   * @param changeTime sets the change time for the strategy
   */
  public void setChangeStrategyTime(int changeTime) {
    this.changeStrategyTime = changeTime;
  }
 
  /**
   * @return the targets
   */
  public ArrayList<Creep> getTargets() {
    return targets;
  }

  /**
   * @param targets
   *            the targets to set
   */
  public void setTargets(ArrayList<Creep> targets) {
    this.targets = targets;
  }

  /**
   * @return the splashRadius
   */
  public int getSplashRadius() {
    return splashRadius;
  }

  /**
   * @param splashRadius
   *            the splashRadius to set
   */
  public void setSplashRadius(int splashRadius) {
    this.splashRadius = splashRadius;
  }

  /**
   * @return the damageReductionAtRadius
   */
  public double getDamageReductionAtRadius() {
    return damageReductionAtRadius;
  }

  /**
   * @param damageReductionAtRadius
   *            the damageReductionAtRadius to set
   */
  public void setDamageReductionAtRadius(double damageReductionAtRadius) {
    this.damageReductionAtRadius = damageReductionAtRadius;
  }

  /**
   * @return the slowDamage
   */
  public double getSlowRate() {
    return slowRate;
  }

  /**
   * @param slowRate
   *            the slowDamage to set
   */
  public void setSlowRate(double slowRate) {
    this.slowRate = slowRate;
  }

  /**
   * @return the damageType
   */
  public DamageType getDamageType() {
    return damageType;
  }

  /**
   * @param damageType
   *            the damageType to set
   */
  public void setDamageType(DamageType damageType) {
    this.damageType = damageType;
  }

  /**
   * @return the totalPrice
   */
  public int getTotalPrice() {
    return totalPrice;
  }

  /**
   * @param totalPrice
   *            the totalPrice to set
   */
  public void setTotalPrice(int totalPrice) {
    this.totalPrice = totalPrice;
  }

  /**
   * Creates a new instance of AbstractTower.
   *
   * @param context
   *            the gameContext for the tower
   * @param type
   *            the type of the tower
   * @param grid
   *            the grid where the tower is placed
   */
  protected AbstractTower(IConstants.Towers type, GameContext context,
      Grid grid) {
    this.setBuilding(false);
    this.buildTime = IConstants.USER_ACTION_DELAY;
    this.upgradeTime = 0;
      this.changeStrategyTime = 0;
    this.context = context;
    this.setType(type);
    this.grid = grid;
    grid.setTower(this);
    this.towerColor = type.getTowerColor();
    this.active = false;
    init();

    if (Cache.getInstance().hasArrayTowerImg(this.getType())) {
      this.setImage(Cache.getInstance().getTowerImg(this.getType()));
    } else {
      this.image = new BufferedImage(20, 20,
          BufferedImage.TYPE_INT_ARGB_PRE);
      generateImage();
      Cache.getInstance().putTowerImg(this.getType(), this.getImage());
    }
    this.translation.setToIdentity();
    this.translation
        .translate(grid.getLocation()[0], grid.getLocation()[1]);

    this.sound = context.getSoundManagement();

   
    this.setDamage(type.getDamage());
    this.setDamageNow(type.getDamage());
    this.setRange(type.getRange());
    this.setCoolDown(type.getSpeed());
    this.setTotalPrice(type.getPrice());
    this.setDamageType(type.getDamageType());
    this.setSplashRadius(type.getSplashRadius());
    this.setDamageReductionAtRadius(type.getDamageReductionAtRadius());
    this.setSlowRate(type.getSlowRate());
    this.setSlowTime(type.getSlowTime());
  }

  /**
   * Init method for tower creation.
   */
  protected abstract void init();

  /**
   * @return the slowTime
   */
  public int getSlowTime() {
    return slowTime;
  }

  /**
   * @param slowTime
   *            the slowTime to set
   */
  public void setSlowTime(int slowTime) {
    this.slowTime = slowTime;
  }
 
  /**
   * {@inheritDoc}
   */
  public void setId(int id) {
    this.id = id;
  }

  /**
   * {@inheritDoc}
   */
  public int getId() {
    return this.id;
  }

  /**
   * {@inheritDoc}
   */
  public String getStatus() {
    return "";
  }

  /**
   * {@inheritDoc}
   */
  public int getSellValue() {
    // TODO Auto-generated method stub

    return 0;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isUpgradable() {
    if (this.type.getNext() == null) {
      return false;
    } else {
      return true;
    }
  }

  /**
   * Creates the image for the tower.
   */
  public abstract void generateImage();

  /**
   * {@inheritDoc}
   */
  public void paint(Graphics2D g) {

    AffineTransform save = g.getTransform();

    g.transform(translation);

    g.drawImage(image, 0, 0, null);

    g.setTransform(save);
  }

  /**
   * {@inheritDoc}
   */
  public void paintEffect(Graphics2D g) {
    AffineTransform save = g.getTransform();

    g.transform(translation);

    if (isSelected()) {
      g.setColor(Color.YELLOW);
      Arc2D rangeArc = new Arc2D.Float();
      rangeArc.setArcByCenter(Grid.SIZE / 2, Grid.SIZE / 2, this.range,
          0.0, 360.0, Arc2D.CHORD);

      if (ALPHA) {
        g.setComposite(myAlpha);
        g.fill(rangeArc);
        g.setComposite(noAlpha);
      }

      g.draw(rangeArc);

      g.drawRect(0, 0, Grid.SIZE, Grid.SIZE);
    }

    // works only if a client does not lag too much
    // or the build time can be bigger than USER_ACTION_DELAY
    if (this.buildTime > 0) {
     
      g.setColor(Color.BLACK);
      g.fillRect(20 - 20 * this.buildTime / IConstants.USER_ACTION_DELAY,
          1, 20 * this.buildTime / IConstants.USER_ACTION_DELAY, 19);
    }

    if (this.upgradeTime > 0) {
      g.setColor(Color.BLUE);
      g.fillRect(1, 1, 20 * this.upgradeTime
          / IConstants.USER_ACTION_DELAY, 3);
    }

    if (this.sellTime > 0) {
      g.setColor(Color.RED);
      g.fillRect(1, 1, 20 * this.sellTime / IConstants.USER_ACTION_DELAY,3);
    }
   
    if (this.changeStrategyTime > 0) {
      g.setColor(Color.ORANGE);
      g.fillRect(1, 1, 20 * this.changeStrategyTime / IConstants.USER_ACTION_DELAY,3);
    }

    g.setTransform(save);
  }

  /**
   * {@inheritDoc}
   */
  public void update(long tickNumber) {
    // upgrade and build animation
    if (this.buildTime > 0) {
      if (isBuilding()) {
        this.buildTime--;
        if (this.buildTime == 0) {
          this.active = true;
          this.grid.setOccupiedStatus(false);
        }
      }
    }

    if (!this.isActive()) {
      return;
    }
   
    // strategy change update
    if (this.changeStrategyTime > 0) {
      this.changeStrategyTime--;
      if (this.changeStrategyTime == 0) {
        if (this.selectedStrategy != null) {
          this.strategy = this.selectedStrategy;
          this.changingStrategy = false;
          this.grid.setOccupiedStatus(false);
        }
      }
    }
   
    // sell animation
    if (sellTime > 0) {
      sellTime--;
      if (sellTime == 0) {
        if (this.getContext() instanceof PlayerContext) {
          getContext().setCredits(getContext().getCredits() + (int) (this.getTotalPrice() * 0.75));
          this.grid.setOccupiedStatus(false);
        }
        getContext().removeTower((Tower) this);
      }
    }
   
    setUpgrading(false);
    //upgrade animation
    if (this.upgradeTime > 0) {
      this.upgradeTime--;
      setUpgrading(true);
      if (getUpgradeTime() == 0) {
        this.upgrade();
        setUpgrading(false);
        getContext().fireSelectedChangedEvent("tower");
        getContext().fireSelectedChangedEvent("upgrade");
        this.grid.setOccupiedStatus(false);
      }
    }

    // decrease cooldown
    if (getCoolDownNow() > 0) {
      this.setCoolDownNow(getCoolDownNow() - 1);
    }

    // find Creep
    if (this.getCoolDownNow() == 0) {
      double xDiff, yDiff, dist, reduction;
      int damage;
      Creep target = this.getStrategy().findCreep();
      this.setTarget(target);

      // splash shoot
      if (this.getSplashRadius() > 0) {
        if (getTarget() != null
            && this.getTarget().isValidTarget()) {
         
          getTargets().clear();
          float x = target.getX();
          float y = target.getY();
          Creep next;

          // find creeps in splashradius
          for (int i = 0; i < getContext().getCreeps().size(); i++) {
            if (getContext().getCreeps().get(i).isValidTarget()) {
              next = getContext().getCreeps().get(i);

              if ((x - next.getX() <= getSplashRadius())
              && (x - next.getX() >= (getSplashRadius() * -1))
              && (y - next.getY() <= getSplashRadius())
              && (y - next.getY() >= (getSplashRadius() * -1))) {
                getTargets().add(next);

              }

            }

          }
          // damage them
          for (Creep creep : getTargets()) {
            if (creep != null && creep.isValidTarget()) {
              xDiff = creep.getX() - getTarget().getX();
              yDiff = creep.getY() - getTarget().getY();
              dist = Math.sqrt(xDiff * xDiff + yDiff * yDiff);

              damage = this.getDamageNow();

              // if the distance is high the damage becomes lower
              reduction = ((getDamageReductionAtRadius()
                  / getSplashRadius()) * dist);
              reduction = damage * reduction;
              creep.damageCreep(damage - (int) reduction,
                  (Tower) this);

            }
          }
          this.setCoolDownNow(getCoolDown());
          // play shoot-sound
          if (sound != null) {
            sound.towerShootsSound(this.getType());
          }
        }
        // normal shot
      } else {
        if (this.getTarget() != null
            && this.getTarget().isValidTarget()) {
          this.getTarget().damageCreep(this.getDamageNow(),
              (Tower) this);
          this.setCoolDownNow(getCoolDown());
          // play shoot-sound
          if (sound != null) {
            sound.towerShootsSound(this.getType());
          }
        }
      }
    }

  }

  /**
   * {@inheritDoc}
   */
  public void upgrade() {

    if (this.type.getNext() != null) {
      this.damage = this.type.getNext().getDamage();
      this.damageNow = this.type.getNext().getDamage();
      this.range = this.type.getNext().getRange();
      this.coolDown = this.type.getNext().getSpeed();
      this.setDamageReductionAtRadius(this.type.getNext()
          .getDamageReductionAtRadius());
      this.setSplashRadius(this.type.getNext().getSplashRadius());
      this.setSlowRate(this.type.getNext().getSlowRate());
      this.setSlowTime(this.type.getNext().getSlowTime());
      this.setTowerColor(this.type.getNext().getTowerColor());
      this.setTotalPrice(getTotalPrice() + type.getNext().getPrice());
      this.setCoolDownNow(getCoolDown() - 1);
      this.type = this.type.getNext();

      if (Cache.getInstance().hasArrayTowerImg(this.getType())) {
        this.setImage(Cache.getInstance().getTowerImg(this.getType()));
      } else {
        this.image = new BufferedImage(20, 20,
            BufferedImage.TYPE_INT_ARGB_PRE);
        generateImage();
        Cache.getInstance()
            .putTowerImg(this.getType(), this.getImage());
      }

      context.repaintBoard();

    }
    // play music
    if (sound != null) {
      sound.towerUpgradeSound(this.type);
    }

  }

  /**
   * {@inheritDoc}
   */
  public void setSelected(boolean selected) {
    this.selected = selected;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isSelected() {
    return this.selected;
  }

  /**
   * {@inheritDoc}
   */
  public void setTowerColor(Color color) {
    this.towerColor = color;
  }

  /**
   * {@inheritDoc}
   */
  public Color getTowerColor() {
    return this.towerColor;
  }

  /**
   * {@inheritDoc}
   */
  public void setBuildTime(int buildTime) {
    this.buildTime = buildTime;
  }

  /**
   * @param target
   *            the target to set
   */
  protected void setTarget(Creep target) {
    this.target = target;
  }

  /**
   * @return the target
   */
  protected Creep getTarget() {
    return target;
  }

  /**
   * @param damage
   *            the damage to set
   */
  public void setDamage(int damage) {
    this.damage = damage;
  }

  /**
   * @return the damage
   */
  public int getDamage() {
    return damage;
  }

  /**
   * @param damageNow
   *            the damageNow to set
   */
  public void setDamageNow(int damageNow) {
    this.damageNow = damageNow;
  }

  /**
   * @return the damageNow
   */
  public int getDamageNow() {
    return damageNow;
  }

  /**
   * @param active
   *            the active to set
   */
  public void setActive(boolean active) {
    this.active = active;
  }

  /**
   * @return the active
   */
  public boolean isActive() {
    return active;
  }

  /**
   * @param type
   *            the type to set
   */
  public void setType(IConstants.Towers type) {
    this.type = type;
  }

  /**
   * @return the type
   */
  public IConstants.Towers getType() {
    return type;
  }

  /**
   * @param grid
   *            the grid to set
   */
  public void setGrid(Grid grid) {
    this.grid = grid;
  }

  /**
   * @return the grid
   */
  public Grid getGrid() {
    return grid;
  }

  /**
   * @param image
   *            the image to set
   */
  protected void setImage(BufferedImage image) {
    this.image = image;
  }

  /**
   * @return the image
   */
  protected BufferedImage getImage() {
    return image;
  }

  /**
   * @return the range
   */
  public float getRange() {
    return range;
  }

  /**
   * @param range
   *            the range to set
   */
  public void setRange(float range) {
    this.range = range;
  }

  /**
   * @return the coolDown
   */
  public int getCoolDown() {
    return coolDown;
  }

  /**
   *
   * @param coolDown
   *            of the Tower
   */
  public void setCoolDown(int coolDown) {
    this.coolDown = coolDown;
  }

  /**
   * @return CoolDownNow
   */
  public int getCoolDownNow() {
    return coolDownNow;
  }

  /**
   *
   * @param coolDownNow
   *            of the Tower
   */
  public void setCoolDownNow(int coolDownNow) {
    this.coolDownNow = coolDownNow;
  }

  /**
   * @return the upgradeTime
   */
  public int getUpgradeTime() {
    return upgradeTime;
  }

  /**
   * @param upgradeTime
   *            the upgradeTime to set
   */
  public void setUpgradeTime(int upgradeTime) {
    this.upgradeTime = upgradeTime;
  }

  /**
   * @return the price
   */
  public int getPrice() {
    return price;
  }

  /**
   * @param price
   *            the price to set
   */
  public void setPrice(int price) {
    this.price = price;
  }

  /**
   * @return the buildTime
   */
  public int getBuildTime() {
    return buildTime;
  }

  /**
   * @return the context
   */
  public GameContext getContext() {
    return context;
  }

  /**
   * @return the upgrading
   */
  public boolean isUpgrading() {
    return upgrading;
  }

  /**
   * @param upgrading the upgrading to set
   */
  public void setUpgrading(boolean upgrading) {
    this.upgrading = upgrading;
  }

  /**
   * @return the building
   */
  public boolean isBuilding() {
    return building;
  }

  /**
   * @param building the building to set
   */
  public void setBuilding(boolean building) {
    this.building = building;
  }
 
  public boolean isSelling() {
    return this.selling;
  }
 
  public void setSelling(boolean selling) {
    this.selling = selling;
  }
 
  public void setChangingStrategy(boolean changingStrategy) {
    this.changingStrategy = changingStrategy;
  }
 
  public boolean isChangingStrategy() {
    return this.changingStrategy;
  }
 
  /**
   * Returns if this tower is ready for selling, upgrading or changing strategy.
   *
   * @return boolean
   */
  public boolean isReady() {
    return (this.active && !this.isUpgrading() && !this.isSelling() && !this.isChangingStrategy());
  }
}
TOP

Related Classes of de.creepsmash.client.tower.AbstractTower

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.