Ejemplo n.º 1
0
  /**
   * Use the sit action.
   *
   * @param activeChar the player trying to sit
   * @param target the target to sit, throne, bench or chair
   * @return {@code true} if the player can sit, {@code false} otherwise
   */
  protected boolean useSit(L2PcInstance activeChar, L2Object target) {
    if (activeChar.getMountType() != MountType.NONE) {
      return false;
    }

    if (!activeChar.isSitting()
        && (target instanceof L2StaticObjectInstance)
        && (((L2StaticObjectInstance) target).getType() == 1)
        && activeChar.isInsideRadius(
            target, L2StaticObjectInstance.INTERACTION_DISTANCE, false, false)) {
      final ChairSit cs = new ChairSit(activeChar, target.getId());
      sendPacket(cs);
      activeChar.sitDown();
      activeChar.broadcastPacket(cs);
      return true;
    }

    if (activeChar.isFakeDeath()) {
      activeChar.stopEffects(L2EffectType.FAKE_DEATH);
    } else if (activeChar.isSitting()) {
      activeChar.standUp();
    } else {
      activeChar.sitDown();
    }
    return true;
  }
Ejemplo n.º 2
0
  /**
   * Did a situation occur in which the duel has to be ended?
   *
   * @return DuelResult duel status
   */
  public DuelResult checkEndDuelCondition() {
    // one of the players might leave during duel
    if ((_playerA == null) || (_playerB == null)) {
      return DuelResult.Canceled;
    }

    // got a duel surrender request?
    if (_surrenderRequest != 0) {
      if (_surrenderRequest == 1) {
        return DuelResult.Team1Surrender;
      }
      return DuelResult.Team2Surrender;
    }
    // duel timed out
    else if (getRemainingTime() <= 0) {
      return DuelResult.Timeout;
    }
    // Has a player been declared winner yet?
    else if (_playerA.getDuelState() == DUELSTATE_WINNER) {
      // If there is a Winner already there should be no more fighting going on
      stopFighting();
      return DuelResult.Team1Win;
    } else if (_playerB.getDuelState() == DUELSTATE_WINNER) {
      // If there is a Winner already there should be no more fighting going on
      stopFighting();
      return DuelResult.Team2Win;
    }

    // More end duel conditions for 1on1 duels
    else if (!_partyDuel) {
      // Duel was interrupted e.g.: player was attacked by mobs / other players
      if ((_playerA.getDuelState() == DUELSTATE_INTERRUPTED)
          || (_playerB.getDuelState() == DUELSTATE_INTERRUPTED)) {
        return DuelResult.Canceled;
      }

      // Are the players too far apart?
      if (!_playerA.isInsideRadius(_playerB, 1600, false, false)) {
        return DuelResult.Canceled;
      }

      // Did one of the players engage in PvP combat?
      if (isDuelistInPvp(true)) {
        return DuelResult.Canceled;
      }

      // is one of the players in a Siege, Peace or PvP zone?
      if (_playerA.isInsideZone(ZoneId.PEACE)
          || _playerB.isInsideZone(ZoneId.PEACE)
          || _playerA.isInsideZone(ZoneId.SIEGE)
          || _playerB.isInsideZone(ZoneId.SIEGE)
          || _playerA.isInsideZone(ZoneId.PVP)
          || _playerB.isInsideZone(ZoneId.PVP)) {
        return DuelResult.Canceled;
      }
    }

    return DuelResult.Continue;
  }
