private void showNextEntry(@Nonnull final Iterator<CreditsList> iterator) {
    if (!iterator.hasNext()) {
      gotoNextScreen();
      return;
    }

    final CreditsList list = iterator.next();
    if (Lang.getInstance().isGerman()) {
      titleLabel.setText(list.getNameGerman());
    } else {
      titleLabel.setText(list.getNameEnglish());
    }

    final List<String> names = new ArrayList<String>();
    for (final CreditsPerson person : list) {
      names.add(person.getName());
    }
    final StringBuilder builder = new StringBuilder();
    final int nameCount = names.size();
    for (int i = 0; i < nameCount; i++) {
      builder.append(names.get(i));
      if (i < (nameCount - 2)) {
        builder.append(", ");
      } else if (i < (nameCount - 1)) {
        if (Lang.getInstance().isGerman()) {
          builder.append(" und ");
        } else {
          builder.append(" and ");
        }
      }
    }
    nameLabel.setText(builder.toString());
    displayParent.layoutElements();

    displayParent.show(
        new EndNotify() {
          @Override
          public void perform() {
            displayParent.hide(
                new EndNotify() {
                  @Override
                  public void perform() {
                    showNextEntry(iterator);
                  }
                });
          }
        });
  }
예제 #2
0
  @Nonnull
  @Override
  @SuppressWarnings("OverlyLongMethod")
  public ServerReplyResult execute() {
    if (informText == null) {
      throw new NotDecodedException();
    }

    if (!World.getGameGui().isReady()) {
      return ServerReplyResult.Reschedule;
    }

    GameGui gui = World.getGameGui();
    switch (informType) {
      case SERVER:
        gui.getInformGui().showServerInform(informText);
        break;
      case BROADCAST:
        gui.getInformGui().showBroadcastInform(informText);
        gui.getChatGui()
            .addChatMessage(
                Lang.getMsg("chat.broadcast") + ": " + informText, ChatGui.COLOR_DEFAULT);
        break;
      case GM:
        gui.getInformGui().showTextToInform(informText);
        gui.getChatGui()
            .addChatMessage(Lang.getMsg("chat.textto") + ": " + informText, ChatGui.COLOR_DEFAULT);
        break;
      case SCRIPT_LOW_PRIORITY:
        gui.getInformGui().showScriptInform(0, informText);
        break;
      case SCRIPT_MEDIUM_PRIORITY:
        gui.getInformGui().showScriptInform(1, informText);
        gui.getChatGui().addChatMessage(informText, ChatGui.COLOR_INFORM);
        break;
      case SCRIPT_HIGH_PRIORITY:
        gui.getInformGui().showScriptInform(2, informText);
        gui.getChatGui().addChatMessage(informText, ChatGui.COLOR_HIGH_INFORM);
        break;
      default:
        log.warn(
            "Received inform with unknown type: {}" + '(' + "{}" + ')', informType, informText);
    }
    return ServerReplyResult.Success;
  }
예제 #3
0
  /**
   * Set number of stacked items.
   *
   * @param newCount the number of items on this stack, in case its more then one a text is
   *     displayed next to the item that shown how many items are on the stack
   */
  public void setCount(@Nullable ItemCount newCount) {
    count = newCount;

    // write number to text for display
    if (ItemCount.isGreaterOne(count)) {
      number = new TextTag(count.getShortText(Lang.getInstance().getLocale()), Color.YELLOW);
    } else {
      number = null;
    }
  }
예제 #4
0
  /**
   * Execute the disconnect message and send the decoded data to the rest of the client.
   *
   * @return true if the execution is done, false if it shall be called again
   */
  @SuppressWarnings("nls")
  @Override
  public boolean executeUpdate() {
    BUILDER.setLength(0);
    BUILDER.append(Lang.getMsg("logout"));
    BUILDER.append("\n");
    BUILDER.append(Lang.getMsg("logout.reason"));
    BUILDER.append(" ");

    if (reason < REASONS.length) {
      BUILDER.append(Lang.getMsg("logout." + REASONS[reason]));
    } else {
      BUILDER.append(Lang.getMsg("logout.unknown"));
      BUILDER.append(Integer.toHexString(reason));
    }
    BUILDER.append("\n");
    BUILDER.append(Lang.getMsg("logout.char"));
    BUILDER.append(" ");
    BUILDER.append(Game.getInstance().getLogin());
    IllaClient.fallbackToLogin(BUILDER.toString());
    return true;
  }
