コード例 #1
0
 private static int[] getCrystal(final int itemid, final int level) {
   int[] all = new int[2];
   all[0] = -1;
   if (level >= 31 && level <= 50) {
     all[0] = 4260000;
   } else if (level >= 51 && level <= 60) {
     all[0] = 4260001;
   } else if (level >= 61 && level <= 70) {
     all[0] = 4260002;
   } else if (level >= 71 && level <= 80) {
     all[0] = 4260003;
   } else if (level >= 81 && level <= 90) {
     all[0] = 4260004;
   } else if (level >= 91 && level <= 100) {
     all[0] = 4260005;
   } else if (level >= 101 && level <= 110) {
     all[0] = 4260006;
   } else if (level >= 111 && level <= 120) {
     all[0] = 4260007;
   } else if (level >= 121 && level <= 200) {
     all[0] = 4260008;
   } else {
     throw new RuntimeException("Invalid Item Maker type" + level);
   }
   if (GameConstants.isWeapon(itemid) || GameConstants.isOverall(itemid)) {
     all[1] = Randomizer.rand(5, 11);
   } else {
     all[1] = Randomizer.rand(3, 7);
   }
   return all;
 }
コード例 #2
0
  public static Pair<String, String> getImageBytes() {
    try {
      URL url =
          new URL("http://localhost/captcha.php?verify=98818D40B83AECCFB7AFD7FD9653E1037519AC61");

      InputStream inputStream = url.openStream();
      ByteArrayOutputStream output = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      int n = 0;
      while (-1 != (n = inputStream.read(buffer))) {
        output.write(buffer, 0, n);
      }
      String imgByte = HexTool.toString(output.toByteArray());
      return new Pair(
          imgByte.substring(39, imgByte.length()), output.toString().split("CAPTCHA")[0]);
    } catch (IOException ex) {
      File directory = new File(IMG_DIRECTORY);
      if (!directory.exists()) {
        System.err.println("lieDetector folder does not exist!");
        return null;
      }
      String[] filename = directory.list();
      String answer = filename[server.Randomizer.nextInt(filename.length)];
      answer = answer.substring(0, answer.length() - 4);
      try {
        return new Pair(
            HexTool.toString(getBytesFromFile(new File(IMG_DIRECTORY + answer + ".jpg"))), answer);
      } catch (IOException e) {
      }
    }
    return null;
  }
コード例 #3
0
  private static int getRandomGem(final List<Pair<Integer, Integer>> rewards) {
    int itemid;
    final List<Integer> items = new ArrayList<>();

    for (final Pair p : rewards) {
      itemid = (Integer) p.getLeft();
      for (int i = 0; i < (Integer) p.getRight(); i++) {
        items.add(itemid);
      }
    }
    return items.get(Randomizer.nextInt(items.size()));
  }
