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

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

/* $Id: Item2DView.java,v 1.32 2011/01/14 14:27:55 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.Inspector;
import games.stendhal.client.entity.Item;
import games.stendhal.client.gui.InternalWindow;
import games.stendhal.client.gui.InternalWindow.CloseListener;
import games.stendhal.client.gui.SlotWindow;
import games.stendhal.client.gui.styled.cursor.StendhalCursor;
import games.stendhal.client.sprite.Sprite;
import games.stendhal.client.sprite.SpriteStore;

import java.util.List;

import javax.swing.SwingUtilities;

import marauroa.common.game.RPSlot;

import org.apache.log4j.Logger;

/**
* The 2D view of an item.
*/
class Item2DView extends Entity2DView {
  /**
   * Log4J.
   */
  private static final Logger logger = Logger.getLogger(Item2DView.class);

  /** Window for showing the slot contents, if any */
  private volatile SlotWindow slotWindow;
  /** Width of the slot window */
  private int slotWindowWidth;
  /** height of the slot window */
  private int slotWindowHeight;
  /** The slot content inspector. */
  private Inspector inspector;

  //
  // Entity2DView
  //

  /**
   * Build the visual representation of this entity.
   */
  @Override
  protected void buildRepresentation(IEntity entity) {
    final SpriteStore store = SpriteStore.get();
    Sprite sprite = store.getSprite(translate(getClassResourcePath()));

    /*
     * Items are always 1x1 (they need to fit in entity slots). Extra
     * columns are animation. Extra rows are ignored.
     */
    final int width = sprite.getWidth();

    if (width > IGameScreen.SIZE_UNIT_PIXELS) {
      sprite = store.getAnimatedSprite(sprite, 0, 0, width
          / IGameScreen.SIZE_UNIT_PIXELS,
          IGameScreen.SIZE_UNIT_PIXELS, IGameScreen.SIZE_UNIT_PIXELS,
          100);
    } else if (sprite.getHeight() > IGameScreen.SIZE_UNIT_PIXELS) {
      sprite = store.getTile(sprite, 0, 0, IGameScreen.SIZE_UNIT_PIXELS,
          IGameScreen.SIZE_UNIT_PIXELS);
      logger.warn("Multi-row item image for: " + getClassResourcePath());
    }

    setSprite(sprite);
  }
 
  /**
   * 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) {
    if (getContent() != null) {
      list.add(ActionType.INSPECT.getRepresentation());
    }
    super.buildActions(list);
  }

  /**
   * 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 7000;
  }

  /**
   * Translate a resource name into it's sprite image path.
   *
   * @param name
   *            The resource name.
   *
   * @return The full resource name.
   */
  @Override
  protected String translate(final String name) {
    return "data/sprites/items/" + name + ".png";
  }

  //
  // 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 == IEntity.PROP_CLASS) {
      representationChanged = true;
    }
  }

  //
  // EntityView
  //

  /**
   * Determine if this entity can be moved (e.g. via dragging).
   *
   * @return <code>true</code> if the entity is movable.
   */
  @Override
  public boolean isMovable() {
    return true;
  }

  /**
   * Perform the default action.
   */
  @Override
  public void onAction() {
    onAction(ActionType.USE);
  }

  @Override
  public boolean onHarmlessAction() {
    if (getContent() != null) {
      onAction(ActionType.INSPECT);
      return true;
    }
    return false;
  }
 
  /**
   * Set the content inspector for this entity.
   *
   * @param inspector
   *            The inspector.
   */
  @Override
  public void setInspector(final Inspector inspector) {
    this.inspector = inspector;
  }

  /**
   * Perform an action.
   *
   * @param at
   *            The action.
   */
  @Override
  public void onAction(final ActionType at) {
    switch (at) {
    case USE:
      /*
       * Send use action even for released items, if they are in a slot.
       * Those get released when the slot contents change, and a new view
       * is created. Users expect to be able to use multiple double clicks
       * or using a menu created previously for the item.
       */
      if (!isReleased() || !entity.isOnGround()) {
        at.send(at.fillTargetInfo(entity.getRPObject()));
      }
      break;
     
    case INSPECT:
      inspect();
      break;

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

  /**
   * Inspect the item. Show the slot contents.
   */
  private void inspect() {
    RPSlot slot = getContent();
    if (slotWindowWidth == 0) {
      calculateWindowProportions(slot.getCapacity());
    }
   
    boolean addListener = slotWindow == null;
    slotWindow = inspector.inspectMe(entity, slot,
        slotWindow, slotWindowWidth, slotWindowHeight);
    SlotWindow window = slotWindow;
    /*
     * Register a listener for window closing so that we can
     * drop the reference to the closed window and let the
     * garbage collector claim it.
     */
    if (addListener && (window != null)) {
      window.addCloseListener(new CloseListener() {
        public void windowClosed(InternalWindow window) {
          slotWindow = null;
        }
      });
    }
    /*
     * In case the view got released while the window was created and
     * added, and before the main thread was aware that there's a window
     * to be closed, close it now. (onAction is called from the event
     * dispatch thread).
     */
    if (isReleased()) {
      if (window != null) {
        window.close();
      }
    }
  }
 
  /**
   * Get the content slot.
   *
   * @return Content slot or <code>null</code> if the item has none or it's
   * not accessible.
   */
  private RPSlot getContent() {
    return ((Item) entity).getContent();
  }

  /**
   * Find out dimensions for a somewhat square slot window.
   * 
   * @param slots number of slots in the window
   */
  private void calculateWindowProportions(final int slots) {
    int width = (int) Math.sqrt(slots);

    while (slots % width != 0) {
      width--;
      if (width <= 0) {
        logger.error("Failed to decide dimensions for slot window. slots = " + slots);

        width = 1;
      }
    }
    slotWindowWidth = width;
    slotWindowHeight = slots / width;
  }
 
  @Override
  public void release() {
    final SlotWindow window = slotWindow;
    if (window != null) {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          window.close();
        }
      });
    }

    super.release();
  }

  @Override
  public StendhalCursor getCursor() {
    return StendhalCursor.NORMAL;
  }
}
TOP

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

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.