예제 #5
0
  /**
   * Get the name of the character. Returns the last known name or someone along with the ID of the
   * character, in case its set that the IDs shall be shown.
   *
   * @param id ID of the character who's name is wanted
   * @return the name of the character or null
   */
  @SuppressWarnings("nls")
  private String getName(final CharacterId id) {
    String name = null;

    if (names != null) {
      name = names.getName(id);
    }

    if (name == null) {
      if (showIDs) {
        final TextBuilder buildName = TextBuilder.newInstance();
        buildName.setLength(0);
        buildName.append(Lang.getMsg("someone"));
        buildName.append(' ');
        buildName.append('(');
        buildName.append(id);
        buildName.append(')');
        name = buildName.toString();
        TextBuilder.recycle(buildName);
      }
    }
    return name;
  }
예제 #6
0
/**
 * Handles all characters known to the client but the player character.
 *
 * @author Martin Karing &lt;[email protected]&gt;
 * @author Nop
 */
public final class People implements TableLoaderSink, ConfigChangeListener {
  /** The key for the configuration where the name mode is stored. */
  @SuppressWarnings("nls")
  public static final String CFG_NAMEMODE_KEY = "showNameMode";

  /** The key for the configuration where the current show ID flag is stored. */
  @SuppressWarnings("nls")
  public static final String CFG_SHOWID_KEY = "showIDs";

  /** Default Name of a enemy. */
  @SuppressWarnings("nls")
  private static final String ENEMY = "'" + Lang.getMsg("chat.enemy") + "'";

  /** The logger instance that takes care for the logging output of this class. */
  private static final Logger LOGGER = Logger.getLogger(People.class);

  /** Settings value for showing full names. */
  public static final int NAME_LONG = 2;

  /** Settings value for showing shorten names. */
  public static final int NAME_SHORT = 1;

  /** This is the format string that is displayed in the {@link #toString()} function. */
  @SuppressWarnings("nls")
  private static final String TO_STRING_TEXT = "People Manager - %d$1 characters in storage";

  /**
   * This function checks a argument against <code>null</code> and throws a exception in case the
   * argument is <code>null</code>
   *
   * @param arg the argument to test
   * @throws NullPointerException in case the argument is <code>null</code>.
   */
  @SuppressWarnings("nls")
  private static void throwNullException(final Object arg) {
    if (arg == null) {
      throw new NullPointerException("Argument must not be null.");
    }
  }

  /** The list of visible characters. */
  private final Map<CharacterId, Char> chars;

  /** The lock that is used to secure the chars table properly. */
  private final ReentrantReadWriteLock charsLock;

  /** Names of known characters. */
  private NamesTable names;

  /** The character of the player. This one is handled seperated of the rest of the characters. */
  private Char playerChar;

  /** A list of characters that are going to be removed. */
  private final List<Char> removalList;

  /**
   * Settings if the ID of characters shall be shown or generic descriptors like "Man", "Woman",
   * etc.
   */
  private boolean showIDs;

  /** Contains the status how the names of the characters shall be shown. */
  private int showMapNames;

  /** Default constructor. Sets up all needed base variables to init the class. */
  public People() {
    showMapNames = IllaClient.getCfg().getInteger(CFG_NAMEMODE_KEY);
    showIDs = IllaClient.getCfg().getBoolean(CFG_SHOWID_KEY);
    IllaClient.getCfg().addListener(CFG_NAMEMODE_KEY, this);
    IllaClient.getCfg().addListener(CFG_SHOWID_KEY, this);

    removalList = new FastTable<Char>();
    chars = new HashMap<CharacterId, Char>();
    charsLock = new ReentrantReadWriteLock();

    final File playerDir =
        new File(
            DirectoryManager.getInstance().getUserDirectory(),
            Login.getInstance().getSelectedCharacterName());
    final File nameTable = new File(playerDir, "names.tbl");
    final File nameTableNew = new File(playerDir, "names.dat");
    names = new NamesTable(nameTableNew);

    if (nameTable.exists() && nameTable.isFile()) {
      new TableLoader(nameTable, this);
      if (!nameTable.delete()) {
        LOGGER.error("Failed to delete old name table.");
      }
    }
  }

