Package games.stendhal.client.gui.j2d.entity

Source Code of games.stendhal.client.gui.j2d.entity.RPEntity2DView

/* $Id: RPEntity2DView.java,v 1.62 2011/01/05 18:17:27 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.client.gui.j2d.entity;


import games.stendhal.client.IGameScreen;
import games.stendhal.client.entity.ActionType;
import games.stendhal.client.entity.IEntity;
import games.stendhal.client.entity.RPEntity;
import games.stendhal.client.entity.User;
import games.stendhal.client.sprite.AnimatedSprite;
import games.stendhal.client.sprite.Sprite;
import games.stendhal.client.sprite.SpriteStore;
import games.stendhal.client.sprite.TextSprite;
import games.stendhal.common.Debug;
import games.stendhal.common.Direction;
import games.stendhal.common.constants.Nature;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import marauroa.common.game.RPAction;

/**
* The 2D view of an RP entity.
*/
abstract class RPEntity2DView extends ActiveEntity2DView {
  private static final int ICON_OFFSET = 8;
 
  /** Number of frames in attack sprites */
  private static final int NUM_ATTACK_FRAMES = 3;
  private static final Stroke ARROW_STROKE = new BasicStroke(2);
  private static final Map<Nature, Color> arrowColor;
 
  static {
    arrowColor = new EnumMap<Nature, Color>(Nature.class);
    arrowColor.put(Nature.CUT, Color.LIGHT_GRAY);
    arrowColor.put(Nature.DARK, Color.DARK_GRAY);
    arrowColor.put(Nature.LIGHT, new Color(255, 240, 140)); // light yellow
    arrowColor.put(Nature.FIRE, new Color(255, 100, 0)); // reddish orange
    arrowColor.put(Nature.ICE, new Color(140, 140, 255)); // light blue
  }

  /**
   * The attack sprites. The top level map contains all the
   * strike sprites sorted by damage type. Those in turn are
   * retrievable by the attack direction.
   */
  private static Map<Nature, Map<Direction, Sprite[]>> bladeStrikeSprites;

  private static Sprite eatingSprite;

  private static Sprite poisonedSprite;

  private static Sprite chokingSprite;

  private static Sprite hitSprite;

  private static Sprite blockedSprite;

  private static Sprite missedSprite;
 
  /** Temporary text sprites, like HP and XP changes. */
  private Map<RPEntity.TextIndicator, Sprite> floaters = new HashMap<RPEntity.TextIndicator, Sprite>();

  /**
   * Blade strike frame.
   */
  private int frameBladeStrike;

  /**
   * Model attributes effecting the title changed.
   */
  private boolean titleChanged;

  /**
   * The title image sprite.
   */
  private Sprite titleSprite;

  /*
   * The drawn height.
   */
  protected int height;

  /*
   * The drawn width.
   */
  protected int width;
 
  /** Put ideas on top? */
  private static final boolean ideasontop = (System
      .getProperty("stendhal.ideasontop") != null);

  static {
    final SpriteStore st = SpriteStore.get();
   
    final int twidth = NUM_ATTACK_FRAMES * IGameScreen.SIZE_UNIT_PIXELS;
    final int theight = 4 * IGameScreen.SIZE_UNIT_PIXELS;

    bladeStrikeSprites = new EnumMap<Nature, Map<Direction, Sprite[]>>(Nature.class);
   
    // Load all attack sprites
    for (Nature damageType : Nature.values()) {
      final Sprite tiles = st.getSprite("data/sprites/combat/blade_strike_"
          + damageType.toString().toLowerCase(Locale.US) + ".png");

      Map<Direction, Sprite[]> map = new EnumMap<Direction, Sprite[]>(Direction.class);
      bladeStrikeSprites.put(damageType, map);
     
      int y = 0;
      map.put(Direction.UP, st.getTiles(tiles, 0, y, 3, twidth, theight));

      y += theight;
      map.put(Direction.RIGHT, st.getTiles(tiles, 0, y, 3, twidth, theight));

      y += theight;
      map.put(Direction.DOWN, st.getTiles(tiles, 0, y, 3, twidth, theight));

      y += theight;
      map.put(Direction.LEFT, st.getTiles(tiles, 0, y, 3, twidth, theight));
    }

    hitSprite = st.getSprite("data/sprites/combat/hitted.png");
    blockedSprite = st.getSprite("data/sprites/combat/blocked.png");
    missedSprite = st.getSprite("data/sprites/combat/missed.png");
    eatingSprite = st.getSprite("data/sprites/ideas/eat.png");
    poisonedSprite = st.getSprite("data/sprites/ideas/poisoned.png");
    chokingSprite = st.getSprite("data/sprites/ideas/choking.png");
  }


