public Q350_EnhanceYourWeapon() { super(350, qn, "Enhance Your Weapon"); addStartNpc(30115, 30194, 30856); addTalkId(30115, 30194, 30856); for (int npcId : SoulCrystalsTable.getNpcInfos().keySet()) addKillId(npcId); for (int crystalId : SoulCrystalsTable.getSoulCrystalInfos().keySet()) addItemUse(crystalId); }
@Override public String onTalk(L2Npc npc, L2PcInstance player) { String htmltext = getNoQuestMsg(); QuestState st = player.getQuestState(qn); if (st == null) return htmltext; switch (st.getState()) { case STATE_CREATED: if (player.getLevel() < 40) htmltext = npc.getNpcId() + "-lvl.htm"; else htmltext = npc.getNpcId() + "-01.htm"; break; case STATE_STARTED: // Check inventory for soul crystals. for (ItemInstance item : player.getInventory().getItems()) { // Crystal found, show "how to" html. if (SoulCrystalsTable.getSoulCrystalInfos().get(item.getItemId()) != null) return npc.getNpcId() + "-03.htm"; } // No crystal found, offer a new crystal. htmltext = npc.getNpcId() + "-21.htm"; break; } return htmltext; }
@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; }
@Override public String onItemUse(ItemInstance item, L2PcInstance user, L2Object target) { // Caster is dead. if (user.isDead()) return null; // No target, or target isn't an L2Attackable. if (target == null || !(target instanceof L2Attackable)) return null; final L2Attackable mob = ((L2Attackable) target); // Mob is dead or not registered in _npcInfos. if (mob.isDead() || !SoulCrystalsTable.getNpcInfos().containsKey(mob.getNpcId())) return null; // Add user to mob's absorber list. mob.addAbsorber(user, item); 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); }