Beispiel #1
0
  public static void doFishing(client.MapleCharacter chr) {
    int mesoMultiplier = 1;
    int expMultiplier = 1;
    switch (chr.getWorld()) {
      case 0:
        mesoMultiplier = 40000;
        expMultiplier = 20000;
        break;
    }
    int mesoAward =
        (int) (1400.0 * Math.random() + 1201) * mesoMultiplier + (6 * chr.getLevel() / 5);
    int expAward =
        (int) ((645.0 * Math.random()) * expMultiplier + (15 * chr.getLevel() / 2) / 6)
            * chr.getFishingLevel();
    if (chr.getReborns() >= 5
        && chr.getMapId() == 970020001
        && chr.haveItem(3011000)
        && chr.getChair() == 3011000) {
      int rand = (int) (3.0 * Math.random());
      int fishingexp = (int) (7.0 * Math.random()) + 1;
      switch (rand) {
        case 0:
          chr.gainMeso(mesoAward, true, true, true);
          chr.gainFishingEXP(fishingexp);
          chr.getClient()
              .getSession()
              .write(MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1));
          chr.getMap()
              .broadcastMessage(
                  chr, MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1), false);
          break;
        case 1:
          chr.gainExp(expAward, true, true);
          chr.gainFishingEXP(fishingexp);
          chr.getClient()
              .getSession()
              .write(MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1));
          chr.getMap()
              .broadcastMessage(
                  chr, MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1), false);
          break;
        case 2:
          chr.gainFishingEXP(fishingexp * 2);
          chr.getClient()
              .getSession()
              .write(MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1));
          chr.getMap()
              .broadcastMessage(
                  chr, MaplePacketCreator.catchMonster(9500336, 2000017, (byte) 1), false);
          break;
      }

    } else {
      chr.dropMessage("Please sit on your fishing chair at the fishing lagoon to fish.");
    }
  }
Beispiel #2
0
 public static void startTrade(MapleCharacter c) {
   if (c.getTrade() == null) {
     c.setTrade(new MapleTrade((byte) 0, c));
     c.getClient()
         .getSession()
         .write(MaplePacketCreator.getTradeStart(c.getClient(), c.getTrade(), (byte) 0));
   } else {
     c.message("You are already in a trade.");
   }
 }
 public void finish(int winningTeam) {
   int chnl = leader1.getClient().getChannel();
   int chnl1 = leader2.getClient().getChannel();
   if (chnl != chnl1) throw new RuntimeException("CPQ leaders are on different channels..");
   ChannelServer cs = ChannelServer.getInstance(chnl);
   if (winningTeam == 0) {
     for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
       MapleCharacter mc;
       mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
       if (mc != null) {
         mc.setCpqRanking(getRankByCP(this.redTotalCP));
         mc.changeMap(
             cs.getMapFactory().getMap(map.getId() + 2),
             cs.getMapFactory().getMap(map.getId() + 2).getPortal(0));
         mc.setTeam(-1);
       }
     }
     for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
       MapleCharacter mc;
       mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
       if (mc != null) {
         mc.setCpqRanking(getRankByCP(this.blueTotalCP));
         mc.changeMap(
             cs.getMapFactory().getMap(map.getId() + 3),
             cs.getMapFactory().getMap(map.getId() + 3).getPortal(0));
         mc.setTeam(-1);
       }
     }
   } else if (winningTeam == 1) {
     for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
       MapleCharacter mc;
       mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
       if (mc != null) {
         mc.changeMap(
             cs.getMapFactory().getMap(map.getId() + 2),
             cs.getMapFactory().getMap(map.getId() + 2).getPortal(0));
         mc.setTeam(-1);
       }
     }
     for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
       MapleCharacter mc;
       mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
       if (mc != null) {
         mc.changeMap(
             cs.getMapFactory().getMap(map.getId() + 3),
             cs.getMapFactory().getMap(map.getId() + 3).getPortal(0));
         mc.setTeam(-1);
       }
     }
   }
   dispose();
 }