  /**
   * Get a character on the client screen. If the character is not available, its created and the
   * appearance is requested from the server.
   *
   * @param id the ID of the character
   * @return the character that was requested
   */
  public Char accessCharacter(final CharacterId id) {
    final Char chara = getCharacter(id);
    if (chara == null) {
      return createNewCharacter(id);
    }
    return chara;
  }

  /**
   * Add a character to the list of known characters.
   *
   * @param chara the character that shall be added
   */
  void addCharacter(final Char chara) {
    throwPlayerCharacter(chara);

    charsLock.writeLock().lock();
    try {
      chars.put(chara.getCharId(), chara);
    } finally {
      charsLock.writeLock().unlock();
    }
  }

  /**
   * Add a character to the list of characters that are going to be removed at the next run of
   * {@link #cleanRemovalList()}.
   *
   * @param removeChar the character that is going to be removed
   */
  public void addCharacterToRemoveList(final Char removeChar) {
    throwNullException(removeChar);
    throwPlayerCharacter(removeChar);
    removalList.add(removeChar);
  }

  /** Check the visibility for all characters currently on the screen. */
  void checkVisibility() {
    charsLock.readLock().lock();
    try {
      for (final Char character : chars.values()) {
        character.setVisible(World.getPlayer().canSee(character));
      }
    } finally {
      charsLock.readLock().unlock();
    }
  }

  /**
   * Clean up the removal list. All character from the list of character to remove get removed and
   * recycled. The list is cleared after calling this function.
   */
  public void cleanRemovalList() {
    charsLock.writeLock().lock();
    try {
      if (!removalList.isEmpty()) {
        for (final Char removeChar : removalList) {
          removeCharacter(removeChar.getCharId());
        }
        removalList.clear();
      }
    } finally {
      charsLock.writeLock().unlock();
    }
  }

  /** Clear the list of characters and recycle all of them. */
  void clear() {
    if (CombatHandler.getInstance().isAttacking()) {
      CombatHandler.getInstance().standDown();
    }
    charsLock.writeLock().lock();
    try {
      cleanRemovalList();
      for (final Char character : chars.values()) {
        character.recycle();
      }
      chars.clear();
    } finally {
      charsLock.writeLock().unlock();
    }
  }

  /**
   * Check all known characters if they are outside of the screen and hide them from the screen.
   * Save them still to the characters that are known to left the screen.
   */
  void clipCharacters() {
    charsLock.writeLock().lock();
    try {

      for (final Char character : chars.values()) {
        if (!World.getPlayer().isOnScreen(character.getLocation(), 0)) {
          addCharacterToRemoveList(character);
        }
      }
      cleanRemovalList();
    } finally {
      charsLock.writeLock().unlock();
    }
  }

  /**
   * Act in case a change of the configuration occurred. This causes all values dependent on the
   * configuration to fit the configuration again.
   */
  @Override
  public void configChanged(final Config cfg, final String key) {
    throwNullException(cfg);
    throwNullException(key);

    if (key.equals(CFG_NAMEMODE_KEY)) {
      showMapNames = cfg.getInteger(CFG_NAMEMODE_KEY);

      for (final Char character : chars.values()) {
        updateName(character);
      }
      return;
    }
    if (key.equals(CFG_SHOWID_KEY)) {
      showIDs = cfg.getBoolean(CFG_SHOWID_KEY);
    }
  }

  /**
   * This function creates a new character and requests the required information from the server.
   *
   * @param id the ID of the character to be created
   * @return the created character
   */
  private Char createNewCharacter(final CharacterId id) {
    final Char chara = Char.create();
    chara.setCharId(id);
    updateName(chara);

    addCharacter(chara);

    // request appearance from server if char is not known
    final RequestAppearanceCmd cmd =
        CommandFactory.getInstance()
            .getCommand(CommandList.CMD_REQUEST_APPEARANCE, RequestAppearanceCmd.class);
    cmd.request(id);
    World.getNet().sendCommand(cmd);
    return chara;
  }