  @Override
  public void initialize(final IEntity entity) {
    super.initialize(entity);
    titleSprite = createTitleSprite();
    titleChanged = false;
  }
  //
  // RPEntity2DView
  //

  /**
   * Populate keyed state sprites.
   *
   * @param map
   *            The map to populate.
   * @param tiles
   *            The master sprite.
   * @param width
   *            The tile width (in pixels).
   * @param height
   *            The tile height (in pixels).
   */
  protected void buildSprites(final Map<Object, Sprite> map,
      final Sprite tiles, final int width, final int height) {
    int y = 0;
    map.put(Direction.UP, createWalkSprite(tiles, y, width, height));

    y += height;
    map.put(Direction.RIGHT, createWalkSprite(tiles, y, width, height));

    y += height;
    map.put(Direction.DOWN, createWalkSprite(tiles, y, width, height));

    y += height;
    map.put(Direction.LEFT, createWalkSprite(tiles, y, width, height));
  }

  /**
   * Calculate sprite image offset. Sub-classes may override this to change
   * alignment.
   *
   * @param spriteWidth
   *            The sprite width (in pixels).
   * @param spriteHeight
   *            The sprite height (in pixels).
   * @param entityWidth
   *            The entity width (in pixels).
   * @param entityHeight
   *            The entity height (in pixels).
   */
  @Override
  protected void calculateOffset(final int spriteWidth,
      final int spriteHeight, final int entityWidth,
      final int entityHeight) {
    /*
     * X alignment centered, Y alignment bottom
     */
    xoffset = (entityWidth - spriteWidth) / 2;
    yoffset = entityHeight - spriteHeight;
  }

  /**
   * Create the title sprite.
   *
   * @return The title sprite.
   */
  protected Sprite createTitleSprite() {
    final String titleType = ((RPEntity) entity).getTitleType();
    final int adminlevel = ((RPEntity) entity).getAdminLevel();
    Color nameColor = null;

    if (titleType != null) {
      if (titleType.equals("npc")) {
        nameColor = new Color(200, 200, 255);
      } else if (titleType.equals("enemy")) {
        nameColor = new Color(255, 200, 200);
      }
    }

    if (nameColor == null) {
      if (adminlevel >= 800) {
        nameColor = new Color(200, 200, 0);
      } else if (adminlevel >= 400) {
        nameColor = new Color(255, 255, 0);
      } else if (adminlevel > 0) {
        nameColor = new Color(255, 255, 172);
      } else {
        nameColor = Color.white;
      }
    }

    return TextSprite.createTextSprite(entity.getTitle(), nameColor);
  }

  /**
   * Extract a walking animation for a specific row. The source sprite
   * contains 3 animation tiles, but this is converted to 4 frames.
   *
   * @param tiles
   *            The tile image.
   * @param y
   *            The base Y coordinate.
   * @param width
   *            The frame width.
   * @param height
   *            The frame height.
   *
   * @return A sprite.
   */
  protected Sprite createWalkSprite(final Sprite tiles, final int y,
      final int width, final int height) {
    final SpriteStore store = SpriteStore.get();

    final Sprite[] frames = new Sprite[4];

    int x = 0;
    frames[0] = store.getTile(tiles, x, y, width, height);

    x += width;
    frames[1] = store.getTile(tiles, x, y, width, height);

    x += width;
    frames[2] = store.getTile(tiles, x, y, width, height);

    frames[3] = frames[1];

    return new AnimatedSprite(frames, 100, false);
  }