コード例 #4
0
  public static final void ItemMaker(final LittleEndianAccessor slea, final MapleClient c) {
    // System.out.println(slea.toString()); //change?
    final int makerType = slea.readInt();

    switch (makerType) {
      case 1:
        { // Gem
          final int toCreate = slea.readInt();

          if (GameConstants.isGem(toCreate)) {
            final GemCreateEntry gem = ItemMakerFactory.getInstance().getGemInfo(toCreate);
            if (gem == null) {
              return;
            }
            if (!hasSkill(c, gem.getReqSkillLevel())) {
              return; // H4x
            }
            if (c.getPlayer().getMeso() < gem.getCost()) {
              return; // H4x
            }
            final int randGemGiven = getRandomGem(gem.getRandomReward());

            if (c.getPlayer().getInventory(GameConstants.getInventoryType(randGemGiven)).isFull()) {
              return; // We'll do handling for this later
            }
            final int taken = checkRequiredNRemove(c, gem.getReqRecipes());
            if (taken == 0) {
              return; // We'll do handling for this later
            }
            c.getPlayer().gainMeso(-gem.getCost(), false);
            MapleInventoryManipulator.addById(
                c,
                randGemGiven,
                (byte) (taken == randGemGiven ? 9 : 1),
                "Made by Gem "
                    + toCreate
                    + " on "
                    + FileoutputUtil.CurrentReadable_Date()); // Gem is always 1

            c.getSession().write(EffectPacket.ItemMaker_Success());
            c.getPlayer()
                .getMap()
                .broadcastMessage(
                    c.getPlayer(),
                    EffectPacket.ItemMaker_Success_3rdParty(c.getPlayer().getId()),
                    false);
          } else if (GameConstants.isOtherGem(toCreate)) {
            // non-gems that are gems
            // stim and numEnchanter always 0
            final GemCreateEntry gem = ItemMakerFactory.getInstance().getGemInfo(toCreate);
            if (gem == null) {
              return;
            }
            if (!hasSkill(c, gem.getReqSkillLevel())) {
              return; // H4x
            }
            if (c.getPlayer().getMeso() < gem.getCost()) {
              return; // H4x
            }

            if (c.getPlayer().getInventory(GameConstants.getInventoryType(toCreate)).isFull()) {
              return; // We'll do handling for this later
            }
            if (checkRequiredNRemove(c, gem.getReqRecipes()) == 0) {
              return; // We'll do handling for this later
            }
            c.getPlayer().gainMeso(-gem.getCost(), false);
            if (GameConstants.getInventoryType(toCreate) == MapleInventoryType.EQUIP) {
              MapleInventoryManipulator.addbyItem(
                  c, MapleItemInformationProvider.getInstance().getEquipById(toCreate));
            } else {
              MapleInventoryManipulator.addById(
                  c,
                  toCreate,
                  (byte) 1,
                  "Made by Gem "
                      + toCreate
                      + " on "
                      + FileoutputUtil.CurrentReadable_Date()); // Gem is always 1
            }

            c.getSession().write(EffectPacket.ItemMaker_Success());
            c.getPlayer()
                .getMap()
                .broadcastMessage(
                    c.getPlayer(),
                    EffectPacket.ItemMaker_Success_3rdParty(c.getPlayer().getId()),
                    false);
          } else {
            final boolean stimulator = slea.readByte() > 0;
            final int numEnchanter = slea.readInt();

            final ItemMakerCreateEntry create =
                ItemMakerFactory.getInstance().getCreateInfo(toCreate);
            if (create == null) {
              return;
            }
            if (numEnchanter > create.getTUC()) {
              return; // h4x
            }
            if (!hasSkill(c, create.getReqSkillLevel())) {
              return; // H4x
            }
            if (c.getPlayer().getMeso() < create.getCost()) {
              return; // H4x
            }
            if (c.getPlayer().getInventory(GameConstants.getInventoryType(toCreate)).isFull()) {
              return; // We'll do handling for this later
            }
            if (checkRequiredNRemove(c, create.getReqItems()) == 0) {
              return; // We'll do handling for this later
            }
            c.getPlayer().gainMeso(-create.getCost(), false);

            final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
            final Equip toGive = (Equip) ii.getEquipById(toCreate);

            if (stimulator || numEnchanter > 0) {
              if (c.getPlayer().haveItem(create.getStimulator(), 1, false, true)) {
                ii.randomizeStats_Above(toGive);
                MapleInventoryManipulator.removeById(
                    c, MapleInventoryType.ETC, create.getStimulator(), 1, false, false);
              }
              for (int i = 0; i < numEnchanter; i++) {
                final int enchant = slea.readInt();
                if (c.getPlayer().haveItem(enchant, 1, false, true)) {
                  final Map<String, Integer> stats = ii.getEquipStats(enchant);
                  if (stats != null) {
                    addEnchantStats(stats, toGive);
                    MapleInventoryManipulator.removeById(
                        c, MapleInventoryType.ETC, enchant, 1, false, false);
                  }
                }
              }
            }
            if (!stimulator || Randomizer.nextInt(10) != 0) {
              MapleInventoryManipulator.addbyItem(c, toGive);
              c.getPlayer()
                  .getMap()
                  .broadcastMessage(
                      c.getPlayer(),
                      EffectPacket.ItemMaker_Success_3rdParty(c.getPlayer().getId()),
                      false);
            } else {
              c.getPlayer().dropMessage(5, "The item was overwhelmed by the stimulator.");
            }
            c.getSession().write(EffectPacket.ItemMaker_Success());
          }
          break;
        }
      case 3:
        { // Making Crystals
          final int etc = slea.readInt();
          if (c.getPlayer().haveItem(etc, 100, false, true)) {
            MapleInventoryManipulator.addById(
                c,
                getCreateCrystal(etc),
                (short) 1,
                "Made by Maker " + etc + " on " + FileoutputUtil.CurrentReadable_Date());
            MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, etc, 100, false, false);

            c.getSession().write(EffectPacket.ItemMaker_Success());
            c.getPlayer()
                .getMap()
                .broadcastMessage(
                    c.getPlayer(),
                    EffectPacket.ItemMaker_Success_3rdParty(c.getPlayer().getId()),
                    false);
          }
          break;
        }
      case 4:
        { // Disassembling EQ.
          final int itemId = slea.readInt();
          c.getPlayer().updateTick(slea.readInt());
          final byte slot = (byte) slea.readInt();

          final Item toUse = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(slot);
          if (toUse == null || toUse.getItemId() != itemId || toUse.getQuantity() < 1) {
            return;
          }
          final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();

          if (!ii.isDropRestricted(itemId) && !ii.isAccountShared(itemId)) {
            final int[] toGive = getCrystal(itemId, ii.getReqLevel(itemId));
            MapleInventoryManipulator.addById(
                c,
                toGive[0],
                (byte) toGive[1],
                "Made by disassemble " + itemId + " on " + FileoutputUtil.CurrentReadable_Date());
            MapleInventoryManipulator.removeFromSlot(
                c, MapleInventoryType.EQUIP, slot, (byte) 1, false);
          }
          c.getSession().write(EffectPacket.ItemMaker_Success());
          c.getPlayer()
              .getMap()
              .broadcastMessage(
                  c.getPlayer(),
                  EffectPacket.ItemMaker_Success_3rdParty(c.getPlayer().getId()),
                  false);
          break;
        }
    }
  }
