public static void CreateChar(LittleEndianAccessor slea, MapleClient c) {
    String name = slea.readMapleAsciiString();
    slea.skip(4);
    final JobType jobType =
        JobType.getByType(
            slea
                .readInt()); // BIGBANG: 0 = Resistance, 1 = Adventurer, 2 = Cygnus, 3 = Aran, 4 =
                             // Evan, 5 = Mercedes
    final short subCategory = slea.readShort(); // whether dual blade = 1 or adventurer = 0
    final byte gender = slea.readByte();
    byte skinColor = slea.readByte(); // 01
    int hairColor = 0;
    slea.skip(1);
    boolean mercedes = (jobType == JobType.Mercedes);
    boolean demon = (jobType == JobType.Demon);
    boolean adventurer = (jobType == JobType.Adventurer);
    int face = slea.readInt();
    int hair = slea.readInt();

    final int demonMark = demon ? slea.readInt() : 0;
    int top = slea.readInt();
    int bottom = (mercedes || demon || adventurer) ? 0 : slea.readInt();
    int shoes = slea.readInt();
    int weapon = slea.readInt();
    int shield = demon ? slea.readInt() : (mercedes ? 1352000 : 0);

    MapleCharacter newchar = MapleCharacter.getDefault(c);
    newchar.setWorld((byte) c.getWorld());
    newchar.setFace(face);
    newchar.setHair(hair + hairColor);
    newchar.setGender(gender);
    newchar.setName(name);
    newchar.setSkinColor(skinColor);
    newchar.setDemonMarking(demonMark);
    newchar.setSubcategory(subCategory);

    MapleInventory equip = newchar.getInventory(MapleInventoryType.EQUIPPED);
    Item eq_top = MapleItemInformationProvider.getInstance().getEquipById(top);
    eq_top.setPosition((byte) -5);
    equip.addFromDB(eq_top);
    Item eq_bottom = MapleItemInformationProvider.getInstance().getEquipById(bottom);
    eq_bottom.setPosition((byte) -6);
    Item eq_shoes = MapleItemInformationProvider.getInstance().getEquipById(shoes);
    eq_shoes.setPosition((byte) -7);
    equip.addFromDB(eq_shoes);
    Item eq_weapon = MapleItemInformationProvider.getInstance().getEquipById(weapon);
    eq_weapon.setPosition((byte) -11);
    equip.addFromDB(eq_weapon);

    if (MapleCharacterUtil.canCreateChar(name, false)
        && !LoginInformationProvider.getInstance().isForbiddenName(name)) {
      MapleCharacter.saveNewCharToDB(newchar, (short) 0);
      c.getSession().write(LoginPacket.addNewCharEntry(newchar, true));
      c.createdChar(newchar.getId());
    } else {
      c.getSession().write(LoginPacket.addNewCharEntry(newchar, false));
    }
    newchar = null;
  }
  public static final void MoveSummon(final LittleEndianAccessor slea, final MapleCharacter chr) {
    if (chr == null || chr.getMap() == null) {
      return;
    }
    final MapleMapObject obj = chr.getMap().getMapObject(slea.readInt(), MapleMapObjectType.SUMMON);
    if (obj == null) {
      return;
    }
    if (obj instanceof MapleDragon) {
      MoveDragon(slea, chr);
      return;
    }
    final MapleSummon sum = (MapleSummon) obj;
    if (sum.getOwnerId() != chr.getId()
        || sum.getSkillLevel() <= 0
        || sum.getMovementType() == SummonMovementType.STATIONARY) {
      return;
    }
    slea.skip(8); // startPOS
    final List<LifeMovementFragment> res = MovementParse.parseMovement(slea, 4);

    final Point pos = sum.getPosition();
    MovementParse.updatePosition(res, sum, 0);
    if (res.size() > 0) {
      chr.getMap()
          .broadcastMessage(
              chr,
              SummonPacket.moveSummon(chr.getId(), sum.getObjectId(), pos, res),
              sum.getTruePosition());
    }
  }
  public static final void MoveDragon(final LittleEndianAccessor slea, final MapleCharacter chr) {
    slea.skip(8); // POS
    final List<LifeMovementFragment> res = MovementParse.parseMovement(slea, 5);
    if (chr != null && chr.getDragon() != null && res.size() > 0) {
      final Point pos = chr.getDragon().getPosition();
      MovementParse.updatePosition(res, chr.getDragon(), 0);
      if (!chr.isHidden()) {
        chr.getMap()
            .broadcastMessage(
                chr, CField.moveDragon(chr.getDragon(), pos, res), chr.getTruePosition());
      }

      WeakReference<MapleCharacter>[] clones = chr.getClones();
      for (int i = 0; i < clones.length; i++) {
        if (clones[i].get() != null) {
          final MapleMap map = chr.getMap();
          final MapleCharacter clone = clones[i].get();
          CloneTimer.getInstance()
              .schedule(
                  new Runnable() {

                    public void run() {
                      try {
                        if (clone.getMap() == map && clone.getDragon() != null) {
                          final Point startPos = clone.getDragon().getPosition();
                          MovementParse.updatePosition(res, clone.getDragon(), 0);
                          if (!clone.isHidden()) {
                            map.broadcastMessage(
                                clone,
                                CField.moveDragon(clone.getDragon(), startPos, res),
                                clone.getTruePosition());
                          }
                        }
                      } catch (Exception e) {
                        // very rarely swallowed
                      }
                    }
                  },
                  500 * i + 500);
        }
      }
    }
  }