  /**
   * Draw the floating text indicators (floaters).
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn width.
   */
  protected void drawFloaters(final Graphics2D g2d, final int x, final int y,
      final int width) {
    for (Map.Entry<RPEntity.TextIndicator, Sprite> floater : floaters.entrySet()) {
      final RPEntity.TextIndicator indicator = floater.getKey();
      final Sprite sprite = floater.getValue();
      final int age = indicator.getAge();
     
      final int tx = x + (width - sprite.getWidth()) / 2;
      final int ty = y - (int) (age * 5L / 300L);
      sprite.draw(g2d, tx, ty);
    }
  }

  /**
   * Draw the entity HP bar.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn width.
   */
  protected void drawHPbar(final Graphics2D g2d, final int x, final int y,
      final int width) {
    final int barWidth = Math.max(width * 2 / 3, IGameScreen.SIZE_UNIT_PIXELS);

    final int bx = x + ((width - barWidth) / 2);
    final int by = y - 3;

    RPEntity rpentity = (RPEntity) entity;
   
    final float hpRatio = rpentity.getHpRatio();

    final float r = Math.min((1.0f - hpRatio) * 2.0f, 1.0f);
    final float g = Math.min(hpRatio * 2.0f, 1.0f);

    g2d.setColor(Color.gray);
    g2d.fillRect(bx, by, barWidth, 3);

    g2d.setColor(new Color(r, g, 0.0f));
    g2d.fillRect(bx, by, (int) (hpRatio * barWidth), 3);

    g2d.setColor(Color.black);
    g2d.drawRect(bx, by, barWidth, 3);
  }

  /**
   * Draw the entity status bar. The status bar show the title and HP bar.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn width.
   */
  protected void drawStatusBar(final Graphics2D g2d, final int x,
      final int y, final int width) {
    drawTitle(g2d, x, y, width);
    drawHPbar(g2d, x, y, width);
  }

  /**
   * Draw the entity title.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn width.
   */
  protected void drawTitle(final Graphics2D g2d, final int x, final int y, final int width) {
    if (titleSprite != null) {
      final int tx = x + ((width - titleSprite.getWidth()) / 2);
      final int ty = y - 3 - titleSprite.getHeight();

      titleSprite.draw(g2d, tx, ty);
    }
  }

  /**
   * Draw the entity ideas. (eating, choking, poisoned, etc)
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.

   * @param height
   *            The drawn entity height.
   */
  protected void drawIdeas(final Graphics2D g2d, final int x,
      final int y, final int height) {
    RPEntity rpentity = (RPEntity) entity;
   
    if (rpentity.isEating()) {
      if (rpentity.isChoking()) {
        chokingSprite.draw(g2d, x, y + height - 2 * ICON_OFFSET);
      } else {
        eatingSprite.draw(g2d, x, y + height - 2 * ICON_OFFSET);
      }
    }

    if (rpentity.isPoisoned()) {
      poisonedSprite.draw(g2d, x - ICON_OFFSET, y + height - 2 * ICON_OFFSET);
    }
  }

