Пример #1
0
  private final void verify() {
    ListContainer list;
    final Iterator<ListContainer> iter = _entries.values().iterator();
    while (iter.hasNext()) {
      list = iter.next();

      for (Entry ent : list.getEntries()) {
        for (Ingredient ing : ent.getIngredients()) {
          if (!verifyIngredient(ing)) {
            LOG.warn(
                "{}: Cannot find ingredient with item ID: {} in list: {}!",
                getClass().getSimpleName(),
                ing.getItemId(),
                list.getListId());
          }
        }
        for (Ingredient ing : ent.getProducts()) {
          if (!verifyIngredient(ing)) {
            LOG.warn(
                "{}: Cannot find product with item ID: {} in list: {}!",
                getClass().getSimpleName(),
                ing.getItemId(),
                list.getListId());
          }
        }
      }
    }
  }
Пример #2
0
  @Override
  public void parseDocument(Document doc, File f) {
    try {
      int id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
      int entryId = 1;
      Node att;
      final ListContainer list = new ListContainer(id);

      for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) {
        if ("list".equalsIgnoreCase(n.getNodeName())) {
          att = n.getAttributes().getNamedItem("applyTaxes");
          list.setApplyTaxes((att != null) && Boolean.parseBoolean(att.getNodeValue()));

          att = n.getAttributes().getNamedItem("useRate");
          if (att != null) {
            try {

              list.setUseRate(Double.valueOf(att.getNodeValue()));
              if (list.getUseRate() <= 1e-6) {
                throw new NumberFormatException(
                    "The value cannot be 0"); // threat 0 as invalid value
              }
            } catch (NumberFormatException e) {
              try {
                list.setUseRate(Config.class.getField(att.getNodeValue()).getDouble(Config.class));
              } catch (Exception e1) {
                LOG.warn(
                    "{}: Unable to parse {}", getClass().getSimpleName(), doc.getLocalName(), e1);
                list.setUseRate(1.0);
              }

            } catch (DOMException e) {
              LOG.warn("{}: Unable to parse {}", getClass().getSimpleName(), doc.getLocalName(), e);
            }
          }

          att = n.getAttributes().getNamedItem("maintainEnchantment");
          list.setMaintainEnchantment((att != null) && Boolean.parseBoolean(att.getNodeValue()));

          for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) {
            if ("item".equalsIgnoreCase(d.getNodeName())) {
              Entry e = parseEntry(d, entryId++, list);
              list.getEntries().add(e);
            } else if ("npcs".equalsIgnoreCase(d.getNodeName())) {
              for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) {
                if ("npc".equalsIgnoreCase(b.getNodeName())) {
                  if (Util.isDigit(b.getTextContent())) {
                    list.allowNpc(Integer.parseInt(b.getTextContent()));
                  }
                }
              }
            }
          }
        }
      }
      _entries.put(id, list);
    } catch (Exception e) {
      LOG.error("{}: Error in file {}", getClass().getSimpleName(), f, e);
    }
  }
Пример #3
0
  /**
   * This will generate the multisell list for the items.<br>
   * There exist various parameters in multisells that affect the way they will appear:
   *
   * <ol>
   *   <li>Inventory only:
   *       <ul>
   *         <li>If true, only show items of the multisell for which the "primary" ingredients are
   *             already in the player's inventory. By "primary" ingredients we mean weapon and
   *             armor.
   *         <li>If false, show the entire list.
   *       </ul>
   *   <li>Maintain enchantment: presumably, only lists with "inventory only" set to true should
   *       sometimes have this as true. This makes no sense otherwise...
   *       <ul>
   *         <li>If true, then the product will match the enchantment level of the ingredient.<br>
   *             If the player has multiple items that match the ingredient list but the enchantment
   *             levels differ, then the entries need to be duplicated to show the products and
   *             ingredients for each enchantment level.<br>
   *             For example: If the player has a crystal staff +1 and a crystal staff +3 and goes
   *             to exchange it at the mammon, the list should have all exchange possibilities for
   *             the +1 staff, followed by all possibilities for the +3 staff.
   *         <li>If false, then any level ingredient will be considered equal and product will
   *             always be at +0
   *       </ul>
   *   <li>Apply taxes: Uses the "taxIngredient" entry in order to add a certain amount of adena to
   *       the ingredients.
   *   <li>
   *   <li>Additional product and ingredient multipliers.
   * </ol>
   *
   * @param listId
   * @param player
   * @param npc
   * @param inventoryOnly
   * @param productMultiplier
   * @param ingredientMultiplier
   */
  public final void separateAndSend(
      int listId,
      L2PcInstance player,
      L2Npc npc,
      boolean inventoryOnly,
      double productMultiplier,
      double ingredientMultiplier) {
    ListContainer template = _entries.get(listId);
    if (template == null) {
      LOG.warn(
          "{}: Cannot find list ID: {} requested by player: {}, NPC ID: {}!",
          getClass().getSimpleName(),
          listId,
          player,
          (npc != null ? npc.getId() : 0));
      return;
    }

    if (((npc != null) && !template.isNpcAllowed(npc.getId()))
        || ((npc == null) && template.isNpcOnly())) {
      LOG.warn(
          "{}: Player {} attempted to open multisell {} from npc {} which is not allowed!",
          getClass().getSimpleName(),
          player,
          listId,
          npc);
      return;
    }

    final PreparedListContainer list =
        new PreparedListContainer(template, inventoryOnly, player, npc);

    // Pass through this only when multipliers are different from 1
    if ((productMultiplier != 1) || (ingredientMultiplier != 1)) {
      list.getEntries()
          .forEach(
              entry -> {
                // Math.max used here to avoid dropping count to 0
                entry
                    .getProducts()
                    .forEach(
                        product ->
                            product.setItemCount(
                                (long) Math.max(product.getItemCount() * productMultiplier, 1)));

                // Math.max used here to avoid dropping count to 0
                entry
                    .getIngredients()
                    .forEach(
                        ingredient ->
                            ingredient.setItemCount(
                                (long)
                                    Math.max(ingredient.getItemCount() * ingredientMultiplier, 1)));
              });
    }
    int index = 0;
    do {
      // send list at least once even if size = 0
      player.sendPacket(new MultiSellList(list, index));
      index += PAGE_SIZE;
    } while (index < list.getEntries().size());

    player.setMultiSell(list);
  }