Beispiel #4
0
 public static void visitTrade(MapleCharacter c1, MapleCharacter c2) {
   if (c1.getTrade() != null
       && c1.getTrade().getPartner() == c2.getTrade()
       && c2.getTrade() != null
       && c2.getTrade().getPartner() == c1.getTrade()) {
     c2.getClient().getSession().write(MaplePacketCreator.getTradePartnerAdd(c1));
     c1.getClient()
         .getSession()
         .write(MaplePacketCreator.getTradeStart(c1.getClient(), c1.getTrade(), (byte) 1));
   } else {
     c1.message("The other player has already closed the trade.");
   }
 }
 public void broadcastToVisitors(MaplePacket packet) {
   for (MapleCharacter visitor : visitors) {
     if (visitor != null) {
       visitor.getClient().getSession().write(packet);
     }
   }
 }
Beispiel #6
0
 private void cancel() {
   for (IItem item : items) {
     MapleInventoryManipulator.addFromDrop(chr.getClient(), item, true);
   }
   if (meso > 0) {
     chr.gainMeso(meso, true, true, true);
   }
   meso = 0;
   if (items != null) {
     items.clear();
   }
   exchangeMeso = 0;
   if (exchangeItems != null) {
     exchangeItems.clear();
   }
   chr.getClient().getSession().write(MaplePacketCreator.getTradeCancel(number));
 }
Beispiel #7
0
 public void chat(String message) {
   chr.getClient().getSession().write(MaplePacketCreator.getTradeChat(chr, message, true));
   if (partner != null) {
     partner
         .getChr()
         .getClient()
         .getSession()
         .write(MaplePacketCreator.getTradeChat(chr, message, false));
   }
 }
Beispiel #8
0
 public static void inviteTrade(MapleCharacter c1, MapleCharacter c2) {
   if (c2.getTrade() == null) {
     c2.setTrade(new MapleTrade((byte) 1, c2));
     c2.getTrade().setPartner(c1.getTrade());
     c1.getTrade().setPartner(c2.getTrade());
     c2.getClient().getSession().write(MaplePacketCreator.getTradeInvite(c1));
   } else {
     c1.message("The other player is already trading with someone else.");
     cancelTrade(c1);
   }
 }
 public static boolean addRing(final MapleCharacter chr, final int Id, final int ringId) {
   MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
   MapleInventoryType type = ii.getInventoryType(Id);
   IItem nEquip = ii.getEquipById(Id, ringId);
   short newSlot = chr.getInventory(type).addItem(nEquip);
   if (newSlot == -1) {
     return false;
   }
   chr.getClient().announce(InventoryFactory.addInventorySlot(type, nEquip));
   return true;
 }
Beispiel #10
0
 public void addItem(IItem item) {
   items.add(item);
   chr.getClient().getSession().write(MaplePacketCreator.getTradeItemAdd((byte) 0, item));
   if (partner != null) {
     partner
         .getChr()
         .getClient()
         .getSession()
         .write(MaplePacketCreator.getTradeItemAdd((byte) 1, item));
   }
 }
Beispiel #11
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));
   }
 }
Beispiel #12
0
 public void copy() {
   while (type.queue.get(ch).size() > 0
       && ChannelServer.getInstance(ch).getMapleSquad(type) == null) {
     int index = 0;
     long lowest = 0;
     for (int i = 0; i < type.queue.get(ch).size(); i++) {
       if (lowest == 0 || type.queue.get(ch).get(i).right < lowest) {
         index = i;
         lowest = type.queue.get(ch).get(i).right;
       }
     }
     final String nextPlayerId = type.queue.get(ch).remove(index).left;
     final int theirCh = World.Find.findChannel(nextPlayerId);
     if (theirCh > 0) {
       final MapleCharacter lead =
           ChannelServer.getInstance(theirCh).getPlayerStorage().getCharacterByName(nextPlayerId);
       if (lead != null && lead.getMapId() == beginMapId && lead.getClient().getChannel() == ch) {
         final MapleSquad squad = new MapleSquad(ch, type.name(), lead, expiration, toSay);
         if (ChannelServer.getInstance(ch).addMapleSquad(squad, type.name())) {
           getBeginMap().broadcastMessage(CField.getClock(expiration / 1000));
           getBeginMap().broadcastMessage(CWvsContext.serverNotice(6, nextPlayerId + toSay));
           type.queuedPlayers.get(ch).add(new Pair<String, String>(nextPlayerId, "Success"));
         } else {
           squad.clear();
           type.queuedPlayers.get(ch).add(new Pair<String, String>(nextPlayerId, "Skipped"));
         }
         break;
       } else {
         if (lead != null) {
           lead.dropMessage(
               6,
               "Your squad has been skipped due to you not being in the right channel and map.");
         }
         getBeginMap()
             .broadcastMessage(
                 CWvsContext.serverNotice(
                     6,
                     nextPlayerId
                         + "'s squad has been skipped due to the player not being in the right channel and map."));
         type.queuedPlayers.get(ch).add(new Pair<String, String>(nextPlayerId, "Not in map"));
       }
     } else {
       getBeginMap()
           .broadcastMessage(
               CWvsContext.serverNotice(
                   6,
                   nextPlayerId
                       + "'s squad has been skipped due to the player not being online."));
       type.queuedPlayers.get(ch).add(new Pair<String, String>(nextPlayerId, "Not online"));
     }
   }
 }
