Example #1
0
 public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
   if (!c.getPlayer().isAlive()) {
     c.announce(MaplePacketCreator.enableActions());
     return;
   }
   slea.readInt();
   byte slot = (byte) slea.readShort();
   int itemId = slea.readInt();
   MapleCharacter player = c.getPlayer();
   IItem toUse = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot);
   if (toUse != null && toUse.getQuantity() == 1) {
     if (toUse.getItemId() != itemId) {
       return;
     }
     Map<String, Integer> skilldata =
         MapleItemInformationProvider.getInstance()
             .getSkillStats(toUse.getItemId(), c.getPlayer().getJob().getId());
     boolean canuse = false;
     boolean success = false;
     int skill = 0;
     int maxlevel = 0;
     if (skilldata == null) {
       return;
     }
     if (skilldata.get("skillid") == 0) {
       canuse = false;
     } else if (player.getMasterLevel(SkillFactory.getSkill(skilldata.get("skillid")))
             >= skilldata.get("reqSkillLevel")
         || skilldata.get("reqSkillLevel") == 0) {
       canuse = true;
       if (Randomizer.nextInt(101) < skilldata.get("success") && skilldata.get("success") != 0) {
         success = true;
         ISkill skill2 = SkillFactory.getSkill(skilldata.get("skillid"));
         player.changeSkillLevel(
             skill2,
             player.getSkillLevel(skill2),
             Math.max(skilldata.get("masterLevel"), player.getMasterLevel(skill2)),
             -1);
       } else {
         success = false;
         player.message(
             "The skill book lights up, but the skill winds up as if nothing happened.");
       }
       MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
     } else {
       canuse = false;
     }
     player
         .getClient()
         .announce(MaplePacketCreator.skillBookSuccess(player, skill, maxlevel, canuse, success));
   }
 }
Example #2
0
 @Override
 public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
   MapleCharacter player = c.getPlayer();
   if (player.getJob().equals(MapleJob.LEGEND)
       || player.getJob().equals(MapleJob.ARAN1)
       || player.getJob().equals(MapleJob.ARAN2)
       || player.getJob().equals(MapleJob.ARAN3)
       || player.getJob().equals(MapleJob.ARAN4)) {
     final long currentTime = System.currentTimeMillis();
     short combo = player.getCombo();
     if ((currentTime - player.getLastCombo()) > 3000 && combo > 0) {
       combo = 0;
       player.cancelEffectFromBuffStat(MapleBuffStat.ARAN_COMBO);
     }
     combo++;
     switch (combo) {
       case 10:
       case 20:
       case 30:
       case 40:
       case 50:
       case 60:
       case 70:
       case 80:
       case 90:
       case 100:
         SkillFactory.getSkill(21000000).getEffect(combo / 10).applyComboBuff(player, combo);
         break;
     }
     player.setLastCombo(currentTime);
     player.setCombo(combo);
   }
 }
