Пример #1
0
  /**
   * Check if the skill can be used
   *
   * @return True if the skill can be used
   */
  public boolean canUseSkill() {
    Properties properties = skillTemplate.getProperties();
    if (properties != null && !properties.validate(this)) {
      log.debug("properties failed");
      return false;
    }

    if (!preCastCheck()) return false;

    // check for counter skill
    if (effector instanceof Player) {
      Player player = (Player) effector;
      if (this.skillTemplate.getCounterSkill() != null) {
        long time = player.getLastCounterSkill(skillTemplate.getCounterSkill());
        if ((time + 5000) < System.currentTimeMillis()) {
          log.debug("chain skill failed, too late");
          return false;
        }
      }

      if (skillMethod == SkillMethod.ITEM
          && duration > 0
          && player.getMoveController().isInMove()) {
        PacketSendUtility.sendPacket(
            player,
            SM_SYSTEM_MESSAGE.STR_ITEM_CANCELED(new DescriptionId(getItemTemplate().getNameId())));
        return false;
      }
    }
    if (!validateEffectedList()) return false;

    return true;
  }
Пример #2
0
  /** Apply effects and perform actions specified in skill template */
  protected void endCast() {
    if (!effector.isCasting() || isCancelled) return;

    // if target out of range
    if (skillTemplate == null) return;

    // Check if target is out of skill range
    Properties properties = skillTemplate.getProperties();
    if (properties != null && !properties.endCastValidate(this)) {
      effector.getController().cancelCurrentSkill();
      return;
    }

    if (!validateEffectedList()) {
      effector.getController().cancelCurrentSkill();
      return;
    }

    if (!preUsageCheck()) {
      return;
    }

    effector.setCasting(null);

    if (this.getSkillTemplate().isDeityAvatar() && effector instanceof Player) {
      AbyssService.rankerSkillAnnounce((Player) effector, this.getSkillTemplate().getNameId());
    }

    /** try removing item, if its not possible return to prevent exploits */
    if (effector instanceof Player && skillMethod == SkillMethod.ITEM) {
      Item item = ((Player) effector).getInventory().getItemByObjId(this.itemObjectId);
      if (item == null) return;
      if (item.getActivationCount() > 1) {
        item.setActivationCount(item.getActivationCount() - 1);
      } else {
        if (!((Player) effector)
            .getInventory()
            .decreaseByObjectId(item.getObjectId(), 1, ItemUpdateType.DEC_USE)) return;
      }
    }
    /** Create effects and precalculate result */
    int spellStatus = 0;
    int dashStatus = 0;
    int resistCount = 0;
    boolean blockedChain = false;
    boolean blockedStance = false;
    final List<Effect> effects = new ArrayList<Effect>();
    if (skillTemplate.getEffects() != null) {
      boolean blockAOESpread = false;
      for (Creature effected : effectedList) {
        Effect effect = new Effect(this, effected, 0, itemTemplate);
        if (effected instanceof Player) {
          if (effect.getEffectResult() == EffectResult.CONFLICT) blockedStance = true;
        }
        // Force RESIST status if AOE spell spread must be blocked
        if (blockAOESpread) effect.setAttackStatus(AttackStatus.RESIST);
        effect.initialize();
        final int worldId = effector.getWorldId();
        final int instanceId = effector.getInstanceId();
        effect.setWorldPosition(worldId, instanceId, x, y, z);

        effects.add(effect);
        spellStatus = effect.getSpellStatus().getId();
        dashStatus = effect.getDashStatus().getId();

        // Block AOE propagation if firstTarget resists the spell
        if ((!blockAOESpread)
            && (effect.getAttackStatus() == AttackStatus.RESIST)
            && (isTargetAOE())) blockAOESpread = true;

        if (effect.getAttackStatus() == AttackStatus.RESIST
            || effect.getAttackStatus() == AttackStatus.DODGE) {
          resistCount++;
        }
      }

      if (resistCount == effectedList.size()) {
        blockedChain = true;
        blockedPenaltySkill = true;
      }

      // exception for point point skills(example Ice Sheet)
      if (effectedList.isEmpty() && this.isPointPointSkill()) {
        Effect effect = new Effect(this, null, 0, itemTemplate);
        effect.initialize();
        final int worldId = effector.getWorldId();
        final int instanceId = effector.getInstanceId();
        effect.setWorldPosition(worldId, instanceId, x, y, z);
        effects.add(effect);
        spellStatus = effect.getSpellStatus().getId();
      }
    }

    if (effector instanceof Player && skillMethod == SkillMethod.CAST) {
      Player playerEffector = (Player) effector;
      if (playerEffector.getController().isUnderStance()) {
        playerEffector.getController().stopStance();
      }
      if (skillTemplate.isStance() && !blockedStance) {
        playerEffector.getController().startStance(skillTemplate.getSkillId());
      }
    }

    boolean setCooldowns = true;
    if (effector instanceof Player) {
      if (this.isMulticast()
          && ((Player) effector)
                  .getChainSkills()
                  .getChainCount((Player) effector, this.getSkillTemplate(), this.chainCategory)
              != 0) {
        setCooldowns = false;
      }
    }

    // Check Chain Skill Trigger Rate
    if (CustomConfig.SKILL_CHAIN_TRIGGERRATE) {
      int chainProb = skillTemplate.getChainSkillProb();
      if (this.chainCategory != null && !blockedChain) {
        this.chainSuccess = Rnd.get(90) < chainProb;
      }
    } else {
      this.chainSuccess = true;
    }

    /** set variables for chaincondition check */
    if (effector instanceof Player && this.chainSuccess && this.chainCategory != null) {
      ((Player) effector).getChainSkills().addChainSkill(this.chainCategory, this.isMulticast());
    }

    /** Perform necessary actions (use mp,dp items etc) */
    Actions skillActions = skillTemplate.getActions();
    if (skillActions != null) {
      for (Action action : skillActions.getActions()) {
        if (!action.act(this)) return;
      }
    }

    if (effector instanceof Player) {
      QuestEnv env = new QuestEnv(effector.getTarget(), (Player) effector, 0, 0);
      QuestEngine.getInstance().onUseSkill(env, skillTemplate.getSkillId());
    }

    if (setCooldowns) this.setCooldowns();

    if (hitTime == 0) applyEffect(effects);
    else {
      ThreadPoolManager.getInstance()
          .schedule(
              new Runnable() {

                @Override
                public void run() {
                  applyEffect(effects);
                }
              },
              hitTime);
    }
    if (skillMethod == SkillMethod.CAST
        || skillMethod == SkillMethod.ITEM
        || skillMethod == SkillMethod.CHARGE) sendCastspellEnd(spellStatus, dashStatus, effects);

    endCondCheck();

    if (effector instanceof Npc)
      SkillAttackManager.afterUseSkill((NpcAI2) ((Npc) effector).getAi2());
  }