Ejemplo n.º 3
0
  /** Handle chat type 'all' */
  @Override
  public void handleChat(int type, L2PcInstance activeChar, String params, String text) {
    boolean vcd_used = false;
    if (text.startsWith(".")) {
      StringTokenizer st = new StringTokenizer(text);
      IVoicedCommandHandler vch;
      String command = "";

      if (st.countTokens() > 1) {
        command = st.nextToken().substring(1);
        params = text.substring(command.length() + 2);
        vch = VoicedCommandHandler.getInstance().getHandler(command);
      } else {
        command = text.substring(1);
        if (Config.DEBUG) {
          _log.info("Command: " + command);
        }
        vch = VoicedCommandHandler.getInstance().getHandler(command);
      }
      if (vch != null) {
        vch.useVoicedCommand(command, activeChar, params);
        vcd_used = true;
      } else {
        if (Config.DEBUG) {
          _log.warning("No handler registered for bypass '" + command + "'");
        }
        vcd_used = false;
      }
    }
    if (!vcd_used) {
      if (activeChar.isChatBanned() && Util.contains(Config.BAN_CHAT_CHANNELS, type)) {
        activeChar.sendPacket(SystemMessageId.CHATTING_IS_CURRENTLY_PROHIBITED);
        return;
      }

      /**
       * Match the character "." literally (Exactly 1 time) Match any character that is NOT a .
       * character. Between one and unlimited times as possible, giving back as needed (greedy)
       */
      if (text.matches("\\.{1}[^\\.]+")) {
        activeChar.sendPacket(SystemMessageId.INCORRECT_SYNTAX);
      } else {
        CreatureSay cs =
            new CreatureSay(
                activeChar.getObjectId(), type, activeChar.getAppearance().getVisibleName(), text);
        Collection<L2PcInstance> plrs = activeChar.getKnownList().getKnownPlayers().values();
        for (L2PcInstance player : plrs) {
          if ((player != null)
              && activeChar.isInsideRadius(player, 1250, false, true)
              && !BlockList.isBlocked(player, activeChar)) {
            player.sendPacket(cs);
          }
        }

        activeChar.sendPacket(cs);
      }
    }
  }
  @Override
  public final boolean useBypass(String command, L2PcInstance activeChar, L2Character target) {
    try {
      final L2Npc olymanager = activeChar.getLastFolkNPC();

      if (command.startsWith(COMMANDS[0])) // list
      {
        if (!Olympiad.getInstance().inCompPeriod()) {
          activeChar.sendPacket(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
          return false;
        }

        activeChar.sendPacket(new ExOlympiadMatchList());
      } else {
        if ((olymanager == null) || !(olymanager instanceof L2OlympiadManagerInstance)) {
          return false;
        }

        if (!activeChar.inObserverMode()
            && !activeChar.isInsideRadius(olymanager, 300, false, false)) {
          return false;
        }

        if (OlympiadManager.getInstance().isRegisteredInComp(activeChar)) {
          activeChar.sendPacket(
              SystemMessageId
                  .WHILE_YOU_ARE_ON_THE_WAITING_LIST_YOU_ARE_NOT_ALLOWED_TO_WATCH_THE_GAME);
          return false;
        }

        if (!Olympiad.getInstance().inCompPeriod()) {
          activeChar.sendPacket(SystemMessageId.THE_OLYMPIAD_GAME_IS_NOT_CURRENTLY_IN_PROGRESS);
          return false;
        }

        if (activeChar.isOnEvent()) {
          activeChar.sendMessage("You can not observe games while registered on an event");
          return false;
        }

        final int arenaId = Integer.parseInt(command.substring(12).trim());
        final OlympiadGameTask nextArena =
            OlympiadGameManager.getInstance().getOlympiadTask(arenaId);
        if (nextArena != null) {
          activeChar.enterOlympiadObserverMode(
              nextArena.getZone().getSpectatorSpawns().get(0), arenaId);
          activeChar.setInstanceId(
              OlympiadGameManager.getInstance().getOlympiadTask(arenaId).getZone().getInstanceId());
        }
      }
      return true;

    } catch (Exception e) {
      _log.log(Level.WARNING, "Exception in " + getClass().getSimpleName(), e);
    }
    return false;
  }
Ejemplo n.º 5
0
  @Override
  public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon) {
    if (player.getClan() == null) {
      return null;
    }

    QuestState st = null;
    if (player.isClanLeader()) {
      st = getQuestState(player, false);
    } else {
      L2PcInstance pleader = player.getClan().getLeader().getPlayerInstance();
      if ((pleader != null) && player.isInsideRadius(pleader, 1500, true, false)) {
        st = getQuestState(pleader, false);
      }
    }

    if ((st != null) && st.isStarted()) {
      st.rewardItems(TYRANNOSAURUS_CLAW, 1);
      st.playSound(QuestSound.ITEMSOUND_QUEST_ITEMGET);
    }
    return null;
  }
Ejemplo n.º 6
0
 protected void StartRace() {
   // Abort race if no players signup
   if (_players.isEmpty()) {
     Broadcast.toAllOnlinePlayers("Race aborted, nobody signup.");
     eventStop();
     return;
   }
   // Set state
   _isRaceStarted = true;
   // Announce
   Broadcast.toAllOnlinePlayers("Race started!");
   // Get random Finish
   int location = getRandom(0, _locations.length - 1);
   _randspawn = _coords[location];
   // And spawn NPC
   recordSpawn(_stop_npc, _randspawn[0], _randspawn[1], _randspawn[2], _randspawn[3], false, 0);
   // Transform players and send message
   for (L2PcInstance player : _players) {
     if ((player != null) && player.isOnline()) {
       if (player.isInsideRadius(_npc, 500, false, false)) {
         sendMessage(
             player,
             "Race started! Go find Finish NPC as fast as you can... He is located near "
                 + _locations[location]);
         transformPlayer(player);
         player.getRadar().addMarker(_randspawn[0], _randspawn[1], _randspawn[2]);
       } else {
         sendMessage(
             player,
             "I told you stay near me right? Distance was too high, you are excluded from race");
         _players.remove(player);
       }
     }
   }
   // Schedule timeup for Race
   _eventTask =
       ThreadPoolManager.getInstance().scheduleGeneral(() -> timeUp(), _time_race * 60 * 1000);
 }
