/** * Remove the old crystal and add new one if stage, broken crystal if break. Send messages in both * cases. * * @param player : The player to check on (inventory and send messages). * @param scd : SoulCrystalData of to take information form. * @param stage : Switch to determine success or fail. */ private void exchangeCrystal(L2PcInstance player, SoulCrystalData scd, boolean stage) { QuestState st = player.getQuestState(qn); st.takeItems(scd.getCrystalItemId(), 1); if (stage) { player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_SUCCEEDED); st.giveItems(scd.getStagedItemId(), 1); st.playSound(QuestState.SOUND_ITEMGET); } else { int broken = scd.getBrokenItemId(); if (broken != 0) { player.sendPacket(SystemMessageId.SOUL_CRYSTAL_BROKE); st.giveItems(broken, 1); } } }
/** * Define the Soul Crystal and try to stage it. Checks for quest enabled, crystal(s) in inventory, * required usage of crystal, mob's ability to level crystal and mob vs player level gap. * * @param player : The player to make checks on. * @param mob : The mob to make checks on. * @param npcInfo : The mob's leveling informations. * @param chance : Input variable used to determine keep/stage/break of the crystal. * @return Returns true only, when crystal is staged or broken (aka any type of crystal change is * made), else returns false. */ private void tryToStageCrystal( L2PcInstance player, L2Attackable mob, LevelingInfo npcInfo, int chance) { SoulCrystalData crystalData = null; ItemInstance crystalItem = null; // Iterate through player's inventory to find crystal(s). for (ItemInstance item : player.getInventory().getItems()) { SoulCrystalData data = SoulCrystalsTable.getSoulCrystalInfos().get(item.getItemId()); if (data == null) continue; // More crystals found. if (crystalData != null) { // Leveling requires soul crystal being used? if (npcInfo.skillRequired()) { // Absorb list contains killer and his AbsorbInfo is registered. final AbsorbInfo ai = mob.getAbsorbInfo(player.getObjectId()); if (ai != null && ai.isRegistered()) player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_FAILED_RESONATION); } else player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_FAILED_RESONATION); return; } crystalData = data; crystalItem = item; } // No crystal found, return without any notification. if (crystalData == null || crystalItem == null) return; // Leveling requires soul crystal being used? if (npcInfo.skillRequired()) { // Absorb list doesn't contain killer or his AbsorbInfo is not registered. final AbsorbInfo ai = mob.getAbsorbInfo(player.getObjectId()); if (ai == null || !ai.isRegistered()) return; // Check if Absorb list contains valid crystal and whether it was used properly. if (!ai.isValid(crystalItem.getObjectId())) { player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_REFUSED); return; } } // Check, if npc stages this type of crystal. if (!npcInfo.isInLevelList(crystalData.getLevel())) { player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_REFUSED); return; } // Check level difference limitation, dark blue monsters does not stage. if (player.getLevel() - mob.getLevel() > 8) { player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_REFUSED); return; } // Lucky, crystal successfully stages. if (chance < npcInfo.getChanceStage()) exchangeCrystal(player, crystalData, true); // Bad luck, crystal accidentally breaks. else if (chance < (npcInfo.getChanceStage() + npcInfo.getChanceBreak())) exchangeCrystal(player, crystalData, false); // Bad luck, crystal doesn't stage. else player.sendPacket(SystemMessageId.SOUL_CRYSTAL_ABSORBING_FAILED); }