예제 #1
0
  @Override
  public void onStart(BuffInfo info) {
    L2Character target = info.getEffected();
    L2Character activeChar = info.getEffector();
    Skill skill = info.getSkill();

    if (activeChar.isAlikeDead()) {
      return;
    }

    if (((skill.getFlyRadius() > 0) || (skill.getFlyType() != null))
        && activeChar.isMovementDisabled()) {
      final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
      sm.addSkillName(skill);
      activeChar.sendPacket(sm);
      return;
    }

    if (target.isPlayer() && target.getActingPlayer().isFakeDeath()) {
      target.stopFakeDeath(true);
    }

    int damage = 0;
    boolean ss = skill.isPhysical() && activeChar.isChargedShot(ShotType.SOULSHOTS);
    final byte shld = Formulas.calcShldUse(activeChar, target, skill);
    // Physical damage critical rate is only affected by STR.
    boolean crit = false;
    if (skill.getBaseCritRate() > 0) {
      crit = Formulas.calcCrit(activeChar, target, skill);
    }

    damage = (int) Formulas.calcPhysDam(activeChar, target, skill, shld, false, ss);

    if ((skill.getMaxSoulConsumeCount() > 0) && activeChar.isPlayer()) {
      // Souls Formula (each soul increase +4%)
      int chargedSouls =
          (activeChar.getActingPlayer().getChargedSouls() <= skill.getMaxSoulConsumeCount())
              ? activeChar.getActingPlayer().getChargedSouls()
              : skill.getMaxSoulConsumeCount();
      damage *= 1 + (chargedSouls * 0.04);
    }
    if (crit) {
      damage *= 2;
    }

    if (damage > 0) {
      activeChar.sendDamageMessage(target, damage, false, crit, false);
      target.reduceCurrentHp(damage, activeChar, skill);
      target.notifyDamageReceived(damage, activeChar, skill, crit, false);

      // Check if damage should be reflected
      Formulas.calcDamageReflected(activeChar, target, skill, crit);
    } else {
      activeChar.sendPacket(SystemMessageId.ATTACK_FAILED);
    }

    if (skill.isSuicideAttack()) {
      activeChar.doDie(activeChar);
    }
  }
