@Override public void onDialogRequest(Player player) { // zer0patches todo check for better solution, portal data looks correct for portal controller // but // problem occurs because it is a quest teleportation via quest dialog on npc so portal check is // bypassed // Prevent Elyos's from using Aerolink in Gelkmaros -> Pandaemonium if (player.getCommonData().getRace() == Race.ELYOS && getOwner().getNpcId() == 730221) { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MOVE_PORTAL_ERROR_INVALID_RACE); return; } // Prevent Asmodian's from using Aerolink in Inggison -> Sanctum if (player.getCommonData().getRace() == Race.ASMODIANS && getOwner().getNpcId() == 730220) { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_MOVE_PORTAL_ERROR_INVALID_RACE); return; } getOwner().getAi().handleEvent(Event.TALK); if (QuestEngine.getInstance().onDialog(new QuestCookie(getOwner(), player, 0, -1))) return; // Zephyr Deliveryman if (getOwner().getObjectId() == player.getZephyrObjectId()) { PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(getOwner().getObjectId(), 18)); return; } int titleId = getOwner().getObjectTemplate().getTitleId(); if (( // title ids of npcs titleId == 315018 || titleId == 350474 || titleId == 350473 || titleId == 350212 || titleId == 350304 || titleId == 350305 || titleId == 370000 || titleId == 370003 // aerolinks || (getOwner().getNpcId() >= 730265 && getOwner().getNpcId() <= 730269))) { NpcQuestData npcQD = QuestEngine.getInstance().getNpcQuestData(getOwner().getNpcId()); QuestStateList list = player.getQuestStateList(); List<Integer> events = npcQD.getOnTalkEvent(); boolean hasQuestFromNpc = false; for (int e : events) { QuestState qs = list.getQuestState(e); if (qs != null && qs.getStatus() != QuestStatus.COMPLETE) { hasQuestFromNpc = true; break; } else { continue; } } if (hasQuestFromNpc) PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(getOwner().getObjectId(), 10)); else PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(getOwner().getObjectId(), 1011)); } else PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(getOwner().getObjectId(), 10)); }
@Override public void onDie(Creature lastAttacker) { super.onDie(lastAttacker); Npc owner = getOwner(); addTask(TaskId.DECAY, RespawnService.scheduleDecayTask(this.getOwner())); scheduleRespawn(); PacketSendUtility.broadcastPacket( owner, new SM_EMOTION( owner, EmotionType.DIE, 0, lastAttacker == null ? 0 : lastAttacker.getObjectId())); // Monster Controller overrides this method. this.doReward(); Npc npc = getOwner(); List<QuestDrop> drops = QuestEngine.getInstance().getQuestDrop(npc.getNpcId()); if (drops.size() > 0) { DropService.getInstance() .registerDrop(getOwner(), (Player) lastAttacker, lastAttacker.getLevel()); } owner.getAi().handleEvent(Event.DIED); // deselect target at the end owner.setTarget(null); PacketSendUtility.broadcastPacket(owner, new SM_LOOKATOBJECT(owner)); }
@Override public void onAttack( final Creature creature, int skillId, TYPE type, int damage, boolean notifyAttackedObservers) { if (getOwner().getLifeStats().isAlreadyDead()) return; super.onAttack(creature, skillId, type, damage, notifyAttackedObservers); Npc npc = getOwner(); Creature actingCreature = creature.getActingCreature(); if (actingCreature instanceof Player) if (QuestEngine.getInstance().onAttack(new QuestCookie(npc, (Player) actingCreature, 0, 0))) return; AI<?> ai = npc.getAi(); if (ai instanceof DummyAi) { log.warn("CHECKPOINT: npc attacked without ai " + npc.getObjectTemplate().getTemplateId()); return; } if (getOwner().getTribe().equals("DUMMY")) damage = 0; getOwner() .getKnownList() .doOnAllNpcs( new Executor<Npc>() { @Override public boolean run(Npc tmp) { if (getOwner().isSupportFrom(tmp) && MathUtil.isInRange(getOwner(), tmp, 10)) { tmp.getAggroList().addHate(creature, 10); } return true; } }, true); npc.getLifeStats().reduceHp(damage, actingCreature); PacketSendUtility.broadcastPacket(npc, new SM_ATTACK_STATUS(npc, type, skillId, damage)); }
/** Handle dialog */ @Override public void onDialogSelect(int dialogId, final Player player, int questId) { Npc npc = getOwner(); int targetObjectId = npc.getObjectId(); if (QuestEngine.getInstance().onDialog(new QuestCookie(npc, player, questId, dialogId))) return; switch (dialogId) { case 2: PacketSendUtility.sendPacket( player, new SM_TRADELIST( npc, TradeService.getTradeListData().getTradeListTemplate(npc.getNpcId()), player.getPrices().getVendorBuyModifier(), player)); break; case 3: PacketSendUtility.sendPacket( player, new SM_SELL_ITEM( targetObjectId, player.getPrices().getVendorSellModifier(player.getCommonData().getRace()))); break; case 4: // stigma PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 1)); break; case 5: // create legion if (MathUtil.isInRange( npc, player, 10)) // avoiding exploit with sending fake dialog_select packet { PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 2)); } else { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.LEGION_CREATE_TOO_FAR_FROM_NPC()); } break; case 6: // disband legion if (MathUtil.isInRange( npc, player, 10)) // avoiding exploit with sending fake dialog_select packet { LegionService.getInstance().requestDisbandLegion(npc, player); } else { PacketSendUtility.sendPacket( player, SM_SYSTEM_MESSAGE.LEGION_DISPERSE_TOO_FAR_FROM_NPC()); } break; case 7: // recreate legion if (MathUtil.isInRange( npc, player, 10)) // voiding exploit with sending fake client dialog_select // packet { LegionService.getInstance().recreateLegion(npc, player); } else { PacketSendUtility.sendPacket( player, SM_SYSTEM_MESSAGE.LEGION_DISPERSE_TOO_FAR_FROM_NPC()); } break; case 20: // warehouse if (MathUtil.isInRange( npc, player, 10)) // voiding exploit with sending fake client dialog_select // packet { if (!RestrictionsManager.canUseWarehouse(player)) return; PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 26)); WarehouseService.sendWarehouseInfo(player, true); } break; case 25: // TODO hotfix to prevent opening the legion wh when a quest returns false. break; case 27: // Consign trade?? npc karinerk, koorunerk PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 13)); break; case 29: // soul healing final long expLost = player.getCommonData().getExpRecoverable(); if (expLost == 0) player.getEffectController().removeEffect(8291); final double factor = (expLost < 1000000 ? 0.25 - (0.00000015 * expLost) : 0.1); final int price = (int) (expLost * factor * CustomConfig.SOULHEALING_PRICE_MULTIPLIER); RequestResponseHandler responseHandler = new RequestResponseHandler(npc) { @Override public void acceptRequest(Creature requester, Player responder) { if (player.getInventory().getKinahItem().getItemCount() >= price) { PacketSendUtility.sendPacket( player, SM_SYSTEM_MESSAGE.EXP(String.valueOf(expLost))); PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.SOUL_HEALED()); player.getCommonData().resetRecoverableExp(); player.getInventory().decreaseKinah(price); player.getEffectController().removeEffect(8291); } else { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.NOT_ENOUGH_KINAH(price)); } } @Override public void denyRequest(Creature requester, Player responder) { // no message } }; if (player.getCommonData().getExpRecoverable() > 0) { boolean result = player .getResponseRequester() .putRequest(SM_QUESTION_WINDOW.STR_SOUL_HEALING, responseHandler); if (result) { PacketSendUtility.sendPacket( player, new SM_QUESTION_WINDOW( SM_QUESTION_WINDOW.STR_SOUL_HEALING, 0, String.valueOf(price))); } } else { PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.DONT_HAVE_RECOVERED_EXP()); } break; case 30: switch (npc.getNpcId()) { // Triniel Arena (Enter) case 204089: TeleportService.teleportTo(player, 120010000, 1, 984f, 1543f, 222.1f, 0); ArenaService.getInstance().registerPlayerForTriniel(player); break; // Coliseum (Enter) case 203764: TeleportService.teleportTo(player, 110010000, 1, 1462.5f, 1326.1f, 564.1f, 0); ArenaService.getInstance().registerPlayerForColiseum(player); break; // Eracus Temple (Enter) case 203981: TeleportService.teleportTo(player, 210020000, 1, 439.3f, 422.2f, 274.3f, 0); break; } break; case 31: switch (npc.getNpcId()) { // Triniel Arena (Leave) case 204087: TeleportService.teleportTo(player, 120010000, 1, 1005.1f, 1528.9f, 222.1f, 0); ArenaService.getInstance().unregister(player); break; // Coliseum (Leave) case 203875: TeleportService.teleportTo(player, 110010000, 1, 1470.3f, 1343.5f, 563.7f, 21); ArenaService.getInstance().unregister(player); break; // Eracus Temple (Leave) case 203982: TeleportService.teleportTo(player, 210020000, 1, 446.2f, 431.1f, 274.5f, 0); break; } break; case 35: // Godstone socketing PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 21)); break; case 36: // remove mana stone PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 20)); break; case 37: // modify appearance PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 19)); break; case 38: // flight and teleport TeleportService.showMap(player, targetObjectId, npc.getNpcId()); break; case 39: // improve extraction case 40: // learn tailoring armor smithing etc... CraftSkillUpdateService.getInstance().learnSkill(player, npc); break; case 41: // expand cube CubeExpandService.expandCube(player, npc); break; case 42: WarehouseService.expandWarehouse(player, npc); break; case 47: // legion warehouse if (LegionConfig.LEGION_WAREHOUSE) if (MathUtil.isInRange(npc, player, 10)) LegionService.getInstance().openLegionWarehouse(player); break; case 50: // WTF??? Quest dialog packet break; case 52: if (MathUtil.isInRange( npc, player, 10)) // avoiding exploit with sending fake dialog_select packet { PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 28)); } break; case 53: // coin reward PacketSendUtility.sendPacket( player, new SM_MESSAGE(0, null, "This feature is not available yet", ChatType.ANNOUNCEMENTS)); break; case 55: case 56: byte changesex = 0; // 0 plastic surgery, 1 gender switch byte check_ticket = 2; // 2 no ticket, 1 have ticket if (dialogId == 56) { // Gender Switch changesex = 1; if (player.getInventory().getItemCountByItemId(169660000) > 0 || player.getInventory().getItemCountByItemId(169660001) > 0) check_ticket = 1; } else { // Plastic Surgery if (player.getInventory().getItemCountByItemId(169650000) > 0 || player.getInventory().getItemCountByItemId(169650001) > 0) check_ticket = 1; } PacketSendUtility.sendPacket( player, new SM_PLASTIC_SURGERY(player, check_ticket, changesex)); player.setEditMode(true); break; case 60: // armsfusion PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 29)); break; case 61: // armsbreaking PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, 30)); break; case 64: // repurchase PacketSendUtility.sendPacket(player, new SM_REPURCHASE(npc, player)); break; case 65: // adopt pet PacketSendUtility.sendPacket(player, new SM_PET(6)); break; case 66: // surrender pet PacketSendUtility.sendPacket(player, new SM_PET(7)); break; case 10000: // generic npc reply (most are teleporters) TeleporterTemplate template = DataManager.TELEPORTER_DATA.getTeleporterTemplate(npc.getNpcId()); if (template != null) { TeleportLocation loc = template.getTeleLocIdData().getTelelocations().get(0); if (loc != null) { player.getInventory().decreaseKinah(loc.getPrice()); TelelocationTemplate tlt = DataManager.TELELOCATION_DATA.getTelelocationTemplate(loc.getLocId()); TeleportService.teleportTo( player, tlt.getMapId(), tlt.getX(), tlt.getY(), tlt.getZ(), 1000); } } break; default: if (questId > 0) PacketSendUtility.sendPacket( player, new SM_DIALOG_WINDOW(targetObjectId, dialogId, questId)); else PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(targetObjectId, dialogId)); break; } }