Beispiel #13
0
 private void complete2() {
   items.clear();
   meso = 0;
   for (IItem item : exchangeItems) {
     if ((item.getFlag() & InventoryConstants.KARMA) == InventoryConstants.KARMA) {
       item.setFlag(
           (byte)
               (item.getFlag()
                   ^ InventoryConstants
                       .KARMA)); // items with scissors of karma used on them are reset once traded
     }
     MapleInventoryManipulator.addFromDrop(chr.getClient(), item, true);
   }
   if (exchangeMeso > 0) {
     int overflow = chr.updateMesosGetOverflow(exchangeMeso - getFee(exchangeMeso));
     partner.chr.gainMeso(overflow, true);
   }
   exchangeMeso = 0;
   if (exchangeItems != null) {
     exchangeItems.clear();
   }
   chr.getClient().getSession().write(MaplePacketCreator.getTradeCompletion(number));
 }
Beispiel #14
0
  public HiredMerchant(final MapleCharacter owner, int itemId, String desc) {
    this.setPosition(owner.getPosition());
    this.start = System.currentTimeMillis();
    this.ownerId = owner.getId();
    this.channel = owner.getClient().getChannel();
    this.world = owner.getWorld();
    this.itemId = itemId;
    this.ownerName = owner.getName();
    this.description = desc;
    this.map = owner.getMap();
    this.schedule =
        TimerManager.getInstance()
            .schedule(
                new Runnable() {

                  @Override
                  public void run() {
                    HiredMerchant.this.closeShop(owner.getClient(), true);
                  }
                },
                1000 * 60 * 60 * 24);
  }
Beispiel #15
0
 public void setMeso(int meso) {
   if (locked) {
     throw new RuntimeException("Trade is locked.");
   }
   if (meso < 0) {
     System.out.println("[h4x] " + chr.getName() + " Trying to trade < 0 mesos");
     return;
   }
   if (chr.getMeso() >= meso) {
     chr.gainMeso(-meso, false, true, false);
     this.meso += meso;
     chr.getClient().getSession().write(MaplePacketCreator.getTradeMesoSet((byte) 0, this.meso));
     if (partner != null) {
       partner
           .getChr()
           .getClient()
           .getSession()
           .write(MaplePacketCreator.getTradeMesoSet((byte) 1, this.meso));
     }
   } else {
   }
 }
Beispiel #16
0
 public static void completeTrade(MapleCharacter c) {
   c.getTrade().lock();
   MapleTrade local = c.getTrade();
   MapleTrade partner = local.getPartner();
   if (partner.isLocked()) {
     local.complete1();
     partner.complete1();
     if (!local.fitsInInventory() || !partner.fitsInInventory()) {
       cancelTrade(c);
       c.message("There is not enough inventory space to complete the trade.");
       partner.getChr().message("There is not enough inventory space to complete the trade.");
       return;
     }
     if (local.getChr().getLevel() < 15) {
       if (local.getChr().getMesosTraded() + local.exchangeMeso > 1000000) {
         cancelTrade(c);
         local.getChr().getClient().getSession().write(MaplePacketCreator.sendMesoLimit());
         return;
       } else {
         local.getChr().addMesosTraded(local.exchangeMeso);
       }
     } else if (c.getTrade().getChr().getLevel() < 15) {
       if (c.getMesosTraded() + c.getTrade().exchangeMeso > 1000000) {
         cancelTrade(c);
         c.getClient().getSession().write(MaplePacketCreator.sendMesoLimit());
         return;
       } else {
         c.addMesosTraded(local.exchangeMeso);
       }
     }
     local.complete2();
     partner.complete2();
     partner.getChr().setTrade(null);
     c.setTrade(null);
   }
 }
 public void complete() {
   int cp1 = this.redTotalCP;
   int cp2 = this.blueTotalCP;
   if (cp1 == cp2) {
     return;
   }
   boolean redWin = cp1 > cp2;
   int chnl = leader1.getClient().getChannel();
   int chnl1 = leader2.getClient().getChannel();
   if (chnl != chnl1) throw new RuntimeException("CPQ leaders are on different channels..");
   ChannelServer cs = ChannelServer.getInstance(chnl);
   map.killAllMonsters(false);
   for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
     MapleCharacter mc;
     mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
     if (mc != null) {
       if (redWin) {
         mc.getClient().getSession().write(MaplePacketCreator.showEffect("quest/carnival/win"));
         mc.getClient().getSession().write(MaplePacketCreator.playSound("MobCarnival/Win"));
       } else {
         mc.getClient().getSession().write(MaplePacketCreator.showEffect("quest/carnival/lose"));
         mc.getClient().getSession().write(MaplePacketCreator.playSound("MobCarnival/Lose"));
       }
     }
   }
   for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) {
     MapleCharacter mc;
     mc = cs.getPlayerStorage().getCharacterByName(mpc.getName());
     if (mc != null) {
       if (!redWin) {
         mc.getClient().getSession().write(MaplePacketCreator.showEffect("quest/carnival/win"));
         mc.getClient().getSession().write(MaplePacketCreator.playSound("MobCarnival/Win"));
       } else {
         mc.getClient().getSession().write(MaplePacketCreator.showEffect("quest/carnival/lose"));
         mc.getClient().getSession().write(MaplePacketCreator.playSound("MobCarnival/Lose"));
       }
     }
   }
 }
 public static boolean handlePortal(String name, MapleCharacter c) {
   if (name.equals(FourthJobQuests.RUSH.getValue())) {
     if (!(c.getParty().getLeader().getId() == c.getId()) && !checkRush(c)) {
       c.dropMessage("You step into the portal, but it swiftly kicks you out.");
       c.getClient().announce(MaplePacketCreator.enableActions());
     }
     if (!(c.getParty().getLeader().getId() == c.getId()) && checkRush(c)) {
       c.dropMessage("You're not the party leader.");
       c.getClient().announce(MaplePacketCreator.enableActions());
       return true;
     }
     if (!checkRush(c)) {
       c.dropMessage("Someone in your party is not a 4th Job warrior.");
       c.getClient().announce(MaplePacketCreator.enableActions());
       return true;
     }
     c.getClient()
         .getChannelServer()
         .getEventSM()
         .getEventManager("4jrush")
         .startInstance(c.getParty(), c.getMap());
     return true;
   } else if (name.equals(FourthJobQuests.BERSERK.getValue())) {
     if (!c.haveItem(4031475)) {
       c.dropMessage("The portal to the Forgotten Shrine is locked");
       c.getClient().announce(MaplePacketCreator.enableActions());
       return true;
     }
     c.getClient()
         .getChannelServer()
         .getEventSM()
         .getEventManager("4jberserk")
         .startInstance(c.getParty(), c.getMap());
     return true;
   }
   return false;
 }
Beispiel #19
0
 public static final void HandleAlliance(
     final LittleEndianAccessor slea, final MapleClient c, boolean denied) {
   if (c.getPlayer().getGuildId() <= 0) {
     c.getSession().write(CWvsContext.enableActions());
     return;
   }
   final MapleGuild gs = World.Guild.getGuild(c.getPlayer().getGuildId());
   if (gs == null) {
     c.getSession().write(CWvsContext.enableActions());
     return;
   }
   // System.out.println("Unhandled GuildAlliance \n" + slea.toString());
   byte op = slea.readByte();
   if (c.getPlayer().getGuildRank() != 1 && op != 1) { // only updating doesn't need guild leader
     return;
   }
   if (op == 22) {
     denied = true;
   }
   int leaderid = 0;
   if (gs.getAllianceId() > 0) {
     leaderid = World.Alliance.getAllianceLeader(gs.getAllianceId());
   }
   // accept invite, and deny invite don't need allianceid.
   if (op != 4 && !denied) {
     if (gs.getAllianceId() <= 0 || leaderid <= 0) {
       return;
     }
   } else if (leaderid > 0
       || gs.getAllianceId() > 0) { // infact, if they have allianceid it's suspicious
     return;
   }
   if (denied) {
     DenyInvite(c, gs);
     return;
   }
   MapleCharacter chr;
   int inviteid;
   switch (op) {
     case 1: // load... must be in world op
       for (byte[] pack : World.Alliance.getAllianceInfo(gs.getAllianceId(), false)) {
         if (pack != null) {
           c.getSession().write(pack);
         }
       }
       break;
     case 3: // invite
       final int newGuild = World.Guild.getGuildLeader(slea.readMapleAsciiString());
       if (newGuild > 0
           && c.getPlayer().getAllianceRank() == 1
           && leaderid == c.getPlayer().getId()) {
         chr = c.getChannelServer().getPlayerStorage().getCharacterById(newGuild);
         if (chr != null && chr.getGuildId() > 0 && World.Alliance.canInvite(gs.getAllianceId())) {
           chr.getClient()
               .getSession()
               .write(
                   AlliancePacket.sendAllianceInvite(
                       World.Alliance.getAlliance(gs.getAllianceId()).getName(), c.getPlayer()));
           World.Guild.setInvitedId(chr.getGuildId(), gs.getAllianceId());
         } else {
           c.getPlayer()
               .dropMessage(1, "Make sure the leader of the guild is online and in your channel.");
         }
       } else {
         c.getPlayer()
             .dropMessage(
                 1,
                 "That Guild was not found. Please enter the correct Guild Name. (Not the player name)");
       }
       break;
     case 4: // accept invite... guildid that invited(int, a/b check) -> guildname that was
             // invited? but we dont care about that
       inviteid = World.Guild.getInvitedId(c.getPlayer().getGuildId());
       if (inviteid > 0) {
         if (!World.Alliance.addGuildToAlliance(inviteid, c.getPlayer().getGuildId())) {
           c.getPlayer().dropMessage(5, "An error occured when adding guild.");
         }
         World.Guild.setInvitedId(c.getPlayer().getGuildId(), 0);
       }
       break;
     case 2: // leave; nothing
     case 6: // expel, guildid(int) -> allianceid(don't care, a/b check)
       final int gid;
       if (op == 6 && slea.available() >= 4) {
         gid = slea.readInt();
         if (slea.available() >= 4 && gs.getAllianceId() != slea.readInt()) {
           break;
         }
       } else {
         gid = c.getPlayer().getGuildId();
       }
       if (c.getPlayer().getAllianceRank() <= 2
           && (c.getPlayer().getAllianceRank() == 1 || c.getPlayer().getGuildId() == gid)) {
         if (!World.Alliance.removeGuildFromAlliance(
             gs.getAllianceId(), gid, c.getPlayer().getGuildId() != gid)) {
           c.getPlayer().dropMessage(5, "An error occured when removing guild.");
         }
       }
       break;
     case 7: // change leader
       if (c.getPlayer().getAllianceRank() == 1 && leaderid == c.getPlayer().getId()) {
         if (!World.Alliance.changeAllianceLeader(gs.getAllianceId(), slea.readInt())) {
           c.getPlayer().dropMessage(5, "An error occured when changing leader.");
         }
       }
       break;
     case 8: // title update
       if (c.getPlayer().getAllianceRank() == 1 && leaderid == c.getPlayer().getId()) {
         String[] ranks = new String[5];
         for (int i = 0; i < 5; i++) {
           ranks[i] = slea.readMapleAsciiString();
         }
         World.Alliance.updateAllianceRanks(gs.getAllianceId(), ranks);
       }
       break;
     case 9:
       if (c.getPlayer().getAllianceRank() <= 2) {
         if (!World.Alliance.changeAllianceRank(
             gs.getAllianceId(), slea.readInt(), slea.readByte())) {
           c.getPlayer().dropMessage(5, "An error occured when changing rank.");
         }
       }
       break;
     case 10: // notice update
       if (c.getPlayer().getAllianceRank() <= 2) {
         final String notice = slea.readMapleAsciiString();
         if (notice.length() > 100) {
           break;
         }
         World.Alliance.updateAllianceNotice(gs.getAllianceId(), notice);
       }
       break;
     default:
       System.out.println("Unhandled GuildAlliance op: " + op + ", \n" + slea.toString());
       break;
   }
   // c.getSession().write(CWvsContext.enableActions());
 }
  /**
   * 角色快照数据
   *
   * @param chr
   */
  public CharacterTransfer(MapleCharacter chr) {
    this.characterid = chr.getId();
    this.accountid = chr.getAccountID();
    this.accountname = chr.getClient().getAccountName();
    this.channel = (byte) chr.getClient().getChannel();
    this.ACash = chr.getCSPoints(1);
    this.MaplePoints = chr.getCSPoints(2);
    this.vpoints = chr.getVPoints();
    this.name = chr.getName();
    this.fame = chr.getFame();
    this.love = chr.getLove();
    this.gender = chr.getClient().getGender();
    this.level = chr.getLevel();
    this.str = chr.getStat().getStr();
    this.dex = chr.getStat().getDex();
    this.int_ = chr.getStat().getInt();
    this.luk = chr.getStat().getLuk();
    this.hp = chr.getStat().getHp();
    this.mp = chr.getStat().getMp();
    this.maxhp = chr.getStat().getMaxHp();
    this.maxmp = chr.getStat().getMaxMp();
    this.exp = chr.getExp();
    this.hpApUsed = chr.getHpApUsed();
    this.remainingAp = chr.getRemainingAp();
    this.remainingSp = chr.getRemainingSp();
    this.meso = chr.getMeso();
    this.pvpExp = chr.getTotalBattleExp();
    this.pvpPoints = chr.getBattlePoints();
    this.skinColor = chr.getSkinColor();
    this.job = chr.getJob();
    this.hair = chr.getHair();
    this.face = chr.getFace();
    this.mapid = chr.getMapId();
    this.initialSpawnPoint = chr.getInitialSpawnpoint();
    this.marriageId = chr.getMarriageId();
    this.world = chr.getWorld();
    this.guildid = chr.getGuildId();
    this.guildrank = chr.getGuildRank();
    this.guildContribution = chr.getGuildContribution();
    this.alliancerank = chr.getAllianceRank();
    this.gmLevel = (byte) chr.getGMLevel();
    this.points = chr.getPoints();
    this.fairyExp = chr.getFairyExp();
    this.petStore = chr.getPetStores();
    this.subcategory = chr.getSubcategory();
    this.imps = chr.getImps();
    this.fatigue = chr.getFatigue();
    this.currentrep = chr.getCurrentRep();
    this.totalrep = chr.getTotalRep();
    this.totalWins = chr.getTotalWins();
    this.totalLosses = chr.getTotalLosses();
    this.gachexp = chr.getGachExp();
    this.boxed = chr.getBoxed();
    this.familiars = chr.getFamiliars();
    this.tempIP = chr.getClient().getTempIP();
    this.decorate = chr.getDecorate();
    this.dollars = chr.getDollars();
    this.shareLots = chr.getShareLots();
    this.apstorage = chr.getAPS();
    this.cardStack = chr.getCardStack();
    this.morphCount = chr.getMorphCount();
    this.powerCount = chr.getPowerCount();
    this.playerPoints = chr.getPlayerPoints();
    this.playerEnergy = chr.getPlayerEnergy();
    this.runningDark = chr.getDarkType();
    this.runningDarkSlot = chr.getDarkTotal();
    this.runningLight = chr.getLightType();
    this.runningLightSlot = chr.getLightTotal();

    boolean uneq = false;
    MaplePet pet = chr.getSpawnPet();
    if (this.petStore == 0) {
      this.petStore = -1;
    }
    if (pet != null) {
      uneq = true;
      this.petStore = (byte) Math.max(this.petStore, pet.getInventoryPosition());
    }
    if (uneq) {
      chr.unequipAllSpawnPets();
    }
    if (chr.getSidekick() != null) {
      this.sidekick = chr.getSidekick().getId();
    } else {
      this.sidekick = 0;
    }
    for (BuddylistEntry qs : chr.getBuddylist().getBuddies()) {
      this.buddies.put(
          new CharacterNameAndId(qs.getCharacterId(), qs.getName(), qs.getGroup()), qs.isVisible());
    }
    this.buddysize = chr.getBuddyCapacity();

    this.partyid = (chr.getParty() == null ? -1 : chr.getParty().getId());

    if (chr.getMessenger() != null) {
      this.messengerid = chr.getMessenger().getId();
    } else {
      this.messengerid = 0;
    }
    this.finishedAchievements = chr.getFinishedAchievements();
    this.KeyValue = chr.getKeyValue_Map();
    this.InfoQuest = chr.getInfoQuest_Map();
    for (Map.Entry qs : chr.getQuest_Map().entrySet()) {
      this.Quest.put(((MapleQuest) qs.getKey()).getId(), qs.getValue());
    }
    this.inventorys = chr.getInventorys();
    for (Entry<Skill, SkillEntry> qs : chr.getSkills().entrySet()) {
      this.Skills.put(((Skill) qs.getKey()).getId(), qs.getValue());
    }
    this.BlessOfFairy = chr.getBlessOfFairyOrigin();
    this.BlessOfEmpress = chr.getBlessOfEmpressOrigin();
    this.chalkboard = chr.getChalkboard();
    this.keymap = chr.getKeyLayout().Layout();
    this.quickslot = chr.getQuickSlot().Layout();
    this.savedlocation = chr.getSavedLocations();
    this.wishlist = chr.getWishlist();
    this.regrocks = chr.getRegRocks();
    this.famedcharacters = chr.getFamedCharacters();
    this.lastfametime = chr.getLastFameTime();
    this.storage = chr.getStorage();
    this.cs = chr.getCashInventory();
    MapleMount mount = chr.getMount();
    this.mount_itemid = mount.getItemId();
    this.mount_Fatigue = mount.getFatigue();
    this.mount_level = mount.getLevel();
    this.mount_exp = mount.getExp();
    this.battlers = chr.getBattlers();
    this.lastLoveTime = chr.getLastLoveTime();
    this.loveCharacters = chr.getLoveCharacters();
    this.TranferTime = System.currentTimeMillis();
  }
  @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);
  }
 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);
   }
 }
  /**
   * 可以创建定时技能
   *
   * @param chr
   * @param numTimes
   * @param hurt
   * @param now
   */
  public static void handleCooldowns(MapleCharacter chr, int numTimes, boolean hurt, long now) {
    if (chr == null) {
      return;
    }
    if (chr.getCooldownSize() > 0) {
      for (MapleCoolDownValueHolder m : chr.getCooldowns()) {
        if (m.startTime + m.length < now) {
          int skillId = m.skillId;
          chr.removeCooldown(skillId);
          chr.getClient().getSession().write(MaplePacketCreator.skillCooldown(skillId, 0));
        }
      }
    }

    if (chr.isAlive()) {
      if (((chr.getJob() == 131) || (chr.getJob() == 132)) && (chr.canBlood(now))) {
        chr.doDragonBlood();
      }

      if (chr.canRecover(now)) {
        chr.doRecovery();
      }
      if (chr.canHPRecover(now)) {
        chr.addHP((int) chr.getStat().getHealHP());
      }
      if (chr.canMPRecover(now)) {
        chr.addMP((int) chr.getStat().getHealMP());
        if ((chr.getJob() == 3111) || (chr.getJob() == 3112)) {
          chr.addDemonMp((int) chr.getStat().getHealMP());
        }
      }

      if (chr.canFairy(now)) {
        chr.doFairy();
      }
      if (chr.canFish(now)) {
        chr.doFish(now);
      }
      if (chr.canDOT(now)) {
        chr.doDOT();
      }
      if (chr.canExpiration(now)) {
        chr.expirationTask();
      }
    }

    if (chr.getDiseaseSize() > 0) {
      for (MapleDiseaseValueHolder m : chr.getAllDiseases()) {
        if ((m != null) && (m.startTime + m.length < now)) {
          chr.dispelDebuff(m.disease);
        }
      }
    }

    if ((numTimes % 7 == 0) && (chr.getMount() != null) && (chr.getMount().canTire(now))) {
      chr.getMount().increaseFatigue();
    }
    if (numTimes % 13 == 0) {
      chr.doFamiliarSchedule(now);
      for (MaplePet pet : chr.getSummonedPets()) {
        if ((pet.getPetItemId() == 5000054) && (pet.getSecondsLeft() > 0)) {
          pet.setSecondsLeft(pet.getSecondsLeft() - 1);
          if (pet.getSecondsLeft() <= 0) {
            chr.unequipSpawnPet(pet, true, true);
            return;
          }
        }
        int newFullness = pet.getFullness() - PetDataFactory.getHunger(pet.getPetItemId());
        if (newFullness <= 5) {
          pet.setFullness(15);
          chr.unequipSpawnPet(pet, true, true);
        } else {
          pet.setFullness(newFullness);
          chr.getClient()
              .getSession()
              .write(
                  PetPacket.updatePet(
                      pet,
                      chr.getInventory(MapleInventoryType.CASH).getItem(pet.getInventoryPosition()),
                      false));
        }
      }
    }
    if ((hurt) && (chr.isAlive())) {
      if (chr.getInventory(MapleInventoryType.EQUIPPED).findById(chr.getMap().getHPDecProtect())
          == null) {
        if ((chr.getMapId() == 749040100)
            && (chr.getInventory(MapleInventoryType.CASH).findById(5451000) == null)) {
          chr.addHP(-chr.getMap().getHPDec());
        } else if (chr.getMapId() != 749040100) {
          chr.addHP(-(chr.getMap().getHPDec()));
        }
      }
    }
  }
  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);
        }
      }
    }
  }
Beispiel #25
0
  private static void monsterBomb(
      MapleCharacter player,
      MapleCharacter attackedPlayers,
      MapleMap map,
      AbstractDealDamageHandler.AttackInfo attack) {
    // level balances
    if (attackedPlayers.getLevel() > player.getLevel() + 25) {
      pvpDamage *= 1.35;
    } else if (attackedPlayers.getLevel() < player.getLevel() - 25) {
      pvpDamage /= 1.35;
    } else if (attackedPlayers.getLevel() > player.getLevel() + 100) {
      pvpDamage *= 1.50;
    } else if (attackedPlayers.getLevel() < player.getLevel() - 100) {
      pvpDamage /= 1.50;
    }
    // class balances
    if (player.getJob().equals(MapleJob.MAGICIAN)) {
      pvpDamage *= 1.20;
    }

    // buff modifiers
    Integer mguard = attackedPlayers.getBuffedValue(MapleBuffStat.MAGIC_GUARD);
    Integer mesoguard = attackedPlayers.getBuffedValue(MapleBuffStat.MESOGUARD);
    if (mguard != null) {
      int mploss = (int) (pvpDamage / .5);
      pvpDamage *= .70;
      if (mploss > attackedPlayers.getMp()) {
        pvpDamage /= .70;
        attackedPlayers.cancelBuffStats(MapleBuffStat.MAGIC_GUARD);
      } else {
        attackedPlayers.setMp(attackedPlayers.getMp() - mploss);
        attackedPlayers.updateSingleStat(MapleStat.MP, attackedPlayers.getMp());
      }
    } else if (mesoguard != null) {
      int mesoloss = (int) (pvpDamage * .75);
      pvpDamage *= .75;
      if (mesoloss > attackedPlayers.getMeso()) {
        pvpDamage /= .75;
        attackedPlayers.cancelBuffStats(MapleBuffStat.MESOGUARD);
      } else {
        attackedPlayers.gainMeso(-mesoloss, false);
      }
    }

    // set up us teh bonmb
    // training thingy = 9409000
    MapleMonster pvpMob = MapleLifeFactory.getMonster(9400711);
    map.spawnMonsterOnGroundBelow(pvpMob, attackedPlayers.getPosition());
    for (int attacks = 0; attacks < attack.numDamage; attacks++) {
      map.broadcastMessage(
          MaplePacketCreator.damagePlayer(
              attack.numDamage, pvpMob.getId(), attackedPlayers.getId(), pvpDamage));
      attackedPlayers.addHP(-pvpDamage);
    }
    int attackedDamage = pvpDamage * attack.numDamage;
    attackedPlayers
        .getClient()
        .getSession()
        .write(
            MaplePacketCreator.serverNotice(
                5, player.getName() + " has hit you for " + attackedDamage + " damage!"));
    map.killMonster(pvpMob, player, false);

    // rewards
    if (attackedPlayers.getHp() <= 0 && !attackedPlayers.isAlive()) {
      int expReward = attackedPlayers.getLevel() * 100;
      if (player.getPvpKills() * .25 >= player.getPvpDeaths()) {
        expReward *= 20;
      }
      player.gainExp(expReward, true, false);
      player.gainPvpKill();
      player
          .getClient()
          .getSession()
          .write(
              MaplePacketCreator.serverNotice(
                  6,
                  "You've killed " + attackedPlayers.getName() + "!! You've gained a pvp kill!"));
      attackedPlayers.gainPvpDeath();
      attackedPlayers
          .getClient()
          .getSession()
          .write(MaplePacketCreator.serverNotice(6, player.getName() + " has killed you!"));
      attackedPlayers.setHp(0);
      attackedPlayers.updateSingleStat(MapleStat.HP, 0);
    }
  }
  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);
      }
    }
  }