@Override public String onKill(L2Npc npc, L2PcInstance killer, boolean isPet) { // Retrieve individual mob informations. final LevelingInfo npcInfo = SoulCrystalsTable.getNpcInfos().get(npc.getNpcId()); if (npcInfo == null) return null; // Handle npc leveling info type. switch (npcInfo.getAbsorbCrystalType()) { case FULL_PARTY: final L2Attackable mob = (L2Attackable) npc; final int chance = Rnd.get(100); for (L2PcInstance player : getPartyMembersState(killer, npc, Quest.STATE_STARTED)) tryToStageCrystal(player, mob, npcInfo, chance); break; case PARTY_ONE_RANDOM: final L2PcInstance player = getRandomPartyMemberState(killer, npc, Quest.STATE_STARTED); if (player != null) tryToStageCrystal(player, (L2Attackable) npc, npcInfo, Rnd.get(100)); break; case LAST_HIT: if (checkPlayerState(killer, npc, Quest.STATE_STARTED) != null) tryToStageCrystal(killer, (L2Attackable) npc, npcInfo, Rnd.get(100)); break; } return null; }
/** * 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); }