  /**
   * Draw the combat indicators.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn entity width.
   * @param height
   *            The drawn entity height.
   */
  protected void drawCombat(final Graphics2D g2d, final int x,
                final int y, final int width, final int height) {
    RPEntity rpentity = (RPEntity) entity;
   
    Rectangle2D wrect = rpentity.getArea();
    final Rectangle srect = new Rectangle((int) (wrect.getX() * IGameScreen.SIZE_UNIT_PIXELS),
        (int) (wrect.getY() * IGameScreen.SIZE_UNIT_PIXELS),
        (int) (wrect.getWidth() * IGameScreen.SIZE_UNIT_PIXELS),
        (int) (wrect.getHeight() * IGameScreen.SIZE_UNIT_PIXELS));
   
    final double DIVISOR = 1.414213562; // sqrt(2)
   
    if (rpentity.isBeingAttacked()) {
      // Draw red box around
      //g2d.setColor(Color.white);
      //g2d.drawRect(srect.x + 1, srect.y + 1, srect.width - 2, srect.height - 2);
      g2d.setColor(Color.red);
      int circleHeight = (int) ((srect.height - 2) / DIVISOR);
      // Avoid showing much smaller area than the creature covers
      circleHeight = Math.max(circleHeight, srect.height - IGameScreen.SIZE_UNIT_PIXELS / 2);
      g2d.drawArc(srect.x, (int) (srect.y + srect.height - circleHeight),
          srect.width + 0, circleHeight, 0, 360);
    }

    if (rpentity.isAttacking(User.get())) {
      // Draw orange box around
      //g2d.setColor(Color.white);
      //g2d.drawRect(srect.x + 2, srect.y + 2, srect.width - 4, srect.height - 4);
      g2d.setColor(Color.orange);
      int circleHeight = (int) ((srect.height - 4) / DIVISOR);
      // Avoid showing much smaller area than the creature covers
      circleHeight = Math.max(circleHeight, srect.height - IGameScreen.SIZE_UNIT_PIXELS / 2 - 2);
      g2d.drawArc(srect.x + 1, (int) (srect.y + srect.height - circleHeight - 1),
          srect.width - 2, circleHeight, 0, 360);
    }

    drawAttack(g2d, x, y, width, height);

    if (rpentity.isDefending()) {
      // Draw bottom right combat icon
      final int sx = srect.x + srect.width - ICON_OFFSET;
      final int sy = y + height - 2 * ICON_OFFSET;

      switch (rpentity.getResolution()) {
      case BLOCKED:
        blockedSprite.draw(g2d, sx, sy);
        break;

      case MISSED:
        missedSprite.draw(g2d, sx, sy);
        break;

      case HIT:
        hitSprite.draw(g2d, sx, sy);
        break;
      default:
        // cannot happen we are switching on enum
      }
    }
  }
 
  /**
   * Draw the attacking effect.
   *
   * @param g2d The graphics context
   * @param x x coordinate of the attacker
   * @param y y coordinate of the attacker
   * @param width width of the attacker
   * @param height height of the attacker
   */
  private void drawAttack(final Graphics2D g2d, final int x, final int y, final int width, final int height) {
    RPEntity rpentity = (RPEntity) entity;
   
    if (rpentity.isAttacking() && rpentity.getShownDamageType() != null) {
      if (frameBladeStrike < NUM_ATTACK_FRAMES) {
        RPEntity target = rpentity.getAttackTarget();

        // A hack to check if it's a distance attack for proof
        // of concept arrow drawing. Should be specified in the
        // attack event itself
        final Rectangle2D area = rpentity.getArea();
        area.setRect(rpentity.getX() - 0.25, rpentity.getY() - 0.25, rpentity.getWidth()
            + 2 * 0.25, rpentity.getHeight() + 2 * 0.25);
       
        if (area.intersects(target.getArea())) {
          drawStrike(g2d, rpentity, x, y, width, height);
        } else {
          drawDistanceAttack(g2d, rpentity, target, x, y, width, height);
        }
        frameBladeStrike++;
      } else {
        rpentity.doneStriking();
        frameBladeStrike = 0;
      }
    }
  }
 
  /**
   * Draw a blade strike.
   * 
   * @param g2d
   * @param entity
   * @param x
   * @param y
   * @param width
   * @param height
   */
  private void drawStrike(final Graphics2D g2d, final RPEntity entity,
      final int x, final int y, final int width, final int height) {
    Nature damageType = entity.getShownDamageType();
   
    if (damageType != null) {     
      final Sprite sprite = bladeStrikeSprites.get(damageType).get(getState(entity))[frameBladeStrike];

      final int spriteWidth = sprite.getWidth();
      final int spriteHeight = sprite.getHeight();

      int sx;
      int sy;

      /*
       * Align swipe image to be 16 px past the facing edge, centering
       * in other axis.
       *
       * Swipe image is 3x4 tiles, but really only uses partial areas.
       * Adjust positions to match (or fix images to be
       * uniform/centered).
       */
      switch (entity.getDirection()) {
      case UP:
        sx = x + ((width - spriteWidth) / 2) + 16;
        sy = y - 16 - 32;
        break;

      case DOWN:
        sx = x + ((width - spriteWidth) / 2);
        sy = y + height - spriteHeight + 16;
        break;

      case LEFT:
        sx = x - 16;
        sy = y + ((height - spriteHeight) / 2) - 16;
        break;

      case RIGHT:
        sx = x + width - spriteWidth + 16;
        sy = y + ((height - spriteHeight) / 2) - ICON_OFFSET;
        break;

      default:
        sx = x + ((width - spriteWidth) / 2);
        sy = y + ((height - spriteHeight) / 2);
      }

      sprite.draw(g2d, sx, sy);
    }
  }
 