コード例 #5
0
 public static final void FeedPot(final LittleEndianAccessor slea, final MapleClient c) {
   final int itemid = slea.readInt();
   final Item slot =
       c.getPlayer()
           .getInventory(GameConstants.getInventoryType(itemid))
           .getItem((short) slea.readInt());
   if (slot == null || slot.getQuantity() <= 0 || slot.getItemId() != itemid) {
     c.getSession().write(CWvsContext.enableActions());
     return;
   }
   final int level =
       GameConstants.getInventoryType(itemid) == MapleInventoryType.ETC
           ? MapleItemInformationProvider.getInstance().getItemMakeLevel(itemid)
           : MapleItemInformationProvider.getInstance().getReqLevel(itemid);
   if (level <= 0
       || level < (Math.min(120, c.getPlayer().getLevel()) - 50)
       || (GameConstants.getInventoryType(itemid) != MapleInventoryType.ETC
           && GameConstants.getInventoryType(itemid) != MapleInventoryType.EQUIP)) {
     c.getPlayer().dropMessage(1, "The item must be within 50 levels of you.");
     c.getSession().write(CWvsContext.enableActions());
     return;
   }
   final int index = slea.readInt() - 1;
   if (index < 0
       || index >= c.getPlayer().getImps().length
       || c.getPlayer().getImps()[index] == null
       || c.getPlayer().getImps()[index].getLevel()
           >= (MapleItemInformationProvider.getInstance()
                   .getPot(c.getPlayer().getImps()[index].getItemId())
                   .right
               - 1)
       || c.getPlayer().getImps()[index].getState() != 1) {
     c.getSession().write(CWvsContext.enableActions());
     return;
   }
   int mask = ImpFlag.FULLNESS.getValue();
   mask |= ImpFlag.FULLNESS_2.getValue();
   mask |= ImpFlag.UPDATE_TIME.getValue();
   mask |= ImpFlag.AWAKE_TIME.getValue();
   // this is where the magic happens
   c.getPlayer()
       .getImps()[index]
       .setFullness(
           c.getPlayer().getImps()[index].getFullness()
               + (100
                   * (GameConstants.getInventoryType(itemid) == MapleInventoryType.EQUIP
                       ? 2
                       : 1)));
   if (Randomizer.nextBoolean()) {
     mask |= ImpFlag.CLOSENESS.getValue();
     c.getPlayer()
         .getImps()[index]
         .setCloseness(
             c.getPlayer().getImps()[index].getCloseness()
                 + 1
                 + (Randomizer.nextInt(
                     5
                         * (GameConstants.getInventoryType(itemid) == MapleInventoryType.EQUIP
                             ? 2
                             : 1))));
   } else if (Randomizer.nextInt(5) == 0) { // 1/10 chance of sickness
     c.getPlayer().getImps()[index].setState(4); // sick
     mask |= ImpFlag.STATE.getValue();
   }
   if (c.getPlayer().getImps()[index].getFullness() >= 1000) {
     c.getPlayer().getImps()[index].setState(1);
     c.getPlayer().getImps()[index].setFullness(0);
     c.getPlayer().getImps()[index].setLevel(c.getPlayer().getImps()[index].getLevel() + 1);
     mask |= ImpFlag.SUMMONED.getValue();
     if (c.getPlayer().getImps()[index].getLevel()
         >= (MapleItemInformationProvider.getInstance()
                 .getPot(c.getPlayer().getImps()[index].getItemId())
                 .right
             - 1)) {
       c.getPlayer().getImps()[index].setState(5);
     }
   }
   MapleInventoryManipulator.removeFromSlot(
       c, GameConstants.getInventoryType(itemid), slot.getPosition(), (short) 1, false, false);
   c.getSession().write(CWvsContext.updateImp(c.getPlayer().getImps()[index], mask, index, false));
 }