Ejemplo n.º 7
0
  @Override
  protected void runImpl() {
    L2PcInstance activeChar = getClient().getActiveChar();
    L2PcInstance targetChar = L2World.getInstance().getPlayer(_player);
    if (activeChar == null) {
      return;
    }
    if (targetChar == null) {
      activeChar.sendPacket(
          SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
      return;
    }
    if (activeChar == targetChar) {
      activeChar.sendPacket(
          SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
      return;
    }

    // Check if duel is possible
    if (!activeChar.canDuel()) {
      activeChar.sendPacket(SystemMessageId.YOU_ARE_UNABLE_TO_REQUEST_A_DUEL_AT_THIS_TIME);
      return;
    } else if (!targetChar.canDuel()) {
      activeChar.sendPacket(targetChar.getNoDuelReason());
      return;
    }
    // Players may not be too far apart
    else if (!activeChar.isInsideRadius(targetChar, 250, false, false)) {
      SystemMessage msg =
          SystemMessage.getSystemMessage(
              SystemMessageId.C1_IS_TOO_FAR_AWAY_TO_RECEIVE_A_DUEL_CHALLENGE);
      msg.addString(targetChar.getName());
      activeChar.sendPacket(msg);
      return;
    } else if (Config.FACTION_SYSTEM_ENABLED
        && ((activeChar.isEvil() && targetChar.isGood())
            || (activeChar.isGood() && targetChar.isEvil()))) {
      activeChar.sendPacket(SystemMessageId.YOU_ARE_UNABLE_TO_REQUEST_A_DUEL_AT_THIS_TIME);
      return;
    }

    // Duel is a party duel
    if (_partyDuel == 1) {
      // Player must be in a party & the party leader
      if (!activeChar.isInParty() || !activeChar.getParty().isLeader(activeChar)) {
        activeChar.sendMessage(
            "You have to be the leader of a party in order to request a party duel.");
        return;
      }
      // Target must be in a party
      else if (!targetChar.isInParty()) {
        activeChar.sendPacket(
            SystemMessageId
                .SINCE_THE_PERSON_YOU_CHALLENGED_IS_NOT_CURRENTLY_IN_A_PARTY_THEY_CANNOT_DUEL_AGAINST_YOUR_PARTY);
        return;
      }
      // Target may not be of the same party
      else if (activeChar.getParty().containsPlayer(targetChar)) {
        activeChar.sendMessage("This player is a member of your own party.");
        return;
      }

      // Check if every player is ready for a duel
      for (L2PcInstance temp : activeChar.getParty().getMembers()) {
        if (!temp.canDuel()) {
          activeChar.sendMessage("Not all the members of your party are ready for a duel.");
          return;
        }
      }
      L2PcInstance partyLeader = null; // snatch party leader of targetChar's party
      for (L2PcInstance temp : targetChar.getParty().getMembers()) {
        if (partyLeader == null) {
          partyLeader = temp;
        }
        if (!temp.canDuel()) {
          activeChar.sendPacket(
              SystemMessageId
                  .THE_OPPOSING_PARTY_IS_CURRENTLY_UNABLE_TO_ACCEPT_A_CHALLENGE_TO_A_DUEL);
          return;
        }
      }

      // Send request to targetChar's party leader
      if (partyLeader != null) {
        if (!partyLeader.isProcessingRequest()) {
          activeChar.onTransactionRequest(partyLeader);
          partyLeader.sendPacket(new ExDuelAskStart(activeChar.getName(), _partyDuel));

          if (Config.DEBUG) {
            _log.fine(activeChar.getName() + " requested a duel with " + partyLeader.getName());
          }

          SystemMessage msg =
              SystemMessage.getSystemMessage(
                  SystemMessageId.C1_S_PARTY_HAS_BEEN_CHALLENGED_TO_A_DUEL);
          msg.addString(partyLeader.getName());
          activeChar.sendPacket(msg);

          msg =
              SystemMessage.getSystemMessage(
                  SystemMessageId.C1_S_PARTY_HAS_CHALLENGED_YOUR_PARTY_TO_A_DUEL);
          msg.addString(activeChar.getName());
          targetChar.sendPacket(msg);
        } else {
          SystemMessage msg =
              SystemMessage.getSystemMessage(
                  SystemMessageId.C1_IS_ON_ANOTHER_TASK_PLEASE_TRY_AGAIN_LATER);
          msg.addString(partyLeader.getName());
          activeChar.sendPacket(msg);
        }
      }
    } else
    // 1vs1 duel
    {
      if (!targetChar.isProcessingRequest()) {
        activeChar.onTransactionRequest(targetChar);
        targetChar.sendPacket(new ExDuelAskStart(activeChar.getName(), _partyDuel));

        if (Config.DEBUG) {
          _log.fine(activeChar.getName() + " requested a duel with " + targetChar.getName());
        }

        SystemMessage msg =
            SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_BEEN_CHALLENGED_TO_A_DUEL);
        msg.addString(targetChar.getName());
        activeChar.sendPacket(msg);

        msg = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_CHALLENGED_YOU_TO_A_DUEL);
        msg.addString(activeChar.getName());
        targetChar.sendPacket(msg);
      } else {
        SystemMessage msg =
            SystemMessage.getSystemMessage(
                SystemMessageId.C1_IS_ON_ANOTHER_TASK_PLEASE_TRY_AGAIN_LATER);
        msg.addString(targetChar.getName());
        activeChar.sendPacket(msg);
      }
    }
  }
Ejemplo n.º 8
0
  @Override
  public boolean useBypass(String command, L2PcInstance activeChar, L2Character target) {
    final L2Npc manager = activeChar.getLastFolkNPC();
    if (!((manager instanceof L2ManorManagerInstance))) {
      return false;
    }

    if (!activeChar.isInsideRadius(manager, L2Npc.INTERACTION_DISTANCE, true, false)) {
      return false;
    }

    try {
      final Castle castle = manager.getCastle();
      if (CastleManorManager.getInstance().isUnderMaintenance()) {
        activeChar.sendPacket(ActionFailed.STATIC_PACKET);
        activeChar.sendPacket(SystemMessageId.THE_MANOR_SYSTEM_IS_CURRENTLY_UNDER_MAINTENANCE);
        return true;
      }

      final StringTokenizer st = new StringTokenizer(command, "&");
      final int ask = Integer.parseInt(st.nextToken().split("=")[1]);
      final int state = Integer.parseInt(st.nextToken().split("=")[1]);
      final int time = Integer.parseInt(st.nextToken().split("=")[1]);

      final int castleId;
      if (state < 0) {
        castleId = castle.getResidenceId(); // info for current manor
      } else {
        castleId = state; // info for requested manor
      }

      switch (ask) {
        case 1: // Seed purchase
          if (castleId != castle.getResidenceId()) {
            SystemMessage sm =
                SystemMessage.getSystemMessage(
                    SystemMessageId.HERE_YOU_CAN_BUY_ONLY_SEEDS_OF_S1_MANOR);
            sm.addString(manager.getCastle().getName());
            activeChar.sendPacket(sm);
          } else {
            activeChar.sendPacket(
                new BuyListSeed(
                    activeChar.getAdena(),
                    castleId,
                    castle.getSeedProduction(CastleManorManager.PERIOD_CURRENT)));
          }
          break;
        case 2: // Crop sales
          activeChar.sendPacket(
              new ExShowSellCropList(
                  activeChar, castleId, castle.getCropProcure(CastleManorManager.PERIOD_CURRENT)));
          break;
        case 3: // Current seeds (Manor info)
          if ((time == 1)
              && !CastleManager.getInstance().getCastleById(castleId).isNextPeriodApproved()) {
            activeChar.sendPacket(new ExShowSeedInfo(castleId, null));
          } else {
            activeChar.sendPacket(
                new ExShowSeedInfo(
                    castleId,
                    CastleManager.getInstance().getCastleById(castleId).getSeedProduction(time)));
          }
          break;
        case 4: // Current crops (Manor info)
          if ((time == 1)
              && !CastleManager.getInstance().getCastleById(castleId).isNextPeriodApproved()) {
            activeChar.sendPacket(new ExShowCropInfo(castleId, null));
          } else {
            activeChar.sendPacket(
                new ExShowCropInfo(
                    castleId,
                    CastleManager.getInstance().getCastleById(castleId).getCropProcure(time)));
          }
          break;
        case 5: // Basic info (Manor info)
          activeChar.sendPacket(new ExShowManorDefaultInfo());
          break;
        case 6: // Buy harvester
          ((L2MerchantInstance) manager).showBuyWindow(activeChar, 300000 + manager.getId());
          break;
        case 9: // Edit sales (Crop sales)
          activeChar.sendPacket(new ExShowProcureCropDetail(state));
          break;
        default:
          return false;
      }
      return true;
    } catch (Exception e) {
      _log.log(Level.WARNING, "Exception in " + getClass().getSimpleName(), e);
    }
    return false;
  }