  /**
   * Get a character out of the list of the known characters.
   *
   * @param id ID of the requested character
   * @return the character or null if it does not exist
   */
  public Char getCharacter(final CharacterId id) {
    if (isPlayerCharacter(id)) {
      return playerChar;
    }

    charsLock.readLock().lock();
    try {
      return chars.get(id);
    } finally {
      charsLock.readLock().unlock();
    }
  }

  /**
   * Get the character on a special location on the map.
   *
   * @param loc the location the character is searched at
   * @return the character or null if not found
   */
  public Char getCharacterAt(final Location loc) {
    throwNullException(loc);

    if (isPlayerCharacter(loc)) {
      return playerChar;
    }

    charsLock.readLock().lock();
    try {

      for (final Char character : chars.values()) {
        if (character.getLocation().equals(loc)) {
          return character;
        }
      }
    } finally {
      charsLock.readLock().unlock();
    }

    return null;
  }

  /**
   * Get the name of the character. Returns the last known name or someone along with the ID of the
   * character, in case its set that the IDs shall be shown.
   *
   * @param id ID of the character who's name is wanted
   * @return the name of the character or null
   */
  @SuppressWarnings("nls")
  private String getName(final CharacterId id) {
    String name = null;

    if (names != null) {
      name = names.getName(id);
    }

    if (name == null) {
      if (showIDs) {
        final TextBuilder buildName = TextBuilder.newInstance();
        buildName.setLength(0);
        buildName.append(Lang.getMsg("someone"));
        buildName.append(' ');
        buildName.append('(');
        buildName.append(id);
        buildName.append(')');
        name = buildName.toString();
        TextBuilder.recycle(buildName);
      }
    }
    return name;
  }

  /**
   * Return the short version of the name of a character.
   *
   * @param id ID of the characters whos short name is wanted
   * @return the short version of the name of the character
   */
  @SuppressWarnings("nls")
  private String getShortName(final CharacterId id) {
    String name = null;

    if (names != null) {
      name = names.getName(id);
    }

    // return the id
    if (name == null) {
      if (showIDs) {
        name = Long.toString(id.getValue());
      }
    } else { // return text up to first blank
      final int pos = name.indexOf(' ');
      if (pos > 0) {
        name = name.substring(0, pos);
      }
    }
    return name;
  }

  /**
   * Get the current settings how the name of the characters is shown.
   *
   * @return the current settings how the names are shown. Possible values are {@link #NAME_SHORT}
   *     or {@link #NAME_LONG}
   */
  public int getShowMapNames() {
    return showMapNames;
  }

  /**
   * Introduce a character and store the name in the table or overwrite a existing entry for this
   * character.
   *
   * @param id the ID of the character that shall get a name
   * @param name the name that the character shall get
   */
  public void introduce(final CharacterId id, final String name) {
    throwNullException(name);

    // update character with his name
    final Char chara = getCharacter(id);
    if (chara != null) {
      chara.setName(name);
    }

    // add name to list of known names
    names.addName(id, name);
  }

  /**
   * Check if the location is the location of the player character.
   *
   * @param loc the location to check
   * @return <code>true</code> in case the player character is set and its location equals the
   *     location supplied by the argument
   */
  private boolean isPlayerCharacter(final Location loc) {
    return (playerChar != null) && playerChar.getLocation().equals(loc);
  }

  /**
   * Check if the ID is the ID of the player character.
   *
   * @param id the id to check
   * @return <code>true</code> in case the player character is set and its ID equals the ID supplied
   *     by the argument
   */
  private boolean isPlayerCharacter(final CharacterId id) {
    return (playerChar != null) && playerChar.getCharId().equals(id);
  }

  /**
   * Process a record from the table containing the names and add the name to the name storage of
   * this class.
   *
   * @param line current line that is handled
   * @param loader table loader that loads the name table
   * @return true at all times
   */
  @Override
  public boolean processRecord(final int line, final TableLoader loader) {
    throwNullException(loader);

    names.addName(new CharacterId(loader.getLong(0)), loader.getString(1));

    return true;
  }

  /**
   * Remove a character from the game list and recycle the character reference for later usage. Also
   * clean up everything related to this character such as the attacking marker.
   *
   * @param id the ID of the character that shall be removed
   */
  public void removeCharacter(final CharacterId id) {
    throwPlayerCharacter(id);

    charsLock.writeLock().lock();
    try {
      final Char chara = chars.get(id);
      if (chara != null) {
        EventBus.publish(new CharRemovedEvent(id));
        // cancel attack when character is removed
        if (CombatHandler.getInstance().isAttacking(chara)) {
          CombatHandler.getInstance().standDown();
        }
        chars.remove(id);
        chara.recycle();
      }
    } finally {
      charsLock.writeLock().unlock();
    }
  }