  /**
   * Draw a distance attack line.
   *
   * @param g2d
   * @param entity
   * @param target
   * @param x
   * @param y
   * @param width
   * @param height
   */
  private void drawDistanceAttack(final Graphics2D g2d, final RPEntity entity, final RPEntity target,
      final int x, final int y, final int width, final int height) {
    Nature nature = entity.getShownDamageType();

    int startX = x + width / 2;
    int startY = y + height / 2;
    int endX = (int) (32 * (target.getX() + target.getWidth() / 2));
    // Target at the upper edge of the occupied area.
    // Getting the EntityView from an entity is tedious, and
    // still does not work reliable for everything (rats)
    int endY = (int) (32 * target.getY());

    int yLength = (endY - startY) / NUM_ATTACK_FRAMES;
    int xLength = (endX - startX) / NUM_ATTACK_FRAMES;

    startY += frameBladeStrike * yLength;
    endY = startY + yLength;

    startX += frameBladeStrike * xLength;
    endX = startX + xLength;

    g2d.setColor(arrowColor.get(nature));
    Stroke oldStroke = g2d.getStroke();
    g2d.setStroke(ARROW_STROKE);
    g2d.drawLine(startX, startY, endX, endY);
    g2d.setStroke(oldStroke);
  }

  /**
   * Get the full directional animation tile set for this entity.
   *
   * @return A tile sprite containing all animation images.
   */
  protected abstract Sprite getAnimationSprite();

  /**
   * Get the number of tiles in the X axis of the base sprite.
   *
   * @return The number of tiles.
   */
  protected int getTilesX() {
    return 3;
  }

  /**
   * Get the number of tiles in the Y axis of the base sprite.
   *
   * @return The number of tiles.
   */
  protected int getTilesY() {
    return 4;
  }

  /**
   * Determine is the user can see this entity while in ghostmode.
   *
   * @return <code>true</code> if the client user can see this entity while in
   *         ghostmode.
   */
  protected boolean isVisibleGhost() {
    return false;
  }

  //
  // StateEntity2DView
  //

  /**
   * Populate keyed state sprites.
   *
   * @param entity the entity to build sprites for
   * @param map
   *            The map to populate.
   */
  @Override
  protected void buildSprites(IEntity entity, final Map<Object, Sprite> map) {
    final Sprite tiles = getAnimationSprite();

    width = tiles.getWidth() / getTilesX();
    height = tiles.getHeight() / getTilesY();

    buildSprites(map, tiles, width, height);
    calculateOffset(entity, width, height);
  }

  //
  // Entity2DView
  //

  /**
   * Build a list of entity specific actions. <strong>NOTE: The first entry
   * should be the default.</strong>
   *
   * @param list
   *            The list to populate.
   */
  @Override
  protected void buildActions(final List<String> list) {
    super.buildActions(list);

    RPEntity rpentity = (RPEntity) entity;
    if (rpentity.isAttackedBy(User.get())) {
      list.add(ActionType.STOP_ATTACK.getRepresentation());
    } else {
      list.add(ActionType.ATTACK.getRepresentation());
    }

    list.add(ActionType.PUSH.getRepresentation());
  }

  /**
   * Draw the entity.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn entity width.
   * @param height
   *            The drawn entity height.
   */
  @Override
  protected void draw(final Graphics2D g2d, final int x, final int y,
      final int width, final int height) {
    drawCombat(g2d, x, y, width, height);
    super.draw(g2d, x, y, width, height);

    if (!ideasontop) {
      drawIdeas(g2d, x, y, height);
    }

    if (Debug.SHOW_ENTITY_VIEW_AREA) {
      g2d.setColor(Color.cyan);
      g2d.drawRect(x, y, width, height);
    }

    drawFloaters(g2d, x, y, width);
  }