Ejemplo n.º 9
0
  @Override
  public void runImpl() {
    final L2PcInstance player = getClient().getActiveChar();
    if (player == null) {
      return;
    }

    if (!getClient().getFloodProtectors().getMultiSell().tryPerformAction("multisell choose")) {
      player.setMultiSell(null);
      return;
    }

    if ((_amount < 1) || (_amount > 5000)) {
      player.setMultiSell(null);
      return;
    }

    PreparedListContainer list = player.getMultiSell();
    if ((list == null) || (list.getListId() != _listId)) {
      player.setMultiSell(null);
      return;
    }

    final L2Npc npc = player.getLastFolkNPC();
    if (((npc != null) && !list.isNpcAllowed(npc.getId())) || ((npc == null) && list.isNpcOnly())) {
      player.setMultiSell(null);
      return;
    }

    if (!player.isGM() && (npc != null)) {
      if (!player.isInsideRadius(npc, INTERACTION_DISTANCE, true, false)
          || (player.getInstanceId() != npc.getInstanceId())) {
        player.setMultiSell(null);
        return;
      }
    }

    for (Entry entry : list.getEntries()) {
      if (entry.getEntryId() == _entryId) {
        if (!entry.isStackable() && (_amount > 1)) {
          _log.severe(
              "Character: "
                  + player.getName()
                  + " is trying to set amount > 1 on non-stackable multisell, id:"
                  + _listId
                  + ":"
                  + _entryId);
          player.setMultiSell(null);
          return;
        }

        final PcInventory inv = player.getInventory();

        int slots = 0;
        int weight = 0;
        for (Ingredient e : entry.getProducts()) {
          if (e.getItemId() < 0) {
            continue;
          }

          if (!e.isStackable()) {
            slots += e.getItemCount() * _amount;
          } else if (player.getInventory().getItemByItemId(e.getItemId()) == null) {
            slots++;
          }
          weight += e.getItemCount() * _amount * e.getWeight();
        }

        if (!inv.validateWeight(weight)) {
          player.sendPacket(SystemMessageId.WEIGHT_LIMIT_EXCEEDED);
          return;
        }

        if (!inv.validateCapacity(slots)) {
          player.sendPacket(SystemMessageId.SLOTS_FULL);
          return;
        }

        ArrayList<Ingredient> ingredientsList = new ArrayList<>(entry.getIngredients().size());
        // Generate a list of distinct ingredients and counts in order to check if the correct
        // item-counts
        // are possessed by the player
        boolean newIng;
        for (Ingredient e : entry.getIngredients()) {
          newIng = true;
          // at this point, the template has already been modified so that enchantments are properly
          // included
          // whenever they need to be applied. Uniqueness of items is thus judged by item id AND
          // enchantment level
          for (int i = ingredientsList.size(); --i >= 0; ) {
            Ingredient ex = ingredientsList.get(i);
            // if the item was already added in the list, merely increment the count
            // this happens if 1 list entry has the same ingredient twice (example 2 swords = 1
            // dual)
            if ((ex.getItemId() == e.getItemId())
                && (ex.getEnchantLevel() == e.getEnchantLevel())) {
              if ((ex.getItemCount() + e.getItemCount()) > Integer.MAX_VALUE) {
                player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_QUANTITY_THAT_CAN_BE_INPUTTED);
                return;
              }
              // two same ingredients, merge into one and replace old
              final Ingredient ing = ex.getCopy();
              ing.setItemCount(ex.getItemCount() + e.getItemCount());
              ingredientsList.set(i, ing);
              newIng = false;
              break;
            }
          }
          if (newIng) {
            // if it's a new ingredient, just store its info directly (item id, count, enchantment)
            ingredientsList.add(e);
          }
        }

        // now check if the player has sufficient items in the inventory to cover the ingredients'
        // expences
        for (Ingredient e : ingredientsList) {
          if ((e.getItemCount() * _amount) > Integer.MAX_VALUE) {
            player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_QUANTITY_THAT_CAN_BE_INPUTTED);
            return;
          }
          if (e.getItemId() < 0) {
            if (!MultisellData.hasSpecialIngredient(
                e.getItemId(), e.getItemCount() * _amount, player)) {
              return;
            }
          } else {
            // if this is not a list that maintains enchantment, check the count of all items that
            // have the given id.
            // otherwise, check only the count of items with exactly the needed enchantment level
            final long required =
                ((Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient())
                    ? (e.getItemCount() * _amount)
                    : e.getItemCount());
            if (inv.getInventoryItemCount(
                    e.getItemId(), list.getMaintainEnchantment() ? e.getEnchantLevel() : -1, false)
                < required) {
              SystemMessage sm =
                  SystemMessage.getSystemMessage(SystemMessageId.S2_UNIT_OF_THE_ITEM_S1_REQUIRED);
              sm.addItemName(e.getTemplate());
              sm.addLong(required);
              player.sendPacket(sm);
              return;
            }
          }
        }

        List<L2Augmentation> augmentation = new ArrayList<>();
        Elementals[] elemental = null;
        /** All ok, remove items and add final product */
        for (Ingredient e : entry.getIngredients()) {
          if (e.getItemId() < 0) {
            if (!MultisellData.takeSpecialIngredient(
                e.getItemId(), e.getItemCount() * _amount, player)) {
              return;
            }
          } else {
            L2ItemInstance itemToTake =
                inv.getItemByItemId(
                    e.getItemId()); // initialize and initial guess for the item to take.
            if (itemToTake
                == null) { // this is a cheat, transaction will be aborted and if any items already
                           // taken will not be returned back to inventory!
              _log.severe(
                  "Character: "
                      + player.getName()
                      + " is trying to cheat in multisell, id:"
                      + _listId
                      + ":"
                      + _entryId);
              player.setMultiSell(null);
              return;
            }

            // if (itemToTake.isEquipped())
            // {
            // this is a cheat, transaction will be aborted and if any items already taken will not
            // be returned back to inventory!
            // _log.severe("Character: " + player.getName() + " is trying to cheat in multisell,
            // exchanging equipped item, merchatnt id:" + merchant.getNpcId());
            // player.setMultiSell(null);
            // return;
            // }

            if (Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) {
              // if it's a stackable item, just reduce the amount from the first (only) instance
              // that is found in the inventory
              if (itemToTake.isStackable()) {
                if (!player.destroyItem(
                    "Multisell",
                    itemToTake.getObjectId(),
                    (e.getItemCount() * _amount),
                    player.getTarget(),
                    true)) {
                  player.setMultiSell(null);
                  return;
                }
              } else {
                // for non-stackable items, one of two scenaria are possible:
                // a) list maintains enchantment: get the instances that exactly match the requested
                // enchantment level
                // b) list does not maintain enchantment: get the instances with the LOWEST
                // enchantment level

                // a) if enchantment is maintained, then get a list of items that exactly match this
                // enchantment
                if (list.getMaintainEnchantment()) {
                  // loop through this list and remove (one by one) each item until the required
                  // amount is taken.
                  L2ItemInstance[] inventoryContents =
                      inv.getAllItemsByItemId(e.getItemId(), e.getEnchantLevel(), false);
                  for (int i = 0; i < (e.getItemCount() * _amount); i++) {
                    if (inventoryContents[i].isAugmented()) {
                      augmentation.add(inventoryContents[i].getAugmentation());
                    }
                    if (inventoryContents[i].getElementals() != null) {
                      elemental = inventoryContents[i].getElementals();
                    }
                    if (!player.destroyItem(
                        "Multisell",
                        inventoryContents[i].getObjectId(),
                        1,
                        player.getTarget(),
                        true)) {
                      player.setMultiSell(null);
                      return;
                    }
                  }
                } else
                // b) enchantment is not maintained. Get the instances with the LOWEST enchantment
                // level
                {
                  // NOTE: There are 2 ways to achieve the above goal.
                  // 1) Get all items that have the correct itemId, loop through them until the
                  // lowest enchantment
                  // level is found. Repeat all this for the next item until proper count of items
                  // is reached.
                  // 2) Get all items that have the correct itemId, sort them once based on
                  // enchantment level,
                  // and get the range of items that is necessary.
                  // Method 1 is faster for a small number of items to be exchanged.
                  // Method 2 is faster for large amounts.
                  //
                  // EXPLANATION:
                  // Worst case scenario for algorithm 1 will make it run in a number of cycles
                  // given by:
                  // m*(2n-m+1)/2 where m is the number of items to be exchanged and n is the total
                  // number of inventory items that have a matching id.
                  // With algorithm 2 (sort), sorting takes n*log(n) time and the choice is done in
                  // a single cycle
                  // for case b (just grab the m first items) or in linear time for case a (find the
                  // beginning of items
                  // with correct enchantment, index x, and take all items from x to x+m).
                  // Basically, whenever m > log(n) we have: m*(2n-m+1)/2 = (2nm-m*m+m)/2 >
                  // (2nlogn-logn*logn+logn)/2 = nlog(n) - log(n*n) + log(n) = nlog(n) + log(n/n*n)
                  // =
                  // nlog(n) + log(1/n) = nlog(n) - log(n) = (n-1)log(n)
                  // So for m < log(n) then m*(2n-m+1)/2 > (n-1)log(n) and m*(2n-m+1)/2 > nlog(n)
                  //
                  // IDEALLY:
                  // In order to best optimize the performance, choose which algorithm to run, based
                  // on whether 2^m > n
                  // if ( (2<<(e.getItemCount()// _amount)) < inventoryContents.length )
                  // // do Algorithm 1, no sorting
                  // else
                  // // do Algorithm 2, sorting
                  //
                  // CURRENT IMPLEMENTATION:
                  // In general, it is going to be very rare for a person to do a massive exchange
                  // of non-stackable items
                  // For this reason, we assume that algorithm 1 will always suffice and we keep
                  // things simple.
                  // If, in the future, it becomes necessary that we optimize, the above discussion
                  // should make it clear
                  // what optimization exactly is necessary (based on the comments under "IDEALLY").
                  //

                  // choice 1. Small number of items exchanged. No sorting.
                  for (int i = 1; i <= (e.getItemCount() * _amount); i++) {
                    L2ItemInstance[] inventoryContents =
                        inv.getAllItemsByItemId(e.getItemId(), false);

                    itemToTake = inventoryContents[0];
                    // get item with the LOWEST enchantment level from the inventory...
                    // +0 is lowest by default...
                    if (itemToTake.getEnchantLevel() > 0) {
                      for (L2ItemInstance item : inventoryContents) {
                        if (item.getEnchantLevel() < itemToTake.getEnchantLevel()) {
                          itemToTake = item;
                          // nothing will have enchantment less than 0. If a zero-enchanted
                          // item is found, just take it
                          if (itemToTake.getEnchantLevel() == 0) {
                            break;
                          }
                        }
                      }
                    }
                    if (!player.destroyItem(
                        "Multisell", itemToTake.getObjectId(), 1, player.getTarget(), true)) {
                      player.setMultiSell(null);
                      return;
                    }
                  }
                }
              }
            }
          }
        }

        // Generate the appropriate items
        for (Ingredient e : entry.getProducts()) {
          if (e.getItemId() < 0) {
            MultisellData.giveSpecialProduct(e.getItemId(), e.getItemCount() * _amount, player);
          } else {
            if (e.isStackable()) {
              inv.addItem(
                  "Multisell",
                  e.getItemId(),
                  e.getItemCount() * _amount,
                  player,
                  player.getTarget());
            } else {
              L2ItemInstance product = null;
              for (int i = 0; i < (e.getItemCount() * _amount); i++) {
                product = inv.addItem("Multisell", e.getItemId(), 1, player, player.getTarget());
                if ((product != null) && list.getMaintainEnchantment()) {
                  if (i < augmentation.size()) {
                    product.setAugmentation(
                        new L2Augmentation(augmentation.get(i).getAugmentationId()));
                  }
                  if (elemental != null) {
                    for (Elementals elm : elemental) {
                      product.setElementAttr(elm.getElement(), elm.getValue());
                    }
                  }
                  product.setEnchantLevel(e.getEnchantLevel());
                  product.updateDatabase();
                }
              }
            }
            // msg part
            SystemMessage sm;

            if ((e.getItemCount() * _amount) > 1) {
              sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
              sm.addItemName(e.getItemId());
              sm.addLong(e.getItemCount() * _amount);
              player.sendPacket(sm);
            } else {
              if (list.getMaintainEnchantment() && (e.getEnchantLevel() > 0)) {
                sm = SystemMessage.getSystemMessage(SystemMessageId.ACQUIRED_S1_S2);
                sm.addLong(e.getEnchantLevel());
                sm.addItemName(e.getItemId());
              } else {
                sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
                sm.addItemName(e.getItemId());
              }
              player.sendPacket(sm);
            }
          }
        }
        player.sendPacket(new ItemList(player, false));

        StatusUpdate su = new StatusUpdate(player);
        su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
        player.sendPacket(su);

        // finally, give the tax to the castle...
        if ((npc != null) && (entry.getTaxAmount() > 0)) {
          npc.getCastle().addToTreasury(entry.getTaxAmount() * _amount);
        }
        break;
      }
    }
  }
  @Override
  public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) {
    switch (event) {
      case "31862-04.html":
        {
          return event;
        }
      case "enter":
        {
          String htmltext = null;
          if (getStatus() == DEAD) {
            htmltext = "31862-03.html";
          } else if (getStatus() == IN_FIGHT) {
            htmltext = "31862-02.html";
          } else if (!hasQuestItems(player, FABRIC)) {
            htmltext = "31862-01.html";
          } else {
            takeItems(player, FABRIC, 1);
            player.teleToLocation(TELEPORT_IN_LOC);
          }
          return htmltext;
        }
      case "teleportOut":
        {
          final Location destination = TELEPORT_OUT_LOC[getRandom(TELEPORT_OUT_LOC.length)];
          player.teleToLocation(
              destination.getX() + getRandom(100),
              destination.getY() + getRandom(100),
              destination.getZ());
          break;
        }
      case "wakeUp":
        {
          if (getStatus() == ALIVE) {
            npc.deleteMe();
            setStatus(IN_FIGHT);
            _baium = (L2GrandBossInstance) addSpawn(BAIUM, BAIUM_LOC, false, 0);
            _baium.disableCoreAI(true);
            addBoss(_baium);
            _lastAttack = System.currentTimeMillis();
            startQuestTimer("WAKEUP_ACTION", 50, _baium, null);
            startQuestTimer("MANAGE_EARTHQUAKE", 2000, _baium, null);
            startQuestTimer("CHECK_ATTACK", 60000, _baium, null);
          }
          break;
        }
      case "WAKEUP_ACTION":
        {
          if (npc != null) {
            zone.broadcastPacket(new SocialAction(_baium.getObjectId(), 2));
          }
          break;
        }
      case "MANAGE_EARTHQUAKE":
        {
          if (npc != null) {
            zone.broadcastPacket(new Earthquake(npc.getX(), npc.getY(), npc.getZ(), 40, 10));
            zone.broadcastPacket(new PlaySound("BS02_A"));
            startQuestTimer("SOCIAL_ACTION", 8000, npc, player);
          }
          break;
        }
      case "SOCIAL_ACTION":
        {
          if (npc != null) {
            zone.broadcastPacket(new SocialAction(npc.getObjectId(), 3));
            startQuestTimer("PLAYER_PORT", 6000, npc, player);
          }
          break;
        }
      case "PLAYER_PORT":
        {
          if (npc != null) {
            if ((player != null) && player.isInsideRadius(npc, 16000, true, false)) {
              player.teleToLocation(BAIUM_GIFT_LOC);
              startQuestTimer("PLAYER_KILL", 3000, npc, player);
            } else if ((_standbyPlayer != null)
                && _standbyPlayer.isInsideRadius(npc, 16000, true, false)) {
              _standbyPlayer.teleToLocation(BAIUM_GIFT_LOC);
              startQuestTimer("PLAYER_KILL", 3000, npc, _standbyPlayer);
            }
          }
          break;
        }
      case "PLAYER_KILL":
        {
          if ((player != null) && player.isInsideRadius(npc, 16000, true, false)) {
            zone.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
            broadcastNpcSay(
                npc,
                Say2.NPC_ALL,
                player.getName()
                    + ", How dare you wake me! Now you shall die!"); // TODO: replace with
                                                                     // NpcStringId when are done
                                                                     // core support
            npc.setTarget(player);
            npc.doCast(BAIUM_PRESENT.getSkill());
          }

          for (L2PcInstance players : zone.getPlayersInside()) {
            if (players.isHero()) {
              zone.broadcastPacket(
                  new ExShowScreenMessage(
                      NpcStringId
                          .NOT_EVEN_THE_GODS_THEMSELVES_COULD_TOUCH_ME_BUT_YOU_S1_YOU_DARE_CHALLENGE_ME_IGNORANT_MORTAL,
                      2,
                      4000,
                      players.getName()));
              break;
            }
          }
          startQuestTimer("SPAWN_ARCHANGEL", 8000, npc, null);
          break;
        }
      case "SPAWN_ARCHANGEL":
        {
          _baium.disableCoreAI(false);

          for (Location loc : ARCHANGEL_LOC) {
            final L2Npc archangel = addSpawn(ARCHANGEL, loc, false, 0, true);
            startQuestTimer("SELECT_TARGET", 5000, archangel, null);
          }

          if ((player != null) && !player.isDead()) {
            attackPlayer((L2Attackable) npc, player);
          } else if ((_standbyPlayer != null) && !_standbyPlayer.isDead()) {
            attackPlayer((L2Attackable) npc, _standbyPlayer);
          } else {
            for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(2000)) {
              if ((characters != null)
                  && characters.isPlayer()
                  && zone.isInsideZone(characters)
                  && !characters.isDead()) {
                attackPlayer((L2Attackable) npc, (L2Playable) characters);
                break;
              }
            }
          }
          break;
        }
      case "SELECT_TARGET":
        {
          if (npc != null) {
            final L2Attackable mob = (L2Attackable) npc;
            final L2Character mostHated = mob.getMostHated();

            if ((_baium == null) || _baium.isDead()) {
              mob.deleteMe();
              break;
            }

            if ((mostHated != null) && mostHated.isPlayer() && zone.isInsideZone(mostHated)) {
              if (mob.getTarget() != mostHated) {
                mob.clearAggroList();
              }
              attackPlayer(mob, (L2Playable) mostHated);
            } else {
              boolean found = false;
              for (L2Character characters : mob.getKnownList().getKnownCharactersInRadius(1000)) {
                if ((characters != null)
                    && characters.isPlayable()
                    && zone.isInsideZone(characters)
                    && !characters.isDead()) {
                  if (mob.getTarget() != characters) {
                    mob.clearAggroList();
                  }
                  attackPlayer(mob, (L2Playable) characters);
                  found = true;
                  break;
                }
              }

              if (!found) {
                if (mob.isInsideRadius(_baium, 40, true, false)) {
                  if (mob.getTarget() != _baium) {
                    mob.clearAggroList();
                  }
                  mob.setIsRunning(true);
                  mob.addDamageHate(_baium, 0, 999);
                  mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _baium);
                } else {
                  mob.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _baium);
                }
              }
            }
            startQuestTimer("SELECT_TARGET", 5000, npc, null);
          }
          break;
        }
      case "CHECK_ATTACK":
        {
          if ((npc != null) && ((_lastAttack + 1800000) < System.currentTimeMillis())) {
            notifyEvent("CLEAR_ZONE", null, null);
            addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
            setStatus(ALIVE);
          } else if (npc != null) {
            if (((_lastAttack + 300000) < System.currentTimeMillis())
                && (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))) {
              npc.setTarget(npc);
              npc.doCast(HEAL_OF_BAIUM.getSkill());
            }
            startQuestTimer("CHECK_ATTACK", 60000, npc, null);
          }
          break;
        }
      case "CLEAR_STATUS":
        {
          setStatus(ALIVE);
          addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
          break;
        }
      case "CLEAR_ZONE":
        {
          for (L2Character charInside : zone.getCharactersInside()) {
            if (charInside != null) {
              if (charInside.isNpc()) {
                charInside.deleteMe();
              } else if (charInside.isPlayer()) {
                notifyEvent("teleportOut", null, (L2PcInstance) charInside);
              }
            }
          }
          break;
        }
      case "RESPAWN_BAIUM":
        {
          if (getStatus() == DEAD) {
            setRespawn(0);
            cancelQuestTimer("CLEAR_STATUS", null, null);
            notifyEvent("CLEAR_STATUS", null, null);
          } else {
            player.sendMessage(
                getClass().getSimpleName() + ": You cant respawn Baium while Baium is alive!");
          }
          break;
        }
      case "ABORT_FIGHT":
        {
          if (getStatus() == IN_FIGHT) {
            _baium = null;
            notifyEvent("CLEAR_ZONE", null, null);
            notifyEvent("CLEAR_STATUS", null, null);
            player.sendMessage(getClass().getSimpleName() + ": Aborting fight!");
          } else {
            player.sendMessage(getClass().getSimpleName() + ": You cant abort attack right now!");
          }
          cancelQuestTimers("CHECK_ATTACK");
          cancelQuestTimers("SELECT_TARGET");
          break;
        }
      case "DESPAWN_MINIONS":
        {
          if (getStatus() == IN_FIGHT) {
            for (L2Character charInside : zone.getCharactersInside()) {
              if ((charInside != null) && charInside.isNpc() && (charInside.getId() == ARCHANGEL)) {
                charInside.deleteMe();
              }
            }
            if (player != null) {
              player.sendMessage(getClass().getSimpleName() + ": All archangels has been deleted!");
            }
          } else if (player != null) {
            player.sendMessage(
                getClass().getSimpleName() + ": You cant despawn archangels right now!");
          }
          break;
        }
      case "MANAGE_SKILLS":
        {
          if (npc != null) {
            manageSkills(npc);
          }
          break;
        }
    }
    return super.onAdvEvent(event, npc, player);
  }
