Ejemplo n.º 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;
  }
Ejemplo n.º 2
0
 private void setCooldowns() {
   int cooldown = effector.getSkillCooldown(skillTemplate);
   if (cooldown != 0) {
     effector.setSkillCoolDown(
         skillTemplate.getCooldownId(), cooldown * 100 + System.currentTimeMillis());
     effector.setSkillCoolDownBase(skillTemplate.getCooldownId(), System.currentTimeMillis());
   }
 }
Ejemplo n.º 3
0
 /**
  * Each skill is a separate object upon invocation Skill level will be populated from player
  * SkillList
  *
  * @param skillTemplate
  * @param effector
  * @param world
  */
 public Skill(SkillTemplate skillTemplate, Player effector, Creature firstTarget) {
   this(
       skillTemplate,
       effector,
       effector.getSkillList().getSkillLevel(skillTemplate.getSkillId()),
       firstTarget,
       null);
 }
Ejemplo n.º 4
0
  /**
   * @param skillTemplate
   * @param effector
   * @param skillLvl
   * @param firstTarget
   */
  public Skill(
      SkillTemplate skillTemplate,
      Creature effector,
      int skillLvl,
      Creature firstTarget,
      ItemTemplate itemTemplate) {
    this.effectedList = new ArrayList<Creature>();
    this.conditionChangeListener = new StartMovingListener();
    this.firstTarget = firstTarget;
    this.skillLevel = skillLvl;
    this.skillStackLvl = skillTemplate.getLvl();
    this.skillTemplate = skillTemplate;
    this.effector = effector;
    this.duration = skillTemplate.getDuration();
    this.itemTemplate = itemTemplate;

    if (itemTemplate != null) skillMethod = SkillMethod.ITEM;
    else if (skillTemplate.isPassive()) skillMethod = SkillMethod.PASSIVE;
    else if (skillTemplate.isProvoked()) skillMethod = SkillMethod.PROVOKED;
    else if (skillTemplate.isCharge()) skillMethod = SkillMethod.CHARGE;
  }
Ejemplo n.º 5
0
 /** @return true if the present skill is a self buff includes items (such as scroll buffs) */
 public boolean isSelfBuff() {
   return (firstTargetAttribute == FirstTargetAttribute.ME
       && targetRangeAttribute == TargetRangeAttribute.ONLYONE
       && skillTemplate.getSubType() == SkillSubType.BUFF
       && !skillTemplate.isDeityAvatar());
 }
Ejemplo n.º 6
0
 /** @return true or false */
 public boolean isPassive() {
   return skillTemplate.getActivationAttribute() == ActivationAttribute.PASSIVE;
 }
Ejemplo n.º 7
0
 /** @return the skillId */
 public int getSkillId() {
   return skillTemplate.getSkillId();
 }
Ejemplo n.º 8
0
 /** Check all conditions after using skill */
 private boolean endCondCheck() {
   Conditions skillConditions = skillTemplate.getEndConditions();
   return skillConditions != null ? skillConditions.validate(this) : true;
 }
Ejemplo n.º 9
0
 /** Check all conditions before using skill */
 private boolean preUsageCheck() {
   Conditions skillConditions = skillTemplate.getUseconditions();
   return skillConditions != null ? skillConditions.validate(this) : true;
 }
Ejemplo n.º 10
0
 /** Check all conditions before starting cast */
 protected boolean preCastCheck() {
   Conditions skillConditions = skillTemplate.getStartconditions();
   return skillConditions != null ? skillConditions.validate(this) : true;
 }
Ejemplo n.º 11
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());
  }