Example #3
0
 public MapleSummon(MapleCharacter owner, int skill, Point pos, SummonMovementType movementType) {
   super();
   this.owner = owner;
   this.skill = skill;
   this.skillLevel = owner.getSkillLevel(SkillFactory.getSkill(skill));
   if (skillLevel == 0) {
     throw new RuntimeException("Trying to create a summon for a char without the skill");
   }
   this.movementType = movementType;
   setPosition(pos);
 }
  @Override
  public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    final MapleCharacter chr = c.getPlayer();

    if ((slea.available() > 8L) && (chr != null)) {
      slea.skip(4);
      int numChanges = slea.readInt();

      for (int i = 0; i < numChanges; i++) {
        int key = slea.readInt();
        byte type = slea.readByte();
        int action = slea.readInt();
        if ((type == 1) && (action >= 1000)) {
          Skill skil = SkillFactory.getSkill(action);
          if ((skil != null)
              && (((!skil.isFourthJob())
                      && (!skil.isBeginnerSkill())
                      && (skil.isInvisible())
                      && (chr.getSkillLevel(skil) <= 0))
                  || (GameConstants.isLinkedAttackSkill(action))
                  || (action % 10000 < 1000))) {
            continue;
          }
        }
        chr.changeKeybinding(key, type, action);
      }
    } else if (chr != null) {
      int type = slea.readInt();
      int data = slea.readInt();
      switch (type) {
        case 1:
          if (data <= 0) {
            chr.getQuestRemove(MapleQuest.getInstance(GameConstants.HP_ITEM));
          } else {
            chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.HP_ITEM))
                .setCustomData(String.valueOf(data));
          }
          break;
        case 2:
          if (data <= 0) {
            chr.getQuestRemove(MapleQuest.getInstance(GameConstants.MP_ITEM));
          } else {
            chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.MP_ITEM))
                .setCustomData(String.valueOf(data));
          }
          break;
      }
    }
  }
  @Override
  public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    int sourceid = slea.readInt();
    MapleStatEffect effect;
    ISkill skill = SkillFactory.getSkill(sourceid);

    if (sourceid == 3121004
        || sourceid == 3221001
        || sourceid == 2121001
        || sourceid == 2221001
        || sourceid == 2321001
        || sourceid == 5221004) {
      c.getPlayer()
          .getMap()
          .broadcastMessage(
              c.getPlayer(), MaplePacketCreator.skillCancel(c.getPlayer(), sourceid), false);
    }

    effect = skill.getEffect(1); // hack but we don't know the level that was casted on us �.o
    c.getPlayer().cancelEffect(effect, false, -1);
  }
  @Override
  public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    int cid = slea.readInt();
    MapleCharacter player = null;
    try {
      player = MapleCharacter.loadCharFromDB(cid, c, true);
      c.setPlayer(player);
    } catch (SQLException e) {
    }
    c.setAccID(player.getAccountID());
    int state = c.getLoginState();
    boolean allowLogin = true;
    ChannelServer cserv = c.getChannelServer();
    synchronized (this) {
      try {
        WorldChannelInterface worldInterface = cserv.getWorldInterface();
        if (state == MapleClient.LOGIN_SERVER_TRANSITION) {
          for (String charName : c.loadCharacterNames(c.getWorld())) {
            if (worldInterface.isConnected(charName)) {
              int chanNum = c.getChannelServer().getWorldInterface().getLocation(charName).channel;
              System.err.print(
                  charName
                      + " on channel "
                      + chanNum
                      + " has been unstuck, for bug-testing purposes.");
              MapleCharacter player_to_dc =
                  ChannelServer.getInstance(chanNum)
                      .getPlayerStorage()
                      .getCharacterByName(charName);
              if (player_to_dc.getEventInstance() != null)
                player_to_dc.getEventInstance().removePlayer(player_to_dc);
              player_to_dc.getMap().removePlayer(player_to_dc);
              ChannelServer.getInstance(chanNum).removePlayer(player_to_dc);
              player_to_dc.getClient().disconnect();
              player_to_dc.getClient().getSession().close();
              c.disconnect();
              allowLogin = false;
              break;
            }
          }
        }
      } catch (RemoteException e) {
        cserv.reconnectWorld();
        allowLogin = false;
      } catch (Exception e) {
        System.out.println("Error unsticking char:");
        e.printStackTrace();
      }
      if (state != MapleClient.LOGIN_SERVER_TRANSITION || !allowLogin) {
        c.setPlayer(null);
        c.getSession().close(true);
        return;
      }
      c.updateLoginState(MapleClient.LOGIN_LOGGEDIN);
    }
    cserv.addPlayer(player);
    try {
      List<PlayerBuffValueHolder> buffs = cserv.getWorldInterface().getBuffsFromStorage(cid);
      if (buffs != null) {
        c.getPlayer().silentGiveBuffs(buffs);
      }
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    Connection con = DatabaseConnection.getConnection();
    try {
      PreparedStatement ps =
          con.prepareStatement("SELECT SkillID,StartTime,length FROM cooldowns WHERE charid = ?");
      ps.setInt(1, c.getPlayer().getId());
      ResultSet rs = ps.executeQuery();
      while (rs.next()) {
        final long length = rs.getLong("length"), startTime = rs.getLong("StartTime");
        if (length + startTime > System.currentTimeMillis()) {
          c.getPlayer().giveCoolDowns(rs.getInt("SkillID"), startTime, length);
        }
      }
      rs.close();
      ps.close();
      ps = con.prepareStatement("DELETE FROM cooldowns WHERE charid = ?");
      ps.setInt(1, c.getPlayer().getId());
      ps.executeUpdate();
      ps.close();
      ps =
          con.prepareStatement(
              "SELECT Mesos FROM dueypackages WHERE RecieverId = ? and Checked = 1");
      ps.setInt(1, c.getPlayer().getId());
      rs = ps.executeQuery();
      if (rs.next()) {
        try {
          PreparedStatement pss =
              DatabaseConnection.getConnection()
                  .prepareStatement("UPDATE dueypackages SET Checked = 0 where RecieverId = ?");
          pss.setInt(1, c.getPlayer().getId());
          pss.executeUpdate();
          pss.close();
        } catch (SQLException e) {
        }
        c.getSession().write(MaplePacketCreator.sendDueyMSG((byte) 0x1B));
      }
      rs.close();
      ps.close();
      rs = null;
      ps = null;
    } catch (SQLException e) {
      e.printStackTrace();
    }
    c.getSession().write(MaplePacketCreator.getCharInfo(player));
    c.getPlayer().InitiateSaveEvent();
    if (player.isGM()) {
      SkillFactory.getSkill(GM.HIDE).getEffect(1).applyTo(player);
    }
    player.sendKeymap();
    player.sendMacros();
    player.getMap().addPlayer(player);
    try {
      int buddyIds[] = player.getBuddylist().getBuddyIds();
      cserv
          .getWorldInterface()
          .loggedOn(player.getName(), player.getId(), c.getChannel(), buddyIds);
      for (CharacterIdChannelPair onlineBuddy :
          cserv.getWorldInterface().multiBuddyFind(player.getId(), buddyIds)) {
        BuddylistEntry ble = player.getBuddylist().get(onlineBuddy.getCharacterId());
        ble.setChannel(onlineBuddy.getChannel());
        player.getBuddylist().put(ble);
      }
      c.getSession().write(MaplePacketCreator.updateBuddylist(player.getBuddylist().getBuddies()));
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    /*  c.getSession().write(MaplePacketCreator.loadFamily(player));
    if (player.getFamilyId() > 0) {
        c.getSession().write(MaplePacketCreator.getFamilyInfo(player));
    }*/
    if (player.getGuildId() > 0) {
      try {
        MapleGuild playerGuild =
            cserv.getWorldInterface().getGuild(player.getGuildId(), player.getMGC());
        if (playerGuild == null) {
          player.deleteGuild(player.getGuildId());
          player.resetMGC();
          player.setGuildId(0);
        } else {
          cserv.getWorldInterface().setGuildMemberOnline(player.getMGC(), true, c.getChannel());
          c.getSession().write(MaplePacketCreator.showGuildInfo(player));
          int allianceId = player.getGuild().getAllianceId();
          if (allianceId > 0) {
            MapleAlliance newAlliance = cserv.getWorldInterface().getAlliance(allianceId);
            if (newAlliance == null) {
              newAlliance = MapleAlliance.loadAlliance(allianceId);
              if (newAlliance != null) {
                cserv.getWorldInterface().addAlliance(allianceId, newAlliance);
              } else {
                player.getGuild().setAllianceId(0);
              }
            }
            if (newAlliance != null) {
              c.getSession().write(MaplePacketCreator.getAllianceInfo(newAlliance));
              c.getSession().write(MaplePacketCreator.getGuildAlliances(newAlliance, c));
              cserv
                  .getWorldInterface()
                  .allianceMessage(
                      allianceId,
                      MaplePacketCreator.allianceMemberOnline(player, true),
                      player.getId(),
                      -1);
            }
          }
        }
      } catch (RemoteException e) {
        cserv.reconnectWorld();
      }
    }
    try {
      //  c.getPlayer().showNote();
      if (player.getParty() != null) {
        cserv
            .getWorldInterface()
            .updateParty(
                player.getParty().getId(),
                PartyOperation.LOG_ONOFF,
                new MaplePartyCharacter(player));
      }
      player.updatePartyMemberHP();
    } catch (RemoteException e) {
      cserv.reconnectWorld();
    }
    for (MapleQuestStatus status : player.getStartedQuests()) {
      if (status.hasMobKills()) {
        c.getSession().write(MaplePacketCreator.updateQuestMobKills(status));
      }
    }
    CharacterNameAndId pendingBuddyRequest = player.getBuddylist().pollPendingRequest();
    if (pendingBuddyRequest != null) {
      player
          .getBuddylist()
          .put(
              new BuddylistEntry(
                  pendingBuddyRequest.getName(), "그룹 미지정", pendingBuddyRequest.getId(), -1, false));
      c.getSession()
          .write(
              MaplePacketCreator.requestBuddylistAdd(
                  pendingBuddyRequest.getId(),
                  c.getPlayer().getId(),
                  pendingBuddyRequest.getName(),
                  0,
                  0)); // todo: make actual levels / jobids appear
    }
    c.getSession().write(MaplePacketCreator.updateBuddylist(player.getBuddylist().getBuddies()));
    //    c.getSession().write(MaplePacketCreator.updateGender(player));
    player.checkMessenger();
    //  c.getSession().write(MaplePacketCreator.enableReport());
    /*     if (!player.isGM() && !player.hasWatchedCygnusIntro() && player.getLevel() > 19 && !player.isCygnus() && player.getCygnusLinkId() == 0) {
        player.startCygnusIntro();
        player.setWatchedCygnusIntro(true);
    }*/
    // unneeded in 83+ as cygnus is created at char select

    ISkill bof =
        SkillFactory.getSkill(
            10000000 * player.getJobType() + 12); // todo: find opcode and re-enable
    player.changeSkillLevel(bof, player.getLinkedLevel() / 10, bof.getMaxLevel());
    player.checkBerserk();
    player.expirationTask();
    player.setRates(false);
  }
Example #7
0
  public static final void CreateUltimate(final LittleEndianAccessor slea, final MapleClient c) {
    if (!c.isLoggedIn()
        || c.getPlayer() == null
        || c.getPlayer().getLevel() < 120
        || c.getPlayer().getMapId() != 130000000
        || c.getPlayer().getQuestStatus(20734) != 0
        || c.getPlayer().getQuestStatus(20616) != 2
        || !GameConstants.isKOC(c.getPlayer().getJob())
        || !c.canMakeCharacter(c.getPlayer().getWorld())) {
      c.getPlayer().dropMessage(1, "You have no character slots.");
      c.getSession().write(CField.createUltimate(0));
      return;
    }
    System.out.println(slea.toString());
    final String name = slea.readMapleAsciiString();
    final int job = slea.readInt(); // job ID

    final int face = slea.readInt();
    final int hair = slea.readInt();

    final int hat = slea.readInt();
    final int top = slea.readInt();
    final int glove = slea.readInt();
    final int shoes = slea.readInt();
    final int weapon = slea.readInt();

    final byte gender = c.getPlayer().getGender();
    JobType jobType = JobType.Adventurer;
    // if (!LoginInformationProvider.getInstance().isEligibleItem(gender, 0, jobType.type, face) ||
    // !LoginInformationProvider.getInstance().isEligibleItem(gender, 1, jobType.type, hair)) {
    //    c.getPlayer().dropMessage(1, "An error occurred.");
    //    c.getSession().write(CField.createUltimate(0));
    //    return;
    // }

    jobType = JobType.UltimateAdventurer;

    MapleCharacter newchar = MapleCharacter.getDefault(c, jobType);
    newchar.setJob(job);
    newchar.setWorld((byte) c.getPlayer().getWorld());
    newchar.setFace(face);
    newchar.setHair(hair);
    newchar.setGender(gender);
    newchar.setName(name);
    newchar.setSkinColor((byte) 3); // troll
    newchar.setLevel((short) 50);
    newchar.getStat().str = (short) 4;
    newchar.getStat().dex = (short) 4;
    newchar.getStat().int_ = (short) 4;
    newchar.getStat().luk = (short) 4;
    newchar.setRemainingAp((short) 254); // 49*5 + 25 - 16
    newchar.setRemainingSp(
        job / 100 == 2 ? 128 : 122); // 2 from job advancements. 120 from leveling. (mages get +6)
    newchar.getStat().maxhp += 150; // Beginner 10 levels
    newchar.getStat().maxmp += 125;
    newchar.getStat().hp += 150; // Beginner 10 levels
    newchar.getStat().mp += 125;
    switch (job) {
      case 110:
      case 120:
      case 130:
        newchar.getStat().maxhp += 600; // Job Advancement
        newchar.getStat().maxhp += 2000; // Levelup 40 times
        newchar.getStat().maxmp += 200;
        newchar.getStat().hp += 600; // Job Advancement
        newchar.getStat().hp += 2000; // Levelup 40 times
        newchar.getStat().mp += 200;
        break;
      case 210:
      case 220:
      case 230:
        newchar.getStat().maxmp += 600;
        newchar.getStat().maxhp += 500; // Levelup 40 times
        newchar.getStat().maxmp += 2000;
        newchar.getStat().mp += 600;
        newchar.getStat().hp += 500; // Levelup 40 times
        newchar.getStat().mp += 2000;
        break;
      case 310:
      case 320:
      case 410:
      case 420:
      case 520:
        newchar.getStat().maxhp += 500;
        newchar.getStat().maxmp += 250;
        newchar.getStat().maxhp += 900; // Levelup 40 times
        newchar.getStat().maxmp += 600;
        newchar.getStat().maxhp += 500;
        newchar.getStat().mp += 250;
        newchar.getStat().hp += 900; // Levelup 40 times
        newchar.getStat().mp += 600;
        break;
      case 510:
        newchar.getStat().maxhp += 500;
        newchar.getStat().maxmp += 250;
        newchar.getStat().maxhp += 450; // Levelup 20 times
        newchar.getStat().maxmp += 300;
        newchar.getStat().maxhp += 800; // Levelup 20 times
        newchar.getStat().maxmp += 400;
        newchar.getStat().hp += 500;
        newchar.getStat().mp += 250;
        newchar.getStat().hp += 450; // Levelup 20 times
        newchar.getStat().mp += 300;
        newchar.getStat().hp += 800; // Levelup 20 times
        newchar.getStat().mp += 400;
        break;
      default:
        return;
    }
    for (int i = 2490; i < 2507; i++) {
      newchar.setQuestAdd(MapleQuest.getInstance(i), (byte) 2, null);
    }
    newchar.setQuestAdd(MapleQuest.getInstance(29947), (byte) 2, null);
    newchar.setQuestAdd(
        MapleQuest.getInstance(GameConstants.ULT_EXPLORER), (byte) 0, c.getPlayer().getName());

    final Map<Skill, SkillEntry> ss = new HashMap<>();
    ss.put(SkillFactory.getSkill(1074 + (job / 100)), new SkillEntry((byte) 5, (byte) 5, -1));
    ss.put(SkillFactory.getSkill(1195 + (job / 100)), new SkillEntry((byte) 5, (byte) 5, -1));
    ss.put(SkillFactory.getSkill(80), new SkillEntry((byte) 1, (byte) 1, -1));
    newchar.changeSkillLevel_Skip(ss, false);
    final MapleItemInformationProvider li = MapleItemInformationProvider.getInstance();

    int[] items =
        new int[] {
          1142257,
          hat,
          top,
          shoes,
          glove,
          weapon,
          hat + 1,
          top + 1,
          shoes + 1,
          glove + 1,
          weapon + 1
        }; // brilliant = fine+1
    for (byte i = 0; i < items.length; i++) {
      Item item = li.getEquipById(items[i]);
      item.setPosition((byte) (i + 1));
      newchar.getInventory(MapleInventoryType.EQUIP).addFromDB(item);
    }
    newchar
        .getInventory(MapleInventoryType.USE)
        .addItem(new Item(2000004, (byte) 0, (short) 100, (byte) 0));
    newchar
        .getInventory(MapleInventoryType.USE)
        .addItem(new Item(2000004, (byte) 0, (short) 100, (byte) 0));
    c.getPlayer().fakeRelog();
    if (MapleCharacterUtil.canCreateChar(name, c.isGm())
        && (!LoginInformationProvider.getInstance().isForbiddenName(name) || c.isGm())) {
      MapleCharacter.saveNewCharToDB(newchar, jobType, (short) 0);
      MapleQuest.getInstance(20734).forceComplete(c.getPlayer(), 1101000);
      c.getSession().write(CField.createUltimate(1));
    } else {
      c.getSession().write(CField.createUltimate(0));
    }
  }
Example #8
0
  public static void CreateChar(final LittleEndianAccessor slea, final MapleClient c) {
    if (!c.isLoggedIn()) {
      c.getSession().close();
      return;
    }
    final String name = slea.readMapleAsciiString();
    final JobType jobType =
        JobType.getByType(
            slea.readInt()); // BIGBANG: 0 = Resistance, 1 = Adventurer, 2 = Cygnus, 3 = Aran, 4 =
    // Evan, 5 = mercedes
    final short db = slea.readShort(); // whether dual blade = 1 or adventurer = 0
    final byte gender = slea.readByte(); // ??idk corresponds with the thing in addCharStats
    byte skinColor = slea.readByte(); // 01
    int hairColor = 0;
    final byte unk2 = slea.readByte(); // 08
    final boolean mercedes = (jobType == JobType.Mercedes);
    final boolean demon = (jobType == JobType.Demon);
    final boolean mihile = (jobType == JobType.Mihile);
    boolean jettPhantom =
        (jobType == LoginInformationProvider.JobType.Jett)
            || (jobType == LoginInformationProvider.JobType.Phantom)
            || (jobType == LoginInformationProvider.JobType.DualBlade);
    final int face = slea.readInt();
    final int hair = slea.readInt();
    if (!mercedes
        && !mihile
        && !demon
        && !jettPhantom) { // mercedes/demon dont need hair color since its already in the hair
      hairColor = slea.readInt();
      skinColor = (byte) slea.readInt();
    }
    final int demonMark = demon ? slea.readInt() : 0;
    final int top = (mihile) ? 0 : slea.readInt();
    final int bottom = (mihile) ? 0 : slea.readInt();
    final int shoes = (mihile) ? 0 : slea.readInt();
    final int weapon =
        jobType == LoginInformationProvider.JobType.Phantom
            ? 1362046
            : mercedes ? 1522038 : (mihile || demon) ? 0 : slea.readInt();
    int shield =
        jobType == LoginInformationProvider.JobType.Phantom
            ? 1352100
            : jobType == LoginInformationProvider.JobType.Mihile
                ? 1098000
                : mercedes ? 1352000 : demon ? slea.readInt() : 0;
    MapleCharacter newchar = MapleCharacter.getDefault(c, jobType);
    newchar.setWorld((byte) c.getWorld());
    newchar.setFace(face);
    newchar.setHair(hair + hairColor);
    newchar.setGender(gender);
    newchar.setName(name);
    newchar.setSkinColor(skinColor);
    newchar.setDemonMarking(demonMark);

    final MapleItemInformationProvider li = MapleItemInformationProvider.getInstance();
    final MapleInventory equip = newchar.getInventory(MapleInventoryType.EQUIPPED);

    Item item = li.getEquipById(top);
    item.setPosition((byte) -5);
    equip.addFromDB(item);

    if (bottom > 0) { // resistance have overall
      item = li.getEquipById(bottom);
      item.setPosition((short) (byte) (jettPhantom ? -9 : -6));
      equip.addFromDB(item);
    }

    item = li.getEquipById(shoes);
    item.setPosition((byte) -7);
    equip.addFromDB(item);

    item = li.getEquipById(weapon);
    item.setPosition((byte) -11);
    equip.addFromDB(item);

    if (shield > 0) {
      item = li.getEquipById(shield);
      item.setPosition((byte) -10);
      equip.addFromDB(item);
    }

    newchar
        .getInventory(MapleInventoryType.USE)
        .addItem(new Item(2000013, (byte) 0, (short) 100, (byte) 0));
    newchar
        .getInventory(MapleInventoryType.USE)
        .addItem(new Item(2000014, (byte) 0, (short) 100, (byte) 0));
    // blue/red pots
    switch (jobType) {
      case Resistance: // Resistance
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161001, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss = new HashMap<>();
        ss.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss, false);
        break;
      case Adventurer: // Adventurer
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161001, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss1 = new HashMap<>();
        ss1.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss1, false);
        break;
      case Cygnus: // Cygnus
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161047, (byte) 0, (short) 1, (byte) 0));
        newchar.setQuestAdd(MapleQuest.getInstance(20022), (byte) 1, "1");
        newchar.setQuestAdd(MapleQuest.getInstance(20010), (byte) 1, null); // >_>_>_> ugh
        final Map<Skill, SkillEntry> ss2 = new HashMap<>();
        ss2.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss2, false);
        break;
      case Aran: // Aran
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161048, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss3 = new HashMap<>();
        ss3.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss3, false);
        break;
      case Evan: // Evan
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161052, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss4 = new HashMap<>();
        ss4.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss4, false);
        break;
      case Mercedes: // Mercedes
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161079, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss5 = new HashMap<>();
        ss5.put(SkillFactory.getSkill(20021000), new SkillEntry((byte) 0, (byte) 0, -1));
        ss5.put(SkillFactory.getSkill(20021001), new SkillEntry((byte) 0, (byte) 0, -1));
        ss5.put(SkillFactory.getSkill(20020002), new SkillEntry((byte) 0, (byte) 0, -1));
        ss5.put(SkillFactory.getSkill(20020022), new SkillEntry((byte) 1, (byte) 1, -1));
        ss5.put(SkillFactory.getSkill(20020109), new SkillEntry((byte) 1, (byte) 1, -1));
        ss5.put(SkillFactory.getSkill(20021110), new SkillEntry((byte) 1, (byte) 1, -1));
        ss5.put(SkillFactory.getSkill(20020111), new SkillEntry((byte) 1, (byte) 1, -1));
        ss5.put(SkillFactory.getSkill(20020112), new SkillEntry((byte) 1, (byte) 1, -1));
        ss5.put(SkillFactory.getSkill(20021181), new SkillEntry((byte) -1, (byte) 0, -1));
        ss5.put(SkillFactory.getSkill(20021166), new SkillEntry((byte) -1, (byte) 0, -1));
        ss5.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss5, false);
        break;
      case Demon: // Demon
        newchar
            .getInventory(MapleInventoryType.ETC)
            .addItem(new Item(4161054, (byte) 0, (short) 1, (byte) 0));
        final Map<Skill, SkillEntry> ss6 = new HashMap<>();
        ss6.put(SkillFactory.getSkill(30011000), new SkillEntry((byte) 0, (byte) 0, -1));
        ss6.put(SkillFactory.getSkill(30011001), new SkillEntry((byte) 0, (byte) 0, -1));
        ss6.put(SkillFactory.getSkill(30010002), new SkillEntry((byte) 0, (byte) 0, -1));
        ss6.put(SkillFactory.getSkill(30010185), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30010112), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30010111), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30010110), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30010022), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30011109), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30011170), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30011169), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30011168), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30011167), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(30010166), new SkillEntry((byte) 1, (byte) 1, -1));
        ss6.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss6, false);
        break;

      case Phantom:
        newchar.setLevel((short) 10);
        newchar.setJob(2400);
        newchar.getStat().maxhp += 294; // Beginner 10 levels
        newchar.getStat().maxmp += 113;
        newchar.getStat().hp += 294; // Beginner 10 levels
        newchar.getStat().mp += 113;
        newchar.getStat().str -= 8;
        newchar.getStat().dex -= 1;
        newchar.getStat().luk += 31;
        newchar.setRemainingAp((short) 23);
        newchar.setRemainingSp(5);
        final Map<Skill, SkillEntry> ss7 = new HashMap<>();
        ss7.put(SkillFactory.getSkill(20031203), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20030204), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20031205), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20030206), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20031207), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20031208), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20031209), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(20031210), new SkillEntry((byte) 1, (byte) 1, -1));
        ss7.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss7, false);
        break;

      case Jett:
        newchar.setLevel((short) 10);
        newchar.setJob(508);
        newchar.getStat().maxhp += 294; // Beginner 10
        newchar.getStat().maxmp += 113;
        newchar.getStat().hp += 294; // Beginner 10
        newchar.getStat().mp += 113;
        newchar.getStat().str -= 8;
        newchar.getStat().dex += 15;
        newchar.setRemainingAp((short) 38);
        newchar.setRemainingSp(1);
        final Map<Skill, SkillEntry> ss8 = new HashMap<>();
        ss8.put(SkillFactory.getSkill(228), new SkillEntry((byte) 1, (byte) 1, -1));
        ss8.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        // ss8.put(SkillFactory.getSkill(80001151), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss8, false);
        break;

      case Mihile:
        final Map<Skill, SkillEntry> ss9 = new HashMap<>();
        ss9.put(SkillFactory.getSkill(80001152), new SkillEntry((byte) 1, (byte) 1, -1));
        newchar.changeSkillLevel_Skip(ss9, false);
        break;
    }

    if (MapleCharacterUtil.canCreateChar(name, c.isGm())
        && (!LoginInformationProvider.getInstance().isForbiddenName(name) || c.isGm())
        && (c.isGm() || c.canMakeCharacter(c.getWorld()))) {
      MapleCharacter.saveNewCharToDB(newchar, jobType, db);
      c.getSession().write(LoginPacket.addNewCharEntry(newchar, true));
      c.createdChar(newchar.getId());
    } else {
      c.getSession().write(LoginPacket.addNewCharEntry(newchar, false));
    }
  }
 private static boolean hasSkill(final MapleClient c, final int reqlvl) {
   return c.getPlayer()
           .getSkillLevel(
               SkillFactory.getSkill(PlayerStats.getSkillByJob(1007, c.getPlayer().getJob())))
       >= reqlvl;
 }
  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);
      }
    }
  }