コード例 #6
0
 private static void addEnchantStats(final Map<String, Integer> stats, final Equip item) {
   Integer s = stats.get("PAD");
   if (s != null && s != 0) {
     item.setWatk((short) (item.getWatk() + s));
   }
   s = stats.get("MAD");
   if (s != null && s != 0) {
     item.setMatk((short) (item.getMatk() + s));
   }
   s = stats.get("ACC");
   if (s != null && s != 0) {
     item.setAcc((short) (item.getAcc() + s));
   }
   s = stats.get("EVA");
   if (s != null && s != 0) {
     item.setAvoid((short) (item.getAvoid() + s));
   }
   s = stats.get("Speed");
   if (s != null && s != 0) {
     item.setSpeed((short) (item.getSpeed() + s));
   }
   s = stats.get("Jump");
   if (s != null && s != 0) {
     item.setJump((short) (item.getJump() + s));
   }
   s = stats.get("MaxHP");
   if (s != null && s != 0) {
     item.setHp((short) (item.getHp() + s));
   }
   s = stats.get("MaxMP");
   if (s != null && s != 0) {
     item.setMp((short) (item.getMp() + s));
   }
   s = stats.get("STR");
   if (s != null && s != 0) {
     item.setStr((short) (item.getStr() + s));
   }
   s = stats.get("DEX");
   if (s != null && s != 0) {
     item.setDex((short) (item.getDex() + s));
   }
   s = stats.get("INT");
   if (s != null && s != 0) {
     item.setInt((short) (item.getInt() + s));
   }
   s = stats.get("LUK");
   if (s != null && s != 0) {
     item.setLuk((short) (item.getLuk() + s));
   }
   s = stats.get("randOption");
   if (s != null && s != 0) {
     final int ma = item.getMatk(), wa = item.getWatk();
     if (wa > 0) {
       item.setWatk((short) (Randomizer.nextBoolean() ? (wa + s) : (wa - s)));
     }
     if (ma > 0) {
       item.setMatk((short) (Randomizer.nextBoolean() ? (ma + s) : (ma - s)));
     }
   }
   s = stats.get("randStat");
   if (s != null && s != 0) {
     final int str = item.getStr(), dex = item.getDex(), luk = item.getLuk(), int_ = item.getInt();
     if (str > 0) {
       item.setStr((short) (Randomizer.nextBoolean() ? (str + s) : (str - s)));
     }
     if (dex > 0) {
       item.setDex((short) (Randomizer.nextBoolean() ? (dex + s) : (dex - s)));
     }
     if (int_ > 0) {
       item.setInt((short) (Randomizer.nextBoolean() ? (int_ + s) : (int_ - s)));
     }
     if (luk > 0) {
       item.setLuk((short) (Randomizer.nextBoolean() ? (luk + s) : (luk - s)));
     }
   }
 }
コード例 #7
0
  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);
        }
      }
    }
  }