Ejemplo n.º 12
0
  /** Start casting of skill */
  protected void startCast() {
    int targetObjId = firstTarget != null ? firstTarget.getObjectId() : 0;

    if (skillMethod == SkillMethod.CAST || skillMethod == SkillMethod.CHARGE) {
      switch (targetType) {
        case 0: // PlayerObjectId as Target
          PacketSendUtility.broadcastPacketAndReceive(
              effector,
              new SM_CASTSPELL(
                  effector.getObjectId(),
                  skillTemplate.getSkillId(),
                  skillLevel,
                  targetType,
                  targetObjId,
                  this.duration,
                  skillTemplate.isCharge()));
          if (effector instanceof Npc && firstTarget instanceof Player) {
            NpcAI2 ai = (NpcAI2) effector.getAi2();
            if (ai.poll(AIQuestion.CAN_SHOUT)) ShoutEventHandler.onCast(ai, firstTarget);
          }
          break;

        case 3: // Target not in sight?
          PacketSendUtility.broadcastPacketAndReceive(
              effector,
              new SM_CASTSPELL(
                  effector.getObjectId(),
                  skillTemplate.getSkillId(),
                  skillLevel,
                  targetType,
                  0,
                  this.duration,
                  skillTemplate.isCharge()));
          break;

        case 1: // XYZ as Target
          PacketSendUtility.broadcastPacketAndReceive(
              effector,
              new SM_CASTSPELL(
                  effector.getObjectId(),
                  skillTemplate.getSkillId(),
                  skillLevel,
                  targetType,
                  x,
                  y,
                  z,
                  this.duration));
          break;
      }
    } else if (skillMethod == SkillMethod.ITEM && duration > 0) {
      PacketSendUtility.broadcastPacketAndReceive(
          effector,
          new SM_ITEM_USAGE_ANIMATION(
              effector.getObjectId(),
              firstTarget.getObjectId(),
              (this.itemObjectId == 0 ? 0 : this.itemObjectId),
              itemTemplate.getTemplateId(),
              this.duration,
              0,
              0));
    }
  }
Ejemplo n.º 13
0
  /** Penalty success skill */
  private void startPenaltySkill() {
    int penaltySkill = skillTemplate.getPenaltySkillId();
    if (penaltySkill == 0) return;

    SkillEngine.getInstance().applyEffectDirectly(penaltySkill, firstTarget, effector, 0);
  }
Ejemplo n.º 14
0
  protected void calculateSkillDuration() {
    // Skills that are not affected by boost casting time
    duration = 0;
    if (isCastTimeFixed()) {
      duration = skillTemplate.getDuration();
      return;
    }
    duration =
        effector
            .getGameStats()
            .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME, skillTemplate.getDuration());
    switch (skillTemplate.getSubType()) {
      case SUMMON:
        duration =
            effector
                .getGameStats()
                .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME_SUMMON, duration);
        break;
      case SUMMONHOMING:
        duration =
            effector
                .getGameStats()
                .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME_SUMMONHOMING, duration);
        break;
      case SUMMONTRAP:
        duration =
            effector
                .getGameStats()
                .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME_TRAP, duration);
        break;
      case HEAL:
        duration =
            effector
                .getGameStats()
                .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME_HEAL, duration);
        break;
      case ATTACK:
        if (skillTemplate.getType() == SkillType.MAGICAL) {
          duration =
              effector
                  .getGameStats()
                  .getPositiveReverseStat(StatEnum.BOOST_CASTING_TIME_ATTACK, duration);
        }
        break;
    }

    // 70% of base skill duration cap
    // No cast speed cap for skill Summoning Alacrity I(skillId: 1778) and Nimble Fingers I(skillId:
    // 2386)
    if (!effector.getEffectController().hasAbnormalEffect(1778)
        && !effector.getEffectController().hasAbnormalEffect(2386)) {
      int baseDurationCap = Math.round(skillTemplate.getDuration() * 0.3f);
      if (duration < baseDurationCap) {
        duration = baseDurationCap;
      }
    }

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

    if (duration < 0) {
      duration = 0;
    }
  }
Ejemplo n.º 15
0
 public boolean isGroundSkill() {
   return skillTemplate.isGroundSkill();
 }