  /**
   * Show a dialog that offers the possibility to send a GM report about a special character to the
   * gms.
   *
   * @param chara The character that shall be reported
   */
  public void reportCharacter(final Char chara) {
    chara.getCharId();

    // Gui.getInstance().getReportRequest().request("", new TextResponse() {
    // private static final int MINIMAL_TEXT_LENGTH = 20;

    // @Override
    // public boolean checkText(final String text) {
    // return text.length() > MINIMAL_TEXT_LENGTH;
    // }

    // @Override
    // public void textCancelled() {
    // // nothing to do
    // }

    // @Override
    // public void textConfirmed(final String text) {
    // final StringBuffer msg = new StringBuffer("!gm report ");
    // msg.append(Long.toString(charID));
    // msg.append(" ");

    // final String name = names.getName(charID);
    // if (name != null) {
    // msg.append(name);
    // msg.append(" ");
    // }
    // msg.append(text);

    // // send say command to server
    // final SayCmd cmd =
    // (SayCmd) CommandFactory.getInstance().getCommand(
    // CommandList.CMD_SAY);
    // cmd.setCharacterName(msg.toString());
    // Game.getNet().sendCommand(cmd);

    // }
    // });

  }

  /**
   * Save the table that stores the names of the characters known to the current player character.
   */
  public void saveNames() {
    names.saveTable();
  }

  /**
   * Set the character of the player.
   *
   * @param character the character of the player
   */
  public void setPlayerCharacter(final Char character) {
    playerChar = character;
  }

  /**
   * Set the settings how the name of the characters is shown.
   *
   * @param newShowMapNames the new state of the settings
   * @see People#NAME_SHORT
   * @see People#NAME_LONG
   */
  public void setShowMapNames(final int newShowMapNames) {
    showMapNames = newShowMapNames;
  }

  /**
   * This function throws a {@link IllegalArgumentException} in case the character supplied with the
   * argument is the player character.
   *
   * @param chara the character to check
   * @throws IllegalArgumentException in case the character in the argument is the player character
   */
  private void throwPlayerCharacter(final Char chara) {
    throwPlayerCharacter(chara.getCharId());
  }

  /**
   * This function throws a {@link IllegalArgumentException} in case the ID suppled by the argument
   * is the ID of the player character
   *
   * @param id the ID to test
   * @throws IllegalArgumentException in case the argument contains the ID of the player character
   */
  @SuppressWarnings("nls")
  private void throwPlayerCharacter(final CharacterId id) {
    if (isPlayerCharacter(id)) {
      throw new IllegalArgumentException("The player character can't be used here.");
    }
  }

  /** Change the name mode and toggle between no name, short name and full name. */
  public void toggleNameMode() {
    if (showMapNames == NAME_LONG) {
      IllaClient.getCfg().set(CFG_NAMEMODE_KEY, NAME_SHORT);
    } else {
      IllaClient.getCfg().set(CFG_NAMEMODE_KEY, NAME_LONG);
    }
  }

  /** Get the string representation of this instance. */
  @Override
  public String toString() {
    return String.format(TO_STRING_TEXT, chars.size());
  }

  /** Force update of light values. */
  void updateLight() {
    if (playerChar != null) {
      playerChar.updateLight(Char.LIGHT_UPDATE);
    }

    charsLock.readLock().lock();
    try {
      synchronized (GameMap.LIGHT_LOCK) {
        for (final Char character : chars.values()) {
          character.updateLight(Char.LIGHT_UPDATE);
        }
      }
    } finally {
      charsLock.readLock().unlock();
    }
  }

  /**
   * Update the name of a character, regarding the long or short name settings.
   *
   * @param chara the character that shall be updated
   */
  void updateName(final Char chara) {
    if (showMapNames == NAME_SHORT) {
      chara.setName(getShortName(chara.getCharId()));
    } else {
      chara.setName(getName(chara.getCharId()));
    }
  }
}