Ejemplo n.º 11
0
  @Override
  protected void runImpl() {
    if (_items == null) {
      return;
    }

    // Get the current player and return if null
    L2PcInstance activeChar = getClient().getActiveChar();
    if (activeChar == null) {
      return;
    }

    if (!getClient().getFloodProtectors().getTransaction().tryPerformAction("buy")) {
      activeChar.sendMessage("You are buying too fast.");
      return;
    }

    // If Alternate rule Karma punishment is set to true, forbid Wear to player with Karma
    if (!Config.ALT_GAME_KARMA_PLAYER_CAN_SHOP && (activeChar.getKarma() > 0)) {
      return;
    }

    // Check current target of the player and the INTERACTION_DISTANCE
    L2Object target = activeChar.getTarget();
    if (!activeChar.isGM()
        && ((target == null // No target (i.e. GM Shop)
            )
            || !((target instanceof L2MerchantInstance)) // Target not a merchant
            || !activeChar.isInsideRadius(
                target, L2Npc.INTERACTION_DISTANCE, false, false) // Distance is too far
        )) {
      return;
    }

    if ((_count < 1) || (_listId >= 4000000)) {
      sendPacket(ActionFailed.STATIC_PACKET);
      return;
    }

    // Get the current merchant targeted by the player
    final L2MerchantInstance merchant =
        (target instanceof L2MerchantInstance) ? (L2MerchantInstance) target : null;
    if (merchant == null) {
      _log.warning(getClass().getName() + " Null merchant!");
      return;
    }

    final L2BuyList buyList = BuyListData.getInstance().getBuyList(_listId);
    if (buyList == null) {
      Util.handleIllegalPlayerAction(
          activeChar,
          "Warning!! Character "
              + activeChar.getName()
              + " of account "
              + activeChar.getAccountName()
              + " sent a false BuyList list_id "
              + _listId,
          Config.DEFAULT_PUNISH);
      return;
    }

    long totalPrice = 0;
    Map<Integer, Integer> itemList = new HashMap<>();

    for (int i = 0; i < _count; i++) {
      int itemId = _items[i];

      final Product product = buyList.getProductByItemId(itemId);
      if (product == null) {
        Util.handleIllegalPlayerAction(
            activeChar,
            "Warning!! Character "
                + activeChar.getName()
                + " of account "
                + activeChar.getAccountName()
                + " sent a false BuyList list_id "
                + _listId
                + " and item_id "
                + itemId,
            Config.DEFAULT_PUNISH);
        return;
      }

      L2Item template = product.getItem();
      if (template == null) {
        continue;
      }

      int slot = Inventory.getPaperdollIndex(template.getBodyPart());
      if (slot < 0) {
        continue;
      }

      if (template instanceof L2Weapon) {
        if (activeChar.getRace().ordinal() == 5) {
          if (template.getItemType() == WeaponType.NONE) {
            continue;
          } else if ((template.getItemType() == WeaponType.RAPIER)
              || (template.getItemType() == WeaponType.CROSSBOW)
              || (template.getItemType() == WeaponType.ANCIENTSWORD)) {
            continue;
          }
        }
      } else if (template instanceof L2Armor) {
        if (activeChar.getRace().ordinal() == 5) {
          if ((template.getItemType() == ArmorType.HEAVY)
              || (template.getItemType() == ArmorType.MAGIC)) {
            continue;
          }
        }
      }

      if (itemList.containsKey(slot)) {
        activeChar.sendPacket(SystemMessageId.YOU_CAN_NOT_TRY_THOSE_ITEMS_ON_AT_THE_SAME_TIME);
        return;
      }

      itemList.put(slot, itemId);
      totalPrice += Config.WEAR_PRICE;
      if (totalPrice > Inventory.MAX_ADENA) {
        Util.handleIllegalPlayerAction(
            activeChar,
            "Warning!! Character "
                + activeChar.getName()
                + " of account "
                + activeChar.getAccountName()
                + " tried to purchase over "
                + Inventory.MAX_ADENA
                + " adena worth of goods.",
            Config.DEFAULT_PUNISH);
        return;
      }
    }

    // Charge buyer and add tax to castle treasury if not owned by npc clan because a Try On is not
    // Free
    if ((totalPrice < 0)
        || !activeChar.reduceAdena("Wear", totalPrice, activeChar.getLastFolkNPC(), true)) {
      activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
      return;
    }

    if (!itemList.isEmpty()) {
      activeChar.sendPacket(new ShopPreviewInfo(itemList));
      // Schedule task
      ThreadPoolManager.getInstance()
          .scheduleGeneral(new RemoveWearItemsTask(activeChar), Config.WEAR_DELAY * 1000);
    }
  }