Example #4
0
 public static void MTSOperation(final LittleEndianAccessor slea, final MapleClient c) {
   final MTSCart cart = MTSStorage.getInstance().getCart(c.getPlayer().getId());
   // System.out.println(slea.toString());
   if (slea.available() <= 0) {
     doMTSPackets(cart, c);
     return;
   }
   final byte op = slea.readByte();
   if (op == 2) { // put up for sale
     final byte invType = slea.readByte(); // 1 = equip 2 = everything else
     if (invType != 1 && invType != 2) { // pet?
       c.getSession().write(MTSCSPacket.getMTSFailSell());
       doMTSPackets(cart, c);
       return;
     }
     final int itemid = slea.readInt(); // itemid
     if (slea.readByte() != 0) {
       c.getSession().write(MTSCSPacket.getMTSFailSell());
       doMTSPackets(cart, c);
       return; // we don't like uniqueIDs
     }
     slea.skip(12); // expiration, -1, don't matter
     short stars = 1, quantity = 1;
     byte slot = 0;
     if (invType == 1) {
       slea.skip(32);
     } else {
       stars = slea.readShort(); // the entire quantity of the item
     }
     slea.readMapleAsciiString(); // owner
     // again? =/
     if (invType == 1) {
       slea.skip(50);
       slot = (byte) slea.readInt();
       slea.skip(4); // skip the quantity int, equips are always 1
     } else {
       slea.readShort(); // flag
       if (GameConstants.isThrowingStar(itemid) || GameConstants.isBullet(itemid)) {
         slea.skip(8); // recharge ID thing
       }
       slot = (byte) slea.readInt();
       if (GameConstants.isThrowingStar(itemid) || GameConstants.isBullet(itemid)) {
         quantity =
             stars; // this is due to stars you need to use the entire quantity, not specified
         slea.skip(4); // so just skip the quantity int
       } else {
         quantity = (short) slea.readInt(); // specified quantity
       }
     }
     final int price = slea.readInt();
     final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
     final MapleInventoryType type = GameConstants.getInventoryType(itemid);
     final Item item = c.getPlayer().getInventory(type).getItem(slot).copy();
     if (ii.isCash(itemid)
         || quantity <= 0
         || item == null
         || item.getQuantity() <= 0
         || item.getItemId() != itemid
         || item.getUniqueId() > 0
         || item.getQuantity() < quantity
         || price < ServerConstants.MIN_MTS
         || c.getPlayer().getMeso() < ServerConstants.MTS_MESO
         || cart.getNotYetSold().size() >= 10
         || ii.isDropRestricted(itemid)
         || ii.isAccountShared(itemid)
         || item.getExpiration() > -1
         || item.getFlag() > 0) {
       c.getSession().write(MTSCSPacket.getMTSFailSell());
       doMTSPackets(cart, c);
       return;
     }
     if (type == MapleInventoryType.EQUIP) {
       final Equip eq = (Equip) item;
       if (eq.getState() > 0 || eq.getEnhance() > 0 || eq.getDurability() > -1) {
         c.getSession().write(MTSCSPacket.getMTSFailSell());
         doMTSPackets(cart, c);
         return;
       }
     }
     if (quantity >= 50 && item.getItemId() == 2340000) {
       c.setMonitored(true); // hack check
     }
     final long expiration = (System.currentTimeMillis() + (7L * 24 * 60 * 60 * 1000));
     item.setQuantity(quantity);
     MTSStorage.getInstance()
         .addToBuyNow(
             cart, item, price, c.getPlayer().getId(), c.getPlayer().getName(), expiration);
     MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false);
     c.getPlayer().gainMeso(-ServerConstants.MTS_MESO, false);
     c.getSession().write(MTSCSPacket.getMTSConfirmSell());
   } else if (op == 5) { // change page/tab
     cart.changeInfo(slea.readInt(), slea.readInt(), slea.readInt());
   } else if (op == 6) { // search
     cart.changeInfo(slea.readInt(), slea.readInt(), 0);
     slea.readInt(); // always 0?
     cart.changeCurrentView(
         MTSStorage.getInstance()
             .getSearch(
                 slea.readInt() > 0, slea.readMapleAsciiString(), cart.getType(), cart.getTab()));
   } else if (op == 7) { // cancel sale
     if (!MTSStorage.getInstance().removeFromBuyNow(slea.readInt(), c.getPlayer().getId(), true)) {
       c.getSession().write(MTSCSPacket.getMTSFailCancel());
     } else {
       c.getSession().write(MTSCSPacket.getMTSConfirmCancel());
       sendMTSPackets(cart, c, true);
       return;
     }
   } else if (op == 8) { // transfer item
     final int id = Integer.MAX_VALUE - slea.readInt(); // fake id
     if (id >= cart.getInventory().size()) {
       c.getPlayer().dropMessage(1, "Please try it again later.");
       sendMTSPackets(cart, c, true);
       return;
     }
     final Item item = cart.getInventory().get(id); // by index
     // System.out.println("NumItems: " + cart.getInventory().size() + ", ID: " + id + ",
     // ItemExists?: " + (item != null));
     if (item != null
         && item.getQuantity() > 0
         && MapleInventoryManipulator.checkSpace(
             c, item.getItemId(), item.getQuantity(), item.getOwner())) {
       Item item_ = item.copy();
       short pos = MapleInventoryManipulator.addbyItem(c, item_, true);
       if (pos >= 0) {
         if (item_.getPet() != null) {
           item_.getPet().setInventoryPosition(pos);
           c.getPlayer().addPet(item_.getPet());
         }
         cart.removeFromInventory(item);
         c.getSession()
             .write(
                 MTSCSPacket.getMTSConfirmTransfer(
                     GameConstants.getInventoryType(item_.getItemId()).getType(),
                     pos)); // IF this is actually pos and pos
         sendMTSPackets(cart, c, true);
         return;
       } else {
         // System.out.println("addByItem is less than 0");
         c.getSession().write(MTSCSPacket.getMTSFailBuy());
       }
     } else {
       // System.out.println("CheckSpace return false");
       c.getSession().write(MTSCSPacket.getMTSFailBuy());
     }
   } else if (op == 9) { // add to cart
     final int id = slea.readInt();
     if (MTSStorage.getInstance().checkCart(id, c.getPlayer().getId()) && cart.addToCart(id)) {
       c.getSession().write(MTSCSPacket.addToCartMessage(false, false));
     } else {
       c.getSession().write(MTSCSPacket.addToCartMessage(true, false));
     }
   } else if (op == 10) { // delete from cart
     final int id = slea.readInt();
     if (cart.getCart().contains(id)) {
       cart.removeFromCart(id);
       c.getSession().write(MTSCSPacket.addToCartMessage(false, true));
     } else {
       c.getSession().write(MTSCSPacket.addToCartMessage(true, true));
     }
   } else if (op == 16 || op == 17) { // buyNow, buy from cart
     final MTSItemInfo mts = MTSStorage.getInstance().getSingleItem(slea.readInt());
     if (mts != null && mts.getCharacterId() != c.getPlayer().getId()) {
       if (c.getPlayer().getCSPoints(1) > mts.getRealPrice()) {
         if (MTSStorage.getInstance()
             .removeFromBuyNow(mts.getId(), c.getPlayer().getId(), false)) {
           c.getPlayer().modifyCSPoints(1, -mts.getRealPrice(), false);
           MTSStorage.getInstance().getCart(mts.getCharacterId()).increaseOwedNX(mts.getPrice());
           c.getSession().write(MTSCSPacket.getMTSConfirmBuy());
           sendMTSPackets(cart, c, true);
           return;
         } else {
           c.getSession().write(MTSCSPacket.getMTSFailBuy());
         }
       } else {
         c.getSession().write(MTSCSPacket.getMTSFailBuy());
       }
     } else {
       c.getSession().write(MTSCSPacket.getMTSFailBuy());
     }
   } else if (c.getPlayer().isAdmin()) {
     // System.out.println("New MTS Op " + op + ", \n" + slea.toString());
   }
   doMTSPackets(cart, c);
 }
  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);
        }
      }
    }
  }
 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);
   }
 }
  public static void SummonAttack(
      final LittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) {
    if (chr == null || !chr.isAlive() || chr.getMap() == null) {
      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;
    }
    final MapleSummon summon = (MapleSummon) obj;
    if (summon.getOwnerId() != chr.getId() || summon.getSkillLevel() <= 0) {
      chr.dropMessage(5, "Error.");
      return;
    }
    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;
    }
    if (!GameConstants.GMS) {
      slea.skip(8);
    }
    int tick = slea.readInt();
    if (sse != null && sse.delay > 0) {
      chr.updateTick(tick);
      // summon.CheckSummonAttackFrequency(chr, tick);
      // chr.getCheatTracker().checkSummonAttack();
    }
    if (!GameConstants.GMS) {
      slea.skip(8);
    }
    final byte animation = slea.readByte();
    if (!GameConstants.GMS) {
      slea.skip(8);
    }
    final byte numAttacked = slea.readByte();
    if (sse != null && numAttacked > sse.mobCount) {
      chr.dropMessage(5, "Warning: Attacking more monster than summon can do");
      chr.getCheatTracker().registerOffense(CheatingOffense.SUMMON_HACK_MOBS);
      // AutobanManager.getInstance().autoban(c, "Attacking more monster that summon can do (Skillid
      // : "+summon.getSkill()+" Count : " + numAttacked + ", allowed : " + sse.mobCount + ")");
      return;
    }
    slea.skip(summon.getSkill() == 35111002 ? 24 : 12); // some pos stuff
    final List<Pair<Integer, Integer>> allDamage = new ArrayList<Pair<Integer, Integer>>();
    for (int i = 0; i < numAttacked; i++) {
      final MapleMonster mob = map.getMonsterByOid(slea.readInt());

      if (mob == null) {
        continue;
      }
      slea.skip(22); // who knows
      final int damge = slea.readInt();
      allDamage.add(new Pair<Integer, Integer>(mob.getObjectId(), damge));
    }
    // if (!summon.isChangedMap()) {
    map.broadcastMessage(
        chr,
        SummonPacket.summonAttack(
            summon.getOwnerId(), summon.getObjectId(), animation, allDamage, chr.getLevel(), false),
        summon.getTruePosition());
    // }
    final Skill summonSkill = SkillFactory.getSkill(summon.getSkill());
    final MapleStatEffect summonEffect = summonSkill.getEffect(summon.getSkillLevel());
    if (summonEffect == null) {
      chr.dropMessage(5, "Error in attack.");
      return;
    }
    for (Pair<Integer, Integer> attackEntry : allDamage) {
      final int toDamage = attackEntry.right;
      final MapleMonster mob = map.getMonsterByOid(attackEntry.left);
      if (mob == null) {
        continue;
      }
      if (sse != null
          && sse.delay > 0
          && summon.getMovementType() != SummonMovementType.STATIONARY
          && summon.getMovementType() != SummonMovementType.CIRCLE_STATIONARY
          && summon.getMovementType() != SummonMovementType.WALK_STATIONARY
          && chr.getTruePosition().distanceSq(mob.getTruePosition()) > 400000.0) {
        // chr.getCheatTracker().registerOffense(CheatingOffense.ATTACK_FARAWAY_MONSTER_SUMMON);
      }
      if (toDamage > 0 && summonEffect.getMonsterStati().size() > 0) {
        if (summonEffect.makeChanceResult()) {
          for (Map.Entry<MonsterStatus, Integer> z : summonEffect.getMonsterStati().entrySet()) {
            mob.applyStatus(
                chr,
                new MonsterStatusEffect(z.getKey(), z.getValue(), summonSkill.getId(), null, false),
                summonEffect.isPoison(),
                4000,
                true,
                summonEffect);
          }
        }
      }
      if (chr.isGM()
          || toDamage
              < (chr.getStat().getCurrentMaxBaseDamage()
                  * 5.0
                  * (summonEffect.getSelfDestruction()
                      + summonEffect.getDamage()
                      + chr.getStat().getDamageIncrease(summonEffect.getSourceId()))
                  / 100.0)) { // 10 x dmg.. eh
        mob.damage(chr, toDamage, true);
        chr.checkMonsterAggro(mob);
        if (!mob.isAlive()) {
          chr.getClient().getSession().write(MobPacket.killMonster(mob.getObjectId(), 1));
        }
      } else {
        chr.dropMessage(5, "Warning - high damage.");
        // AutobanManager.getInstance().autoban(c, "High Summon Damage (" + toDamage + " to " +
        // attackEntry.right + ")");
        // TODO : Check player's stat for damage checking.
        break;
      }
    }
    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);
      }
    }
  }