コード例 #8
0
 public static final void SubSummon(final LittleEndianAccessor slea, final MapleCharacter chr) {
   final MapleMapObject obj = chr.getMap().getMapObject(slea.readInt(), MapleMapObjectType.SUMMON);
   if (obj == null || !(obj instanceof MapleSummon)) {
     return;
   }
   final MapleSummon sum = (MapleSummon) obj;
   if (sum == null
       || sum.getOwnerId() != chr.getId()
       || sum.getSkillLevel() <= 0
       || !chr.isAlive()) {
     return;
   }
   switch (sum.getSkill()) {
     case 35121009:
       if (!chr.canSummon(2000)) {
         return;
       }
       final int skillId = slea.readInt(); // 35121009?
       if (sum.getSkill() != skillId) {
         return;
       }
       slea.skip(1); // 0E?
       chr.updateTick(slea.readInt());
       for (int i = 0; i < 3; i++) {
         final MapleSummon tosummon =
             new MapleSummon(
                 chr,
                 SkillFactory.getSkill(35121011).getEffect(sum.getSkillLevel()),
                 new Point(sum.getTruePosition().x, sum.getTruePosition().y - 5),
                 SummonMovementType.WALK_STATIONARY);
         chr.getMap().spawnSummon(tosummon);
         chr.addSummon(tosummon);
       }
       break;
     case 35111011: // healing
       if (!chr.canSummon(1000)) {
         return;
       }
       chr.addHP(
           (int)
               (chr.getStat().getCurrentMaxHp()
                   * SkillFactory.getSkill(sum.getSkill()).getEffect(sum.getSkillLevel()).getHp()
                   / 100.0));
       chr.getClient()
           .getSession()
           .write(
               EffectPacket.showOwnBuffEffect(
                   sum.getSkill(), 2, chr.getLevel(), sum.getSkillLevel()));
       chr.getMap()
           .broadcastMessage(
               chr,
               EffectPacket.showBuffeffect(
                   chr.getId(), sum.getSkill(), 2, chr.getLevel(), sum.getSkillLevel()),
               false);
       break;
     case 1321007: // beholder
       Skill bHealing = SkillFactory.getSkill(slea.readInt());
       final int bHealingLvl = chr.getTotalSkillLevel(bHealing);
       if (bHealingLvl <= 0 || bHealing == null) {
         return;
       }
       final MapleStatEffect healEffect = bHealing.getEffect(bHealingLvl);
       if (bHealing.getId() == 1320009) {
         healEffect.applyTo(chr);
       } else if (bHealing.getId() == 1320008) {
         if (!chr.canSummon(healEffect.getX() * 1000)) {
           return;
         }
         chr.addHP(healEffect.getHp());
       }
       chr.getClient()
           .getSession()
           .write(EffectPacket.showOwnBuffEffect(sum.getSkill(), 2, chr.getLevel(), bHealingLvl));
       chr.getMap()
           .broadcastMessage(
               SummonPacket.summonSkill(
                   chr.getId(),
                   sum.getSkill(),
                   bHealing.getId() == 1320008 ? 5 : (Randomizer.nextInt(3) + 6)));
       chr.getMap()
           .broadcastMessage(
               chr,
               EffectPacket.showBuffeffect(
                   chr.getId(), sum.getSkill(), 2, chr.getLevel(), bHealingLvl),
               false);
       break;
   }
   if (GameConstants.isAngel(sum.getSkill())) {
     if (sum.getSkill() % 10000 == 1087) {
       MapleItemInformationProvider.getInstance().getItemEffect(2022747).applyTo(chr);
     } else if (sum.getSkill() % 10000 == 1179) {
       MapleItemInformationProvider.getInstance().getItemEffect(2022823).applyTo(chr);
     } else if (sum.getSkill() % 10000 == 1085) {
       MapleItemInformationProvider.getInstance().getItemEffect(2022746).applyTo(chr);
     }
     chr.getClient().getSession().write(EffectPacket.showOwnBuffEffect(sum.getSkill(), 2, 2, 1));
     chr.getMap()
         .broadcastMessage(
             chr, EffectPacket.showBuffeffect(chr.getId(), sum.getSkill(), 2, 2, 1), false);
   }
 }