Example #1
0
 public void applyEffect(MapleCharacter player, MapleMonster monster, boolean skill) {
   MapleDisease disease = null;
   Map<MonsterStatus, Integer> stats = new ArrayMap<MonsterStatus, Integer>();
   List<Integer> reflection = new LinkedList<Integer>();
   switch (skillId) {
     case 100:
     case 110:
     case 150:
       stats.put(MonsterStatus.WEAPON_ATTACK_UP, Integer.valueOf(x));
       break;
     case 101:
     case 111:
     case 151:
       stats.put(MonsterStatus.MAGIC_ATTACK_UP, Integer.valueOf(x));
       break;
     case 102:
     case 112:
     case 152:
       stats.put(MonsterStatus.WEAPON_DEFENSE_UP, Integer.valueOf(x));
       break;
     case 103:
     case 113:
     case 153:
       stats.put(MonsterStatus.MAGIC_DEFENSE_UP, Integer.valueOf(x));
       break;
     case 114:
       if (lt != null && rb != null && skill) {
         List<MapleMapObject> objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER);
         final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random());
         for (MapleMapObject mons : objects) {
           ((MapleMonster) mons).heal(hps, getY());
         }
       } else {
         monster.heal(getX(), getY());
       }
       break;
     case 120:
       disease = MapleDisease.SEAL;
       break;
     case 121:
       disease = MapleDisease.DARKNESS;
       break;
     case 122:
       disease = MapleDisease.WEAKEN;
       break;
     case 123:
       disease = MapleDisease.STUN;
       break;
     case 124:
       disease = MapleDisease.CURSE;
       break;
     case 125:
       disease = MapleDisease.POISON;
       break;
     case 126: // Slow
       disease = MapleDisease.SLOW;
       break;
     case 127:
       if (lt != null && rb != null && skill) {
         for (MapleCharacter character : getPlayersInRange(monster, player)) {
           character.dispel();
         }
       } else {
         player.dispel();
       }
       break;
     case 128: // Seduce
       disease = MapleDisease.SEDUCE;
       break;
     case 129: // Banish
       if (lt != null && rb != null && skill) {
         for (MapleCharacter chr : getPlayersInRange(monster, player)) {
           chr.changeMapBanish(
               monster.getBanish().getMap(),
               monster.getBanish().getPortal(),
               monster.getBanish().getMsg());
         }
       } else {
         player.changeMapBanish(
             monster.getBanish().getMap(),
             monster.getBanish().getPortal(),
             monster.getBanish().getMsg());
       }
       break;
     case 131: // Mist
       monster
           .getMap()
           .spawnMist(
               new MapleMist(calculateBoundingBox(monster.getPosition(), true), monster, this),
               x * 10,
               false,
               false);
       break;
     case 132:
       disease = MapleDisease.CONFUSE;
       break;
     case 133: // zombify
       break;
     case 140:
       if (makeChanceResult() && !monster.isBuffed(MonsterStatus.MAGIC_IMMUNITY)) {
         stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
       }
       break;
     case 141:
       if (makeChanceResult() && !monster.isBuffed(MonsterStatus.WEAPON_IMMUNITY)) {
         stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
       }
       break;
     case 143: // Weapon Reflect
       stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
       stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
       reflection.add(x);
       break;
     case 144: // Magic Reflect
       stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
       stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
       reflection.add(x);
       break;
     case 145: // Weapon / Magic reflect
       stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
       stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
       stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
       stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
       reflection.add(x);
       break;
     case 154: // accuracy up
     case 155: // avoid up
     case 156: // speed up
       break;
     case 200:
       if (monster.getMap().getSpawnedMonstersOnMap() < 80) {
         for (Integer mobId : getSummons()) {
           MapleMonster toSpawn = MapleLifeFactory.getMonster(mobId);
           toSpawn.setPosition(monster.getPosition());
           int ypos, xpos;
           xpos = (int) monster.getPosition().getX();
           ypos = (int) monster.getPosition().getY();
           switch (mobId) {
             case 8500003: // Pap bomb high
               toSpawn.setFh((int) Math.ceil(Math.random() * 19.0));
               ypos = -590;
               break;
             case 8500004: // Pap bomb
               xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
               if (ypos != -590) {
                 ypos = (int) monster.getPosition().getY();
               }
               break;
             case 8510100: // Pianus bomb
               if (Math.ceil(Math.random() * 5) == 1) {
                 ypos = 78;
                 xpos = (int) Randomizer.nextInt(5) + (Randomizer.nextInt(2) == 1 ? 180 : 0);
               } else {
                 xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
               }
               break;
           }
           switch (monster.getMap().getId()) {
             case 220080001: // Pap map
               if (xpos < -890) {
                 xpos = (int) (Math.ceil(Math.random() * 150) - 890);
               } else if (xpos > 230) {
                 xpos = (int) (230 - Math.ceil(Math.random() * 150));
               }
               break;
             case 230040420: // Pianus map
               if (xpos < -239) {
                 xpos = (int) (Math.ceil(Math.random() * 150) - 239);
               } else if (xpos > 371) {
                 xpos = (int) (371 - Math.ceil(Math.random() * 150));
               }
               break;
           }
           toSpawn.setPosition(new Point(xpos, ypos));
           monster
               .getMap()
               .spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition());
         }
       }
       break;
   }
   if (stats.size() > 0) {
     if (lt != null && rb != null && skill) {
       for (MapleMapObject mons : getObjectsInRange(monster, MapleMapObjectType.MONSTER)) {
         ((MapleMonster) mons)
             .applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
       }
     } else {
       monster.applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
     }
   }
   if (disease != null) {
     if (lt != null && rb != null && skill) {
       int i = 0;
       for (MapleCharacter character : getPlayersInRange(monster, player)) {
         if (!character.isActiveBuffedValue(2321005)) {
           if (disease.equals(MapleDisease.SEDUCE)) {
             if (i < 10) {
               character.giveDebuff(MapleDisease.SEDUCE, this);
               i++;
             }
           } else {
             character.giveDebuff(disease, this);
           }
         }
       }
     } else {
       player.giveDebuff(disease, this);
     }
   }
   monster.usedSkill(skillId, skillLevel, cooltime);
   monster.setMp(monster.getMp() - getMpCon());
 }
  public static final void SummonPVP(final LittleEndianAccessor slea, final MapleClient c) {
    final MapleCharacter chr = c.getPlayer();
    if (chr == null
        || chr.isHidden()
        || !chr.isAlive()
        || chr.hasBlockedInventory()
        || chr.getMap() == null
        || !chr.inPVP()
        || !chr.getEventInstance().getProperty("started").equals("1")) {
      return;
    }
    final MapleMap map = chr.getMap();
    final MapleMapObject obj = map.getMapObject(slea.readInt(), MapleMapObjectType.SUMMON);
    if (obj == null || !(obj instanceof MapleSummon)) {
      chr.dropMessage(5, "The summon has disappeared.");
      return;
    }
    int tick = -1;
    if (slea.available() == 27) {
      slea.skip(23);
      tick = slea.readInt();
    }
    final MapleSummon summon = (MapleSummon) obj;
    if (summon.getOwnerId() != chr.getId() || summon.getSkillLevel() <= 0) {
      chr.dropMessage(5, "Error.");
      return;
    }
    final Skill skil = SkillFactory.getSkill(summon.getSkill());
    final MapleStatEffect effect = skil.getEffect(summon.getSkillLevel());
    final int lvl = Integer.parseInt(chr.getEventInstance().getProperty("lvl"));
    final int type = Integer.parseInt(chr.getEventInstance().getProperty("type"));
    final int ourScore =
        Integer.parseInt(chr.getEventInstance().getProperty(String.valueOf(chr.getId())));
    int addedScore = 0;
    final boolean magic = skil.isMagic();
    boolean killed = false, didAttack = false;
    double maxdamage =
        lvl == 3
            ? chr.getStat().getCurrentMaxBasePVPDamageL()
            : chr.getStat().getCurrentMaxBasePVPDamage();
    maxdamage *= (effect.getDamage() + chr.getStat().getDamageIncrease(summon.getSkill())) / 100.0;
    int mobCount = 1, attackCount = 1, ignoreDEF = chr.getStat().ignoreTargetDEF;

    final SummonSkillEntry sse = SkillFactory.getSummonData(summon.getSkill());
    if (summon.getSkill() / 1000000 != 35 && summon.getSkill() != 33101008 && sse == null) {
      chr.dropMessage(5, "Error in processing attack.");
      return;
    }
    Point lt, rb;
    if (sse != null) {
      if (sse.delay > 0) {
        if (tick != -1) {
          summon.CheckSummonAttackFrequency(chr, tick);
          chr.updateTick(tick);
        } else {
          summon.CheckPVPSummonAttackFrequency(chr);
        }
        chr.getCheatTracker().checkSummonAttack();
      }
      mobCount = sse.mobCount;
      attackCount = sse.attackCount;
      lt = sse.lt;
      rb = sse.rb;
    } else {
      lt = new Point(-100, -100);
      rb = new Point(100, 100);
    }
    final Rectangle box =
        MapleStatEffect.calculateBoundingBox(chr.getTruePosition(), chr.isFacingLeft(), lt, rb, 0);
    List<AttackPair> ourAttacks = new ArrayList<AttackPair>();
    List<Pair<Integer, Boolean>> attacks;
    maxdamage *= chr.getStat().dam_r / 100.0;
    for (MapleMapObject mo : chr.getMap().getCharactersIntersect(box)) {
      final MapleCharacter attacked = (MapleCharacter) mo;
      if (attacked.getId() != chr.getId()
          && attacked.isAlive()
          && !attacked.isHidden()
          && (type == 0 || attacked.getTeam() != chr.getTeam())) {
        double rawDamage =
            maxdamage
                / Math.max(
                    0,
                    ((magic ? attacked.getStat().mdef : attacked.getStat().wdef)
                            * Math.max(1.0, 100.0 - ignoreDEF)
                            / 100.0)
                        * (type == 3 ? 0.1 : 0.25));
        if (attacked.getBuffedValue(MapleBuffStat.INVINCIBILITY) != null
            || PlayersHandler.inArea(attacked)) {
          rawDamage = 0;
        }
        rawDamage += (rawDamage * chr.getDamageIncrease(attacked.getId()) / 100.0);
        rawDamage *= attacked.getStat().mesoGuard / 100.0;
        rawDamage = attacked.modifyDamageTaken(rawDamage, attacked).left;
        final double min = (rawDamage * chr.getStat().trueMastery / 100);
        attacks = new ArrayList<Pair<Integer, Boolean>>(attackCount);
        int totalMPLoss = 0, totalHPLoss = 0;
        for (int i = 0; i < attackCount; i++) {
          int mploss = 0;
          double ourDamage =
              Randomizer.nextInt((int) Math.abs(Math.round(rawDamage - min)) + 1) + min;
          if (attacked.getStat().dodgeChance > 0
              && Randomizer.nextInt(100) < attacked.getStat().dodgeChance) {
            ourDamage = 0;
            // i dont think level actually matters or it'd be too op
            // } else if (attacked.getLevel() > chr.getLevel() && Randomizer.nextInt(100) <
            // (attacked.getLevel() - chr.getLevel())) {
            //	ourDamage = 0;
          }
          if (attacked.getBuffedValue(MapleBuffStat.MAGIC_GUARD) != null) {
            mploss =
                (int)
                    Math.min(
                        attacked.getStat().getMp(),
                        (ourDamage
                            * attacked.getBuffedValue(MapleBuffStat.MAGIC_GUARD).doubleValue()
                            / 100.0));
          }
          ourDamage -= mploss;
          if (attacked.getBuffedValue(MapleBuffStat.INFINITY) != null) {
            mploss = 0;
          }
          attacks.add(new Pair<Integer, Boolean>((int) Math.floor(ourDamage), false));

          totalHPLoss += Math.floor(ourDamage);
          totalMPLoss += mploss;
        }
        attacked.addMPHP(-totalHPLoss, -totalMPLoss);
        ourAttacks.add(new AttackPair(attacked.getId(), attacked.getPosition(), attacks));
        attacked.getCheatTracker().setAttacksWithoutHit(false);
        if (totalHPLoss > 0) {
          didAttack = true;
        }
        if (attacked.getStat().getHPPercent() <= 20) {
          SkillFactory.getSkill(attacked.getStat().getSkillByJob(93, attacked.getJob()))
              .getEffect(1)
              .applyTo(attacked);
        }
        if (effect != null) {
          if (effect.getMonsterStati().size() > 0 && effect.makeChanceResult()) {
            for (Map.Entry<MonsterStatus, Integer> z : effect.getMonsterStati().entrySet()) {
              MapleDisease d = MonsterStatus.getLinkedDisease(z.getKey());
              if (d != null) {
                attacked.giveDebuff(d, z.getValue(), effect.getDuration(), d.getDisease(), 1);
              }
            }
          }
          effect.handleExtraPVP(chr, attacked);
        }
        chr.getClient()
            .getSession()
            .write(
                CField.getPVPHPBar(
                    attacked.getId(),
                    attacked.getStat().getHp(),
                    attacked.getStat().getCurrentMaxHp()));
        addedScore += (totalHPLoss / 100) + (totalMPLoss / 100); // ive NO idea
        if (!attacked.isAlive()) {
          killed = true;
        }

        if (ourAttacks.size() >= mobCount) {
          break;
        }
      }
    }
    if (killed || addedScore > 0) {
      chr.getEventInstance().addPVPScore(chr, addedScore);
      chr.getClient().getSession().write(CField.getPVPScore(ourScore + addedScore, killed));
    }
    if (didAttack) {
      chr.getMap()
          .broadcastMessage(
              SummonPacket.pvpSummonAttack(
                  chr.getId(),
                  chr.getLevel(),
                  summon.getObjectId(),
                  summon.isFacingLeft() ? 4 : 0x84,
                  summon.getTruePosition(),
                  ourAttacks));
      if (!summon.isMultiAttack()) {
        chr.getMap().broadcastMessage(SummonPacket.removeSummon(summon, true));
        chr.getMap().removeMapObject(summon);
        chr.removeVisibleMapObject(summon);
        chr.removeSummon(summon);
        if (summon.getSkill() != 35121011) {
          chr.cancelEffectFromBuffStat(MapleBuffStat.SUMMON);
        }
      }
    }
  }