  /**
   * Draw the top layer parts of an entity. This will be on down after all
   * other game layers are rendered.
   *
   * @param g2d
   *            The graphics context.
   * @param x
   *            The drawn X coordinate.
   * @param y
   *            The drawn Y coordinate.
   * @param width
   *            The drawn entity width.
   * @param height
   *            The drawn entity height.
   */
  @Override
  protected void drawTop(final Graphics2D g2d, final int x, final int y,
      final int width, final int height) {
    drawStatusBar(g2d, x, y, width);
    if (ideasontop) {
      drawIdeas(g2d, x, y, height);
    }
  }

  /**
   * Get the height.
   *
   * @return The height (in pixels).
   */
  @Override
  public int getHeight() {
    return height;
  }

  /**
   * Get the entity's visibility.
   *
   * @return The visibility value (0-100).
   */
  @Override
  protected int getVisibility() {
    /*
     * Hide while in ghostmode.
     */
    if (((RPEntity) entity).isGhostMode()) {
      if (isVisibleGhost()) {
        return super.getVisibility() / 2;
      } else {
        return 0;
      }
    } else {
      return super.getVisibility();
    }
  }

  /**
   * Get the width.
   *
   * @return The width (in pixels).
   */
  @Override
  public int getWidth() {
    return width;
  }

  /**
   * Determines on top of which other entities this entity should be drawn.
   * Entities with a high Z index will be drawn on top of ones with a lower Z
   * index.
   *
   * Also, players can only interact with the topmost entity.
   *
   * @return The drawing index.
   */
  @Override
  public int getZIndex() {
    return 8000;
  }

  @Override
  protected void update() {
    super.update();

    if (titleChanged) {
      titleSprite = createTitleSprite();
      titleChanged = false;
    }
  }

  //
  // EntityChangeListener
  //

  /**
   * An entity was changed.
   *
   * @param entity
   *            The entity that was changed.
   * @param property
   *            The property identifier.
   */
  @Override
  public void entityChanged(final IEntity entity, final Object property) {
    super.entityChanged(entity, property);

    if (property == RPEntity.PROP_ADMIN_LEVEL) {
      titleChanged = true;
      visibilityChanged = true;
    } else if (property == RPEntity.PROP_GHOSTMODE) {
      visibilityChanged = true;
    } else if (property == RPEntity.PROP_OUTFIT) {
      representationChanged = true;
    } else if (property == IEntity.PROP_TITLE) {
      titleChanged = true;
    } else if (property == RPEntity.PROP_TITLE_TYPE) {
      titleChanged = true;
    } else if (property == RPEntity.PROP_TEXT_INDICATORS) {
      onFloatersChanged();
    }
  }
 
  private void onFloatersChanged() {
    Iterator<RPEntity.TextIndicator> it = ((RPEntity) entity).getTextIndicators();
    Map<RPEntity.TextIndicator, Sprite> newFloaters = new HashMap<RPEntity.TextIndicator, Sprite>();
   
    while (it.hasNext()) {
      RPEntity.TextIndicator floater = it.next();
      Sprite sprite = floaters.get(floater);
      if (sprite == null) {
        sprite = TextSprite.createTextSprite(floater.getText(), floater.getType().getColor());
      }
     
      newFloaters.put(floater, sprite);
    }
   
    floaters = newFloaters;
  }

  /**
   * Perform an action.
   *
   * @param at
   *            The action.
   */
  @Override
  public void onAction(final ActionType at) {
    if (isReleased()) {
      return;
    }
    RPAction rpaction;

    switch (at) {
    case PUSH:
    case ATTACK:
      at.send(at.fillTargetInfo(entity.getRPObject()));
      break;

    case STOP_ATTACK:
      rpaction = new RPAction();

      rpaction.put("type", at.toString());
      rpaction.put("attack", "");

      at.send(rpaction);
      break;

    default:
      super.onAction(at);
      break;
    }
  }
}
TOP

Related Classes of games.stendhal.client.gui.j2d.entity.RPEntity2DView

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.