예제 #2
0
  @Override
  public void useSkill(L2Character activeChar, L2Object[] targets) {
    if (activeChar.isAlikeDead()) {
      return;
    }

    boolean ss = useSoulShot() && activeChar.isChargedShot(ShotType.SOULSHOTS);
    boolean sps = useSpiritShot() && activeChar.isChargedShot(ShotType.SPIRITSHOTS);
    boolean bss = useSpiritShot() && activeChar.isChargedShot(ShotType.BLESSED_SPIRITSHOTS);

    for (L2Character target : (L2Character[]) targets) {
      if (target.isAlikeDead() && (getTargetType() != L2TargetType.CORPSE_MOB)) {
        continue;
      }

      if ((activeChar != target) && target.isInvul()) {
        continue; // No effect on invulnerable chars unless they cast it themselves.
      }

      boolean mcrit = Formulas.calcMCrit(activeChar.getMCriticalHit(target, this));
      byte shld = Formulas.calcShldUse(activeChar, target, this);
      int damage =
          isStaticDamage()
              ? (int) getPower()
              : (int) Formulas.calcMagicDam(activeChar, target, this, shld, sps, bss, mcrit);

      int _drain = 0;
      int _cp = (int) target.getCurrentCp();
      int _hp = (int) target.getCurrentHp();

      if (_cp > 0) {
        if (damage < _cp) {
          _drain = 0;
        } else {
          _drain = damage - _cp;
        }
      } else if (damage > _hp) {
        _drain = _hp;
      } else {
        _drain = damage;
      }

      double hpAdd = _absorbAbs + (_absorbPart * _drain);
      double hp =
          ((activeChar.getCurrentHp() + hpAdd) > activeChar.getMaxHp()
              ? activeChar.getMaxHp()
              : (activeChar.getCurrentHp() + hpAdd));

      activeChar.setCurrentHp(hp);

      StatusUpdate suhp = new StatusUpdate(activeChar);
      suhp.addAttribute(StatusUpdate.CUR_HP, (int) hp);
      activeChar.sendPacket(suhp);

      // Check to see if we should damage the target
      if ((damage > 0) && (!target.isDead() || (getTargetType() != L2TargetType.CORPSE_MOB))) {
        // Manage attack or cast break of the target (calculating rate, sending message...)
        if (!target.isRaid() && Formulas.calcAtkBreak(target, damage)) {
          target.breakAttack();
          target.breakCast();
        }

        activeChar.sendDamageMessage(target, damage, mcrit, false, false);

        if (Config.LOG_GAME_DAMAGE
            && activeChar.isPlayable()
            && (damage > Config.LOG_GAME_DAMAGE_THRESHOLD)) {
          LogRecord record = new LogRecord(Level.INFO, "");
          record.setParameters(
              new Object[] {activeChar, " did damage ", damage, this, " to ", target});
          record.setLoggerName("mdam");
          _logDamage.log(record);
        }

        if (hasEffects() && (getTargetType() != L2TargetType.CORPSE_MOB)) {
          // ignoring vengance-like reflections
          if ((Formulas.calcSkillReflect(target, this) & Formulas.SKILL_REFLECT_SUCCEED) > 0) {
            activeChar.stopSkillEffects(getId());
            getEffects(target, activeChar);
            SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
            sm.addSkillName(getId());
            activeChar.sendPacket(sm);
          } else {
            // activate attacked effects, if any
            target.stopSkillEffects(getId());
            if (Formulas.calcSkillSuccess(activeChar, target, this, shld, ss, sps, bss)) {
              getEffects(activeChar, target);
            } else {
              SystemMessage sm =
                  SystemMessage.getSystemMessage(SystemMessageId.C1_RESISTED_YOUR_S2);
              sm.addCharName(target);
              sm.addSkillName(this);
              activeChar.sendPacket(sm);
            }
          }
        }

        target.reduceCurrentHp(damage, activeChar, this);
      }

      // Check to see if we should do the decay right after the cast
      if (target.isDead() && (getTargetType() == L2TargetType.CORPSE_MOB) && target.isNpc()) {
        ((L2Npc) target).endDecayTask();
      }
    }
    // effect self :]
    L2Effect effect = activeChar.getFirstEffect(getId());
    if ((effect != null) && effect.isSelfEffect()) {
      // Replace old effect with new one.
      effect.exit();
    }
    // cast self effect if any
    getEffectsSelf(activeChar);
    // Consume shot
    activeChar.setChargedShot(bss ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
  }
  @Override
  public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item) {
    // Need skill rework for fix that properly
    if (skill.getAffectRange() > 0) {
      return true;
    }
    if (effected == null) {
      return false;
    }
    boolean canResurrect = true;

    if (effected.isPlayer()) {
      final L2PcInstance player = effected.getActingPlayer();
      if (!player.isDead()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          final SystemMessage msg =
              SystemMessage.getSystemMessage(
                  SystemMessageId.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS);
          msg.addSkillName(skill);
          effector.sendPacket(msg);
        }
      } else if (player.isResurrectionBlocked()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          effector.sendPacket(SystemMessageId.REJECT_RESURRECTION);
        }
      } else if (player.isReviveRequested()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          effector.sendPacket(SystemMessageId.RESURRECTION_HAS_ALREADY_BEEN_PROPOSED);
        }
      }
    } else if (effected.isSummon()) {
      final L2Summon summon = (L2Summon) effected;
      final L2PcInstance player = summon.getOwner();
      if (!summon.isDead()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          final SystemMessage msg =
              SystemMessage.getSystemMessage(
                  SystemMessageId.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS);
          msg.addSkillName(skill);
          effector.sendPacket(msg);
        }
      } else if (summon.isResurrectionBlocked()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          effector.sendPacket(SystemMessageId.REJECT_RESURRECTION);
        }
      } else if ((player != null) && player.isRevivingPet()) {
        canResurrect = false;
        if (effector.isPlayer()) {
          effector.sendPacket(
              SystemMessageId
                  .RESURRECTION_HAS_ALREADY_BEEN_PROPOSED); // Resurrection is already been
                                                            // proposed.
        }
      }
    }
    return (_val == canResurrect);
  }