@Override public void attackTarget(Creature target) { Npc npc = getOwner(); /** Check all prerequisites */ if (npc == null || npc.getLifeStats().isAlreadyDead() || !npc.isSpawned()) return; if (!npc.canAttack()) return; AI<?> ai = npc.getAi(); NpcGameStats gameStats = npc.getGameStats(); if (target == null || target.getLifeStats().isAlreadyDead()) { ai.handleEvent(Event.MOST_HATED_CHANGED); return; } /** notify attack observers */ super.attackTarget(target); /** Calculate and apply damage */ List<AttackResult> attackList = AttackUtil.calculateAttackResult(npc, target); int damage = 0; for (AttackResult result : attackList) { damage += result.getDamage(); } int attackType = 0; // TODO investigate attack types (0 or 1) PacketSendUtility.broadcastPacket( npc, new SM_ATTACK(npc, target, gameStats.getAttackCounter(), 274, attackType, attackList)); target.getController().onAttack(npc, damage, true); gameStats.increaseAttackCounter(); }
@Override public void onRespawn() { super.onRespawn(); cancelTask(TaskId.DECAY); Npc owner = getOwner(); if (owner != null && owner.isCustom()) { DAOManager.getDAO(SpawnDAO.class) .setSpawned(owner.getSpawn().getSpawnId(), owner.getObjectId(), true); } // set state from npc templates if (owner.getObjectTemplate().getState() != 0) owner.setState(owner.getObjectTemplate().getState()); else owner.setState(CreatureState.NPC_IDLE); owner.getLifeStats().setCurrentHpPercent(100); owner.getLifeStats().setCurrentMpPercent(100); owner.getAi().handleEvent(Event.RESPAWNED); if (owner.getSpawn().getNpcFlyState() != 0) { owner.setState(CreatureState.FLYING); } }
@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 see(VisibleObject object) { super.see(object); Npc owner = getOwner(); owner.getAi().handleEvent(Event.SEE_CREATURE); if (object instanceof Player) { owner.getAi().handleEvent(Event.SEE_PLAYER); // TODO check on retail how walking npc is presented, probably need replace emotion // with some state etc. if (owner.getMoveController().isWalking()) PacketSendUtility.sendPacket((Player) object, new SM_EMOTION(owner, EmotionType.WALK)); else if (owner.getMoveController().isWalking() && owner.canSee((Player) object)) owner.getAi().clearDesires(); owner.getAi().addDesire(new AggressionDesire(owner, 100)); } else if (object instanceof Summon) { owner.getAi().handleEvent(Event.SEE_PLAYER); } }
@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)); }
@Override public void notSee(VisibleObject object, boolean isOutOfRange) { super.notSee(object, isOutOfRange); if (object instanceof Player || object instanceof Summon) getOwner().getAi().handleEvent(Event.NOT_SEE_PLAYER); }
@Override public void onStopMove() { super.onStopMove(); }