Example #13
0
  public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    slea.readInt(); // whatever...
    byte slot = (byte) slea.readShort();
    byte dst = (byte) slea.readShort();
    byte ws = (byte) slea.readShort();
    boolean whiteScroll = false; // white scroll being used?
    boolean legendarySpirit = false; // legendary spirit skill
    if ((ws & 2) == 2) {
      whiteScroll = true;
    }
    MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
    IEquip toScroll = (IEquip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(dst);
    ISkill LegendarySpirit = SkillFactory.getSkill(1003);
    if (c.getPlayer().getSkillLevel(LegendarySpirit) > 0 && dst >= 0) {
      legendarySpirit = true;
      toScroll = (IEquip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(dst);
    }
    byte oldLevel = toScroll.getLevel();
    if (((IEquip) toScroll).getUpgradeSlots() < 1) {
      c.announce(MaplePacketCreator.getInventoryFull());
      return;
    }
    MapleInventory useInventory = c.getPlayer().getInventory(MapleInventoryType.USE);
    IItem scroll = useInventory.getItem(slot);
    IItem wscroll = null;
    List<Integer> scrollReqs = ii.getScrollReqs(scroll.getItemId());
    if (scrollReqs.size() > 0 && !scrollReqs.contains(toScroll.getItemId())) {
      c.announce(MaplePacketCreator.getInventoryFull());
      return;
    }
    if (whiteScroll) {
      wscroll = useInventory.findById(2340000);
      if (wscroll == null || wscroll.getItemId() != 2340000) {
        whiteScroll = false;
      }
    }
    if (scroll.getItemId() != 2049100 && !isCleanSlate(scroll.getItemId())) {
      if (!canScroll(scroll.getItemId(), toScroll.getItemId())) {
        return;
      }
    }
    if (scroll.getQuantity() < 1) {
      return;
    }
    try {
      IEquip scrolled = null;
      ScrollResult scrollSuccess = null;
      int sExpAdd = 0;
      Enchantment enchantment =
          (Enchantment) c.getPlayer().getPowerSkill(PowerSkillType.ENCHANTMENT);
      boolean isMultiScroll = enchantment.getMultiScrollChance() > Randomizer.nextFloat();
      int scrollMulti = 1 + (isMultiScroll ? enchantment.getMultiScrollAmount() : 0);
      if (scrollMulti > 1) sExpAdd += Randomizer.rand(0, 4);
      boolean removeSlot = enchantment.getNoSlotUse() > Randomizer.nextFloat();
      if (scrollMulti > scroll.getQuantity()) {
        scrollMulti = scroll.getQuantity();
      }
      int scrollCount = 0;
      while (scroll.getQuantity() > 0 && scrollMulti > 0) {
        scrollMulti--;
        scrollCount++;
        int scrollRerolls = enchantment.getRerolls();
        sExpAdd += scrollRerolls;

        float statMultiplier = 1 + enchantment.getExtraStats();
        if (statMultiplier > 1) sExpAdd++;

        scrolled =
            (IEquip)
                ii.scrollEquipWithId(
                    toScroll,
                    scroll.getItemId(),
                    whiteScroll,
                    removeSlot,
                    scrollRerolls,
                    statMultiplier,
                    c.getPlayer().isGM());

        if (scrolled != null && enchantment.getDoubleScroll() > Randomizer.nextFloat()) {
          scrolled =
              (IEquip)
                  ii.scrollEquipWithId(
                      scrolled,
                      scroll.getItemId(),
                      whiteScroll,
                      removeSlot,
                      scrollRerolls,
                      statMultiplier,
                      c.getPlayer().isGM());
        }

        scrollSuccess = IEquip.ScrollResult.FAIL; // fail
        if (scrolled == null) {
          scrollSuccess = IEquip.ScrollResult.CURSE;
        } else if (scrolled.getLevel() > oldLevel
            || (isCleanSlate(scroll.getItemId()) && scrolled.getLevel() == oldLevel + 1)) {
          scrollSuccess = IEquip.ScrollResult.SUCCESS;
        }
        useInventory.removeItem(scroll.getPosition(), (short) 1, false);
        if (whiteScroll) {
          useInventory.removeItem(wscroll.getPosition(), (short) 1, false);
          if (wscroll.getQuantity() < 1) {
            c.announce(
                MaplePacketCreator.clearInventoryItem(
                    MapleInventoryType.USE, wscroll.getPosition(), false));
          } else {
            c.announce(
                MaplePacketCreator.updateInventorySlot(MapleInventoryType.USE, (Item) wscroll));
          }
        }
        c.getPlayer()
            .getMap()
            .broadcastMessage(
                MaplePacketCreator.getScrollEffect(
                    c.getPlayer().getId(), scrollSuccess, legendarySpirit));
        if (scrollSuccess == IEquip.ScrollResult.CURSE) {
          break;
        }
      }
      if (scrollSuccess == IEquip.ScrollResult.CURSE) {
        scrollMulti = 0;
        c.announce(MaplePacketCreator.scrolledItem(scroll, toScroll, true));
        if (dst < 0) {
          c.getPlayer()
              .getInventory(MapleInventoryType.EQUIPPED)
              .removeItem(toScroll.getPosition());
        } else {
          c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeItem(toScroll.getPosition());
        }
      } else {
        c.announce(MaplePacketCreator.scrolledItem(scroll, scrolled, false));
      }
      if (dst < 0
          && (scrollSuccess == IEquip.ScrollResult.SUCCESS
              || scrollSuccess == IEquip.ScrollResult.CURSE)) {
        c.getPlayer().equipChanged();
      }
      // sExpAdd /= initMulti;
      if (scrollCount > 1)
        c.getPlayer().message("You have successfully multi-scrolled " + scrollCount + " times!");
      c.getPlayer().addPowerSkillExp(PowerSkillType.ENCHANTMENT, sExpAdd + Randomizer.nextInt(4));
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }