public void run() {
                changeMap(map, portal);
            }
        }, 5 * 1000);
    }

    public int getPQLog(String pqid) {
        Connection con1 = DatabaseConnection.getConnection();
        try {
            int ret_count = 0;
            PreparedStatement ps;
            ps = con1.prepareStatement("SELECT COUNT(*) FROM pqlog WHERE charid = ? and pqid = ? and lastattempt >= subtime(current_timestamp, '1 0:0:0.0')");
            ps.setInt(1, id);
            ps.setString(2, pqid);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                ret_count = rs.getInt(1);
            } else {
                ret_count = -1;
            }
            rs.close();
            ps.close();
            return ret_count;
        } catch (Exception Ex) {
            return -1;
        }
    }

//    public int getGiftLog(String pqid) {
//        Connection con1 = DatabaseConnection.getConnection();
//        try {
//            int ret_count = 0;
//            PreparedStatement ps;
//            ps = con1.prepareStatement("select count(*) from pqlog where accountid = ? and pqid = ? and lastattempt >= subtime(current_timestamp, '1 0:0:0.0')");
//            ps.setInt(1, accountid);
//            ps.setString(2, pqid);
//            ResultSet rs = ps.executeQuery();
//            if (rs.next()) 
//                ret_count = rs.getInt(1);
//            else
//                ret_count = -1;
//            rs.close();
//            ps.close();
//            return ret_count;
//        } catch (Exception Ex) {
//            return -1;
//        }
//    }
    //setPQLog module
    public void setPQLog(String pqid) {
        Connection con1 = DatabaseConnection.getConnection();
        try {
            PreparedStatement ps;
            ps = con1.prepareStatement("INSERT INTO pqlog (accid, charid, pqid) values (?,?,?)");
            ps.setInt(1, accountid);
            ps.setInt(2, id);
            ps.setString(3, pqid);
            ps.executeUpdate();
            ps.close();
        } catch (Exception Ex) {
        }
    }

    public void changeSkillLevel(Skill skill, byte newLevel, byte newMasterlevel) {
        changeSkillLevel_Skip(skill, newLevel, newMasterlevel);
    }

    public void setKeyValue(String key, String values) {
        if (CustomValues.containsKey(key)) {
            CustomValues.remove(key);
        }
        CustomValues.put(key, values);
        keyvalue_changed = true;
    }

    public String getKeyValue(String key) {
        if (CustomValues.containsKey(key)) {
            return CustomValues.get(key);
        }
        return null;
    }

    public void setChatType(short chattype) {
        this.chattype = chattype;
    }

    public short getChatType() {
        return chattype;
    }

    public void gainItem(int code, int amount) {
        MapleInventoryManipulator.addById(client, code, (short) amount, null);
    }

    public final int[] getFriendShipPoints() {
        return friendshippoints;
    }

    public final void setFriendShipPoints(int joejoe, int hermoninny, int littledragon, int ika) {
        this.friendshippoints[0] = joejoe;
        this.friendshippoints[1] = hermoninny;
        this.friendshippoints[2] = littledragon;
        this.friendshippoints[3] = ika;
    }

    public final int getFriendShipToAdd() {
        return friendshiptoadd;
    }

    public final void setFriendShipToAdd(int points) {
        this.friendshiptoadd = points;
    }

    public final void addFriendShipToAdd(int points) {
        this.friendshiptoadd += points;
    }

    public void makeNewAzwanShop() {
        /*
         * Azwan Etc Scrolls 60% - 30 conqueror coins
         * Azwan Weapon Scrolls 60% - 50 conqueror coins
         * 9 Conqueror's Coin - 1 emperor coin
         * Circulator - rank * 1 emperor coins
         * Azwan Scrolls 50% - 3 emperor coins
         * Azwan Scrolls 40% - 5 emperor coins
         * Azwan Scrolls 30% - 7 emperor coins
         * Azwan Scrolls 20% - 10 emperor coins
         * Emperor Armor Recipes - 70 emperor coins
         * Emperor Accessory & Weapon Recipes - 75 emperor coins
         * Emperor Weapon - 300 emperor coins
         * Emperor Armor - 250 emperor coins
         * Duke Accessory - 50 emperor coins
         * Duke Accessory - 50 emperor coins
         * 10 Sunrise Dew - 3 conqueror coins
         * 10 Simset Dew - 4 conqueror coins
         * 10 Reindeer Milk - 2 conqueror coins
         * 100% Scrolls - 3 conqueror coins
         */
        azwanShopList = new MapleShop(100000000 + getId(), 2182002);
        int itemid = GameConstants.getAzwanRecipes()[(int) Math.floor(Math.random() * GameConstants.getAzwanRecipes().length)];
        azwanShopList.addItem(new MapleShopItem((short) 1, (short) 1, itemid, 0, (short) 0, 4310038, 75, (byte) 0, 0, 0, 0, false));
        itemid = GameConstants.getAzwanScrolls()[(int) Math.floor(Math.random() * GameConstants.getAzwanScrolls().length)];
        azwanShopList.addItem(new MapleShopItem((short) 1, (short) 1, itemid, 0, (short) 0, 4310036, 15, (byte) 0, 0, 0, 0, false));
        itemid = (Integer) GameConstants.getUseItems()[(int) Math.floor(Math.random() * GameConstants.getUseItems().length)].getLeft();
        int price = (Integer) GameConstants.getUseItems()[(int) Math.floor(Math.random() * GameConstants.getUseItems().length)].getRight();
        azwanShopList.addItem(new MapleShopItem((short) 1, (short) 1, itemid, price, (short) 0, 0, 0, (byte) 0, 0, 0, 0, false));
        itemid = GameConstants.getCirculators()[(int) Math.floor(Math.random() * GameConstants.getCirculators().length)];
        price = InnerAbillity.getInstance().getCirculatorRank(itemid);
        if (price > 10) {
            price = 10;
        }
        azwanShopList.addItem(new MapleShopItem((short) 1, (short) 1, itemid, 0, (short) 0, 4310038, price, (byte) 0, 0, 0, 0, false));
        client.getSession().write(CField.getWhisper("Jean Pierre", client.getChannel(), "Psst! I got some new items in stock! Come take a look! Oh, but if your Honor Level increased, why not wait until you get a Circulator?"));
    }

    public MapleShop getAzwanShop() {
        return azwanShopList;
    }

    public void openAzwanShop() {
        if (azwanShopList == null) {
            MapleShopFactory.getInstance().getShop(2182002).sendShop(client);
        } else {
            getAzwanShop().sendShop(client);
        }
    }

    public void sendWelcome() {
        getClient().getSession().write(CField.startMapEffect("Welcome to " + getClient().getChannelServer().getServerName() + "!", 5122000, true));
        dropMessage(1, "Welcome to " + getClient().getChannelServer().getServerName() + ", " + getName() + " ! \r\nUse @npc to collect your Item Of Appreciation once you're level 10! \r\nUse @help for commands. \r\nGood luck and have fun!");
        dropMessage(5, "Your EXP Rate will be set to 1x until you finish the tutorial.");
        dropMessage(5, "Use @npc to collect your Item Of Appreciation once you're level 10! Use @help for commands. Good luck and have fun!");
        dropMessage(1, "Use @help for additional commands.");
    }

    private static void addMedalString(final MapleCharacter c, final StringBuilder sb) {
        final Item medal = c.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -46);
        if (medal != null) { // Medal
            sb.append("<");
            if (medal.getItemId() == 1142257 && GameConstants.isAdventurer(c.getJob())) {
                MapleQuestStatus stat = c.getQuestNoAdd(MapleQuest.getInstance(GameConstants.ULT_EXPLORER));
                if (stat != null && stat.getCustomData() != null) {
                    sb.append(stat.getCustomData());
                    sb.append("'s Successor");
                } else {
                    sb.append(MapleItemInformationProvider.getInstance().getName(medal.getItemId()));
                }
            } else {
                sb.append(MapleItemInformationProvider.getInstance().getName(medal.getItemId()));
            }
            sb.append("> ");
        }
    }

    public void updateReward() {
        List<MapleReward> rewards = new LinkedList();
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("SELECT * FROM rewards WHERE `cid`=?")) {
                ps.setInt(1, id);
                try (ResultSet rs = ps.executeQuery()) {
                    //rewards.last();
                    //int size = rewards.getRow();
                    //rewards.first();
                    //client.getSession().write(Reward.updateReward(rewards.getInt("id"), (byte) 9, rewards, size, 9));
                    while (rs.next()) {
                        rewards.add(new MapleReward(
                                rs.getInt("id"),
                                rs.getLong("start"),
                                rs.getLong("end"),
                                rs.getInt("type"),
                                rs.getInt("itemId"),
                                rs.getInt("mp"),
                                rs.getInt("meso"),
                                rs.getInt("exp"),
                                rs.getString("desc")));
                    }
                }
            }
        } catch (SQLException e) {
            System.err.println("Unable to update rewards: " + e);
        }
        //client.getSession().write(Reward.updateReward(0, (byte) 9, rewards, 9));
    }

    public MapleReward getReward(int id) {
        MapleReward reward = null;
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("SELECT * FROM rewards WHERE `id` = ?")) {
                ps.setInt(1, id);
                try (ResultSet rs = ps.executeQuery()) {
                    if (rs.next()) {
                        reward = new MapleReward(rs.getInt("id"), rs.getLong("start"), rs.getLong("end"), rs.getInt("type"), rs.getInt("itemId"), rs.getInt("mp"), rs.getInt("meso"), rs.getInt("exp"), rs.getString("desc"));
                    }
                }
            }
        } catch (SQLException e) {
            System.err.println("Unable to obtain reward information: " + e);
        }
        return reward;
    }

    public void addReward(int type, int item, int mp, int meso, int exp, String desc) {
        addReward(0L, 0L, type, item, mp, meso, exp, desc);
    }

    public void addReward(long start, long end, int type, int item, int mp, int meso, int exp, String desc) {
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("INSERT INTO rewards (`cid`, `start`, `end`, `type`, `itemId`, `mp`, `meso`, `exp`, `desc`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
                ps.setInt(1, id);
                ps.setLong(2, start);
                ps.setLong(3, end);
                ps.setInt(4, type);
                ps.setInt(5, item);
                ps.setInt(6, mp);
                ps.setInt(7, meso);
                ps.setInt(8, exp);
                ps.setString(9, desc);
                ps.executeUpdate();
            }
        } catch (SQLException e) {
            System.err.println("Unable to obtain reward: " + e);
        }
    }

    public void deleteReward(int id) {
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("DELETE FROM rewards WHERE `id` = ?")) {
                ps.setInt(1, id);
                ps.execute();
            }
        } catch (SQLException e) {
            System.err.println("Unable to delete reward: " + e);
        }
        updateReward();
    }

    public void checkCustomReward(int level) {
        List<Integer> rewards = new LinkedList<>();
        int mp = 0;
        switch (level) {
            case 10:
                rewards.add(2450000);
                rewards.add(2022918);
                mp = 1000;
                break;
            case 20:
                rewards.add(2022918);
                rewards.add(1032099);
                mp = 3000;
                break;
            case 30:
                addReward(4, 0, 0, 5000000, 0, "Here is a special reward for beginners to help you start your journey!");//was 1000000
                rewards.add(2450000);
                rewards.add(1112659);
                mp = 5000;
                break;
            case 50:
                rewards.add(2022918);
                rewards.add(1003361);
                rewards.add(1082399);
                rewards.add(1102337);
                mp = 7500;
                break;
            case 70:
                rewards.add(2450000);
                rewards.add(2022918);
                rewards.add(1003016);
                mp = 10000;
                break;
            case 100:
                addReward(4, 0, 0, 50000000, 0, "Here is a special reward for the experts! Beta only tho.");//just for beta
                rewards.add(2450000);
                rewards.add(2022918);
                rewards.add(1122195);
                rewards.add(1132043);
                rewards.add(1152084);
                mp = 12500;
                break;
            case 120:
                rewards.add(2450000);
                rewards.add(1182007);
                mp = 15000;
                break;
            case 150:
                rewards.add(1142349);
                mp = 17500;
                break;
            case 170:
                rewards.add(1142295);
                mp = 20000;
                break;
            case 200:
                rewards.add(1142456);
                mp = 25000;
                break;
        }
        for (int reward : rewards) {
            addReward(1, reward, 0, 0, 0, "Here is a special reward for reaching Lv. " + level + "!");
        }
        if (mp != 0) {
            addReward(3, 0, mp, 0, 0, "Here is a special reward for reaching Lv. " + level + "!");
        }
        updateReward();
    }

    public void newCharRewards() {
        List<Integer> rewards = new LinkedList<>();
        rewards.add(2022680);
        rewards.add(2450031);
        rewards.add(1142358);
        for (int reward : rewards) {
            addReward(1, reward, 0, 0, 0, "Here is a special reward for beginners to help you start your journey!");
        }
        updateReward();
    }

    public boolean canVote() {
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("SELECT * FROM ipvotes WHERE `accid` = ?")) {
                ps.setInt(1, getAccountID());
                ResultSet rs = ps.executeQuery();
                if (rs.next()) {
                    if ((rs.getLong("lastvote") - (System.currentTimeMillis() / 1000)) > 6 * 60 * 60) {
                        return true;
                    }
                } else {
                    return true;
                }
            }
        } catch (SQLException e) {
            System.err.println("Unable to obtain vote information: " + e);
        }
        return false;
    }

    public void setVote() {
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("DELETE FROM ipvotes WHERE `accid` = ?")) {
                ps.setInt(1, getAccountID());
                ps.execute();
            }
        } catch (SQLException e) {
            System.err.println("Unable to delete vote entry: " + e);
        }
        try {
            Connection con = DatabaseConnection.getConnection();
            try (PreparedStatement ps = con.prepareStatement("INSERT INTO ipvotes (`ip`, `accid`, `lastvote`) VALUES (?, ?, ?)")) {
                ps.setString(1, getClient().getSession().getRemoteAddress().toString().split(":")[0].replaceAll("/", ""));
                ps.setInt(2, getAccountID());
                ps.setLong(3, System.currentTimeMillis() / 1000);
                ps.executeUpdate();
            }
        } catch (SQLException e) {
            System.err.println("Unable to update votes: " + e);
        }
    }

    public void removeBGLayers() {
        for (byte i = 0; i < 127; i++) {
            client.getSession().write(CField.removeBGLayer(true, 0, i, 0));
            //duration 0 = forever map 0 = current map
        }
    }

    public void showBGLayers() {
        for (byte i = 0; i < 127; i++) {
            client.getSession().write(CField.removeBGLayer(false, 0, i, 0));
            //duration 0 = forever map 0 = current map
        }
    }
    public static final int CUSTOM_BG = 61000000;

    public int getCustomBGState() {
        return getIntNoRecord(CUSTOM_BG);
    }

    public void toggleCustomBGState() {
        getQuestNAdd(MapleQuest.getInstance(CUSTOM_BG)).setCustomData(String.valueOf(getCustomBGState() == 1 ? 0 : 1));
        for (byte i = 0; i < 127; i++) {
            WriteFuture write = client.getSession().write(CField.removeBGLayer((getCustomBGState() == 1), 0, i, 0));
            //duration 0 = forever map 0 = current map
        }
    }

    public static void addLinkSkill(int cid, int skill) {
        Connection con = DatabaseConnection.getConnection();
        try {
            try (PreparedStatement ps = con.prepareStatement("INSERT INTO skills (characterid, skillid, skilllevel, masterlevel, expiration) VALUES (?, ?, ?, ?, ?)")) {
                ps.setInt(1, cid);
                if (GameConstants.isApplicableSkill(skill)) { //do not save additional skills
                    ps.setInt(2, skill);
                    ps.setInt(3, 1);
                    ps.setByte(4, (byte) 1);
                    ps.setLong(5, -1);
                    ps.execute();
                }
            }
        } catch (SQLException ex) {
            System.out.println("Failed adding link skill: " + ex);
        }
    }

    public int getWheelItem() {
        return wheelItem;
    }

    public void setWheelItem(int wheelItem) {
        this.wheelItem = wheelItem;
    }

    public static void removePartTime(int cid) {
        Connection con = DatabaseConnection.getConnection();
        try {
            try (PreparedStatement ps = con.prepareStatement("DELETE FROM parttime where cid = ?")) {
                ps.setInt(1, cid);
                ps.executeUpdate();
            }
        } catch (SQLException ex) {
            System.out.println("Failed to remove part time job: " + ex);
        }
    }

    public static void addPartTime(PartTimeJob partTime) {
        if (partTime.getCharacterId() < 1) {
            return;
        }
        addPartTime(partTime.getCharacterId(), partTime.getJob(), partTime.getTime(), partTime.getReward());
    }

    public static void addPartTime(int cid, byte job, long time, int reward) {
        Connection con = DatabaseConnection.getConnection();
        try {
            try (PreparedStatement ps = con.prepareStatement("INSERT INTO parttime (cid, job, time, reward) VALUES (?, ?, ?, ?)")) {
                ps.setInt(1, cid);
                ps.setByte(2, job);
                ps.setLong(3, time);
                ps.setInt(4, reward);
                ps.execute();
            }
        } catch (SQLException ex) {
            System.out.println("Failed to add part time job: " + ex);
        }
    }

    public static PartTimeJob getPartTime(int cid) {
        PartTimeJob partTime = new PartTimeJob(cid);
        Connection con = DatabaseConnection.getConnection();
        try {
            try (PreparedStatement ps = con.prepareStatement("SELECT * FROM parttime WHERE cid = ?")) {
                ps.setInt(1, cid);
                try (ResultSet rs = ps.executeQuery()) {
                    if (rs.next()) {
                        partTime.setJob(rs.getByte("job"));
                        partTime.setTime(rs.getLong("time"));
                        partTime.setReward(rs.getInt("reward"));
                    }
                }
            }
        } catch (Exception ex) {
            System.out.println("Failed to retrieve part time job: " + ex);
        }
        return partTime;
    }

    public void handleKaiserCombo() {
        if (kaiserCombo < 1000) {
            kaiserCombo += 1;
        }
        SkillFactory.getSkill(61111008).getEffect(1).applyKaiser_Combo(this, kaiserCombo);
    }

    public void resetKaiserCombo() {
        kaiserCombo = 0;
        SkillFactory.getSkill(61111008).getEffect(1).applyKaiser_Combo(this, kaiserCombo);
    }

    public void changeLuminousMode(final int skillid) {
        final boolean equilibrium = skillid == 20040220;
        final boolean eclipse = skillid == 20040217;
        final boolean sunfire = skillid == 20040216;
        final MapleCharacter chr = this;
        if (equilibrium || (!eclipse && !sunfire)) {
            return; //impossible
        }
        dispelBuff(skillid);
        luminousState = skillid;
        if (sunfire) {
            runningLight--;
        } else if (eclipse) {
            runningDark--;
        }
        client.getSession().write(LuminousPacket.updateLuminousGauge(runningDarkSlot, runningLightSlot, runningDark, runningLight));
        luminousState = 20040200;
        client.getSession().write(LuminousPacket.giveLuminousState(20040220, chr.getLightGauge(), chr.getDarkGauge(), 0));
        SkillFactory.getSkill(20040220).getEffect(1).applyTo(this);
        equipChanged();
        WorldTimer.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                dispelBuff(20040220);
                client.getSession().write(LuminousPacket.giveLuminousState(skillid, chr.getLightGauge(), chr.getDarkGauge(), 0));
                SkillFactory.getSkill(skillid).getEffect(1).applyTo(chr);
            }
        }, 10000);
    }

    public void handleLuminous(int skillid) {
        int[] lightSkills = new int[]{27001100, 27101100, 27101101, 27111100, 27111101, 27121100};
        int[] darkSkills = new int[]{27001201, 27101202, 27111202, 27121201, 27121202, 27120211};
        boolean found = false;
        for (int light : lightSkills) {
            if (skillid == light) {
                runningLightSlot += Randomizer.nextInt(200) + 100;
                if (runningLightSlot > 10000) {
                    runningLightSlot = 0;
                    runningLight += 1;
                    if (runningLight > 5) {
                        runningLight = 5;
                    }
                }
                found = true;
            }
        }
        for (int dark : darkSkills) {
            if (skillid == dark) {
                runningDarkSlot += Randomizer.nextInt(200) + 100;
                if (runningDarkSlot > 10000) {
                    runningDarkSlot = 0;
                    runningDark += 1;
                    if (runningDark > 5) {
                        runningDark = 5;
                    }
                }
                found = true;
            }
        }
        if (!found) {
            return;
        }

        client.getSession().write(LuminousPacket.updateLuminousGauge(runningDarkSlot, runningLightSlot, runningDark, runningLight));
    }

    public void resetRunningStack() {
        this.runningStack = 0;
        this.runningDark = 0;
        this.runningDarkSlot = 0;
        this.runningLight = 0;
        this.runningLightSlot = 0;
    }

    public int getRunningStack() {
        return this.runningStack;
    }

    public void addRunningStack(int s) {
        runningStack += s;
    }

    public int getLightGauge() {
        return runningLightSlot;
    }

    public int getDarkGauge() {
        return runningDarkSlot;
    }

    public int getLuminousState() {
        return luminousState;
    }

    public void setLuminousState(int luminousState) {
        this.luminousState = luminousState;
    }

    public void setCardStack(byte amount) {
        this.cardStack = amount;
    }

    public byte getCardStack() {
        return this.cardStack;
    }

    public void applyBlackBlessingBuff(int combos) {
        if ((combos == -1) && (this.runningBless == 0)) {
            //combos = 0;
            return;
        }
        Skill skill = SkillFactory.getSkill(27100003);
        int lvl = getTotalSkillLevel(27100003);
        if (lvl > 0) {
            runningBless = ((byte) (runningBless + combos));
            if (runningBless > 3) {
                runningBless = 3;
            }
            if (runningBless == 0) {
                if (getBuffedValue(MapleBuffStat.BLACK_BLESSING) != null) {
                    cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.BLACK_BLESSING});
                }
            } else {
                skill.getEffect(lvl).applyBlackBlessingBuff(this, runningBless);
            }
        }
    }

    public short getXenonSurplus() {
        return xenonSurplus;
    }

    public void setXenonSurplus(short amount) {
        int maxSupply = level >= 100 ? 20 : level >= 60 ? 15 : level >= 30 ? 10 : 5;
        if (xenonSurplus + amount > maxSupply) {
            this.xenonSurplus = (short) maxSupply;
            updateXenonSurplus(xenonSurplus);
            return;
        }
        this.xenonSurplus = amount;
        updateXenonSurplus(xenonSurplus);
    }

    public void gainXenonSurplus(short amount) {
        int maxSupply = level >= 100 ? 20 : level >= 60 ? 15 : level >= 30 ? 10 : 5;
        if (xenonSurplus + amount > maxSupply) {
            this.xenonSurplus = (short) maxSupply;
            updateXenonSurplus(xenonSurplus);
            return;
        }
        this.xenonSurplus += amount;
        updateXenonSurplus(xenonSurplus);
    }

    public void updateXenonSurplus(short amount) {
        int maxSupply = level >= 100 ? 20 : level >= 60 ? 15 : level >= 30 ? 10 : 5;
        if (amount > maxSupply) {
            amount = (short) maxSupply;
        }
        client.getSession().write(XenonPacket.giveXenonSupply(amount));
    }

    public final void startXenonSupply() {
        BuffTimer tMan = BuffTimer.getInstance();
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int maxSupply = level >= 100 ? 20 : level >= 60 ? 15 : level >= 30 ? 10 : 5;
                if (maxSupply > getXenonSurplus()) {
                    gainXenonSurplus((short) 1);
                }
            }
        };
        if (client.isLoggedIn()) {
            XenonSupplyTask = tMan.register(r, 4000);
        }
    }

    public short getExceed() {
        return exceed;
    }

    public void setExceed(short amount) {
        this.exceed = amount;
    }

    public void gainExceed(short amount) {
        this.exceed += amount;
        updateExceed(exceed);
    }

    public void updateExceed(short amount) {
        client.getSession().write(AvengerPacket.giveExceed(amount));
    }

    public void handleExceedAttack(int skill) {
        long now = System.currentTimeMillis();
        if (lastExceedTime + 15000 < now) {
            exceedAttack = 0;
            lastExceedTime = now;
        }
        client.getSession().write(AvengerPacket.giveExceedAttack(skill, ++exceedAttack));
    }

    public MapleCoreAura getCoreAura() {
        return coreAura;
    }

    public void changeWarriorStance(final int skillid) {
        if (skillid == 11101022) {
            dispelBuff(11111022);
            /*List<MapleBuffStat> statups = new LinkedList();
             statups.add(MapleBuffStat.INDIE_BOOSTER);
             statups.add(MapleBuffStat.DAMAGE_PERCENT);
             statups.add(MapleBuffStat.WARRIOR_STANCE);
             //client.getSession().write(BuffPacket.cancelBuff(statups));*/
            client.getSession().write(JobPacket.DawnWarriorPacket.giveMoonfallStance(getSkillLevel(skillid)));
            SkillFactory.getSkill(skillid).getEffect(1).applyTo(this);
        } else if (skillid == 11111022) {
            dispelBuff(11101022);
            /*List<MapleBuffStat> statups = new LinkedList();
             statups.add(MapleBuffStat.MOON_STANCE1);
             statups.add(MapleBuffStat.MOON_STANCE2);
             statups.add(MapleBuffStat.WARRIOR_STANCE);
             //client.getSession().write(BuffPacket.cancelBuff(statups));*/
            client.getSession().write(JobPacket.DawnWarriorPacket.giveSunriseStance(getSkillLevel(skillid)));
            SkillFactory.getSkill(skillid).getEffect(1).applyTo(this);
            /*} else if (skillid == 11121005) {
             //equinox
             } else if (skillid == 11121011) {
             dispelBuff(11101022);
             client.getSession().write(DawnWarriorPacket.giveEquinox_Moon(getSkillLevel(skillid), Integer.MAX_VALUE));
             SkillFactory.getSkill(skillid).getEffect(1).applyTo(this);
             } else if (skillid == 11121012) {
             dispelBuff(11101022);
             client.getSession().write(DawnWarriorPacket.giveEquinox_Sun(getSkillLevel(skillid), Integer.MAX_VALUE));
             SkillFactory.getSkill(skillid).getEffect(1).applyTo(this);*/
        }
    }

    public List<MaplePotionPot> getPotionPots() {
        return potionPots;
    }

    public int getDeathCount() {
        return deathCount;
    }

    public void setDeathCount(int deathCount) {
        this.deathCount = deathCount;
    }

    public void updateDeathCount() {
        if (deathCount < 0) {
            deathCount = 0;
        }
        if (deathCount > 99) {
            deathCount = 99;
        }
//        client.getSession().write(EffectPacket.updateDeathCount(deathCount));
    }

    public void giveMiracleBlessing() {
        for (MapleCharacter chr : getMap().getCharactersThreadsafe()) {
            MapleItemInformationProvider.getInstance().getItemEffect(2023055).applyTo(chr);
        }
        getMap().broadcastMessage(CField.startMapEffect(name + " has received Double Miracle Time's Mysterious Blessing. Congratulations!", 2023055, true));
        World.Broadcast.broadcastMessage(CWvsContext.broadcastMsg(0x19, 0, name + " has received [Double Miracle Time's Miraculous Blessing]. Congratulations!", false));
    }

    public void checkForceShield() {
        final MapleItemInformationProvider li = MapleItemInformationProvider.getInstance();
        Equip equip;
        boolean potential = false;
        switch (job) {
            case 508:
                equip = (Equip) li.getEquipById(1352300);
                break;
            case 572:
                potential = true;
            case 570:
            case 571:
                equip = (Equip) li.getEquipById(1352301 + job % 10);
                break;
            case 3001:
                equip = (Equip) li.getEquipById(1099000);
                break;
            case 3112:
                potential = true;
            case 3100:
            case 3110:
            case 3111:
                equip = (Equip) li.getEquipById(1099001 + job % 10 + ((job % 100) / 10));
                break;
            case 5112:
                potential = true;
            case 5100:
            case 5110:
            case 5111:
                equip = (Equip) li.getEquipById(1098000 + job % 10 + ((job % 100) / 10));
                break;
            case 6001:
                equip = (Equip) li.getEquipById(1352600);
                break;
            case 6512:
                potential = true;
            case 6500:
            case 6510:
            case 6511:
                equip = (Equip) li.getEquipById(1352601 + job % 10 + ((job % 100) / 10));
                break;
            default:
                equip = null;
        }
        if (equip != null) {
            if (potential) {
                equip.resetPotential();
            }
            equip.setPosition((short) -10);
            equip.setQuantity((short) 1);
            equip.setGMLog("Job Advance");
            forceReAddItem_NoUpdate(equip, MapleInventoryType.EQUIPPED);
            client.getSession().write(InventoryPacket.updateEquippedItem(this, equip, (short) -10));
            equipChanged();
        }
    }

    public void checkZeroWeapon() {
        if (level < 100) {
            return;
        }
        int lazuli = getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11).getItemId();
        int lapis = getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10).getItemId();
        if (lazuli == getZeroWeapon(false) && lapis == getZeroWeapon(true)) {
            return;
        }
        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        for (int i = 0; i < 2; i++) {
            int itemId = i == 0 ? getZeroWeapon(false) : getZeroWeapon(true);
            Equip equip = (Equip) ii.getEquipById(itemId);
            equip.setPosition((short) (i == 0 ? -11 : -10));
            equip.setQuantity((short) 1);
            equip.setGMLog("Zero Weapon Advance");
            forceReAddItem_NoUpdate(equip, MapleInventoryType.EQUIPPED);
            client.getSession().write(InventoryPacket.updateEquippedItem(this, equip, (short) (i == 0 ? -11 : -10)));
        }
        equipChanged();
    }

    public int getZeroWeapon(boolean lapis) {
        if (level < 100) {
            return lapis ? 1562000 : 1572000;
        }
        int weapon = lapis ? 1562001 : 1572001;
        if (level >= 100 && level < 160) {
            weapon += (level % 100) / 10;
        } else if (level >= 160 && level < 170) {
            weapon += 5;
        } else if (level >= 170) {
            weapon += 6;
        }
        return weapon;
    }

    public void zeroChange(boolean beta) {
        getMap().broadcastMessage(this, CField.updateCharLook(this, beta), getPosition());
    }

    public void checkZeroTranscendent() {
        int skill = -1;
        switch (level / 10) {
            case 10:
                skill = 100000267;
                break;
            case 11:
                skill = 100001261;
                break;
            case 12:
                skill = 100001274;
                break;
            case 14:
                skill = 100001272;
                break;
            case 17:
                skill = 100001283;
                break;
            case 20:
                skill = 100001005;
                break;
        }
        if (skill == -1) {
            return;
        }
        Skill skil = SkillFactory.getSkill(skill);
        if (skil != null) {
            changeSkillLevel_Skip(skil, 1, (byte) 1);
        }
    }

    public boolean hasEntered(String script) {
        for (int mapId : entered.keySet()) {
            if (entered.get(mapId).equals(script)) {
                return true;
            }
        }
        return false;
    }

    public boolean hasEntered(String script, int mapId) {
        if (entered.containsKey(mapId)) {
            if (entered.get(mapId).equals(script)) {
                return true;
            }
        }
        return false;
    }

    public void enteredScript(String script, int mapid) {
        if (!entered.containsKey(mapid)) {
            entered.put(mapid, script);
        }
    }

    public void femaleMihile() {
        setGender((byte) 1);
        setFace(21158); //Elegant Lady face sounds nice
        setHair(34773); //Aria hair fits there most
        final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        Equip equip;
        int[][] items = new int[][]{{1051355, -5}, {1072833, -6}};
        for (int[] item : items) {
            equip = (Equip) ii.getEquipById(item[0]);
            equip.setPosition((short) item[1]);
            equip.setQuantity((short) 1);
            equip.setGMLog("Female Mihile");
            forceReAddItem_NoUpdate(equip, MapleInventoryType.EQUIPPED);
            client.getSession().write(InventoryPacket.updateEquippedItem(this, equip, (short) item[1]));
        }