Search in sources :

Example 1 with MapleStat

use of client.MapleStat in project HeavenMS by ronancpl.

the class MaplePacketCreator method updatePlayerStats.

/**
 * Gets an update for specified stats.
 *
 * @param stats The list of stats to update.
 * @param itemReaction Result of an item reaction(?)
 * @return The stat update packet.
 */
public static byte[] updatePlayerStats(List<Pair<MapleStat, Integer>> stats, boolean itemReaction, MapleCharacter chr) {
    final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
    mplew.writeShort(SendOpcode.STAT_CHANGED.getValue());
    mplew.write(itemReaction ? 1 : 0);
    int updateMask = 0;
    for (Pair<MapleStat, Integer> statupdate : stats) {
        updateMask |= statupdate.getLeft().getValue();
    }
    List<Pair<MapleStat, Integer>> mystats = stats;
    if (mystats.size() > 1) {
        Collections.sort(mystats, new Comparator<Pair<MapleStat, Integer>>() {

            @Override
            public int compare(Pair<MapleStat, Integer> o1, Pair<MapleStat, Integer> o2) {
                int val1 = o1.getLeft().getValue();
                int val2 = o2.getLeft().getValue();
                return (val1 < val2 ? -1 : (val1 == val2 ? 0 : 1));
            }
        });
    }
    mplew.writeInt(updateMask);
    for (Pair<MapleStat, Integer> statupdate : mystats) {
        if (statupdate.getLeft().getValue() >= 1) {
            if (statupdate.getLeft().getValue() == 0x1) {
                mplew.writeShort(statupdate.getRight().shortValue());
            } else if (statupdate.getLeft().getValue() <= 0x4) {
                mplew.writeInt(statupdate.getRight());
            } else if (statupdate.getLeft().getValue() < 0x20) {
                mplew.write(statupdate.getRight().shortValue());
            } else if (statupdate.getLeft().getValue() == 0x8000) {
                if (GameConstants.hasSPTable(chr.getJob())) {
                    mplew.write(chr.getRemainingSpSize());
                    for (int i = 0; i < chr.getRemainingSps().length; i++) {
                        if (chr.getRemainingSpBySkill(i) > 0) {
                            mplew.write(i + 1);
                            mplew.write(chr.getRemainingSpBySkill(i));
                        }
                    }
                } else {
                    mplew.writeShort(statupdate.getRight().shortValue());
                }
            } else if (statupdate.getLeft().getValue() < 0xFFFF) {
                mplew.writeShort(statupdate.getRight().shortValue());
            } else {
                mplew.writeInt(statupdate.getRight().intValue());
            }
        }
    }
    return mplew.getPacket();
}
Also used : MaplePacketLittleEndianWriter(tools.data.output.MaplePacketLittleEndianWriter) MapleStat(client.MapleStat) Point(java.awt.Point)

Example 2 with MapleStat

use of client.MapleStat in project HeavenMS by ronancpl.

the class AutoAssignHandler method handlePacket.

@Override
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    MapleCharacter chr = c.getPlayer();
    int[] statGain = new int[4];
    int[] statEqpd = new int[4];
    statGain[0] = 0;
    statGain[1] = 0;
    statGain[2] = 0;
    statGain[3] = 0;
    slea.skip(8);
    // useful for pirate autoassigning
    byte opt = slea.readByte();
    if (chr.getRemainingAp() < 1)
        return;
    if (ServerConstants.USE_SERVER_AUTOASSIGNER) {
        // --------- Ronan Lana's AUTOASSIGNER ---------
        // This method excels for assigning APs in such a way to cover all equipments AP requirements.
        int str = 0, dex = 0, luk = 0, int_ = 0;
        List<Short> eqpStrList = new ArrayList<>();
        List<Short> eqpDexList = new ArrayList<>();
        List<Short> eqpLukList = new ArrayList<>();
        MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
        Collection<Item> equippedC = iv.list();
        Equip nEquip;
        for (Item item : equippedC) {
            // selecting the biggest AP value of each stat from each equipped item.
            nEquip = (Equip) item;
            if (nEquip.getStr() > 0)
                eqpStrList.add(nEquip.getStr());
            str += nEquip.getStr();
            if (nEquip.getDex() > 0)
                eqpDexList.add(nEquip.getDex());
            dex += nEquip.getDex();
            if (nEquip.getLuk() > 0)
                eqpLukList.add(nEquip.getLuk());
            luk += nEquip.getLuk();
            // if(nEquip.getInt() > 0) eqpIntList.add(nEquip.getInt()); //not needed...
            int_ += nEquip.getInt();
        }
        statEqpd[0] = str;
        statEqpd[1] = dex;
        statEqpd[2] = luk;
        statEqpd[3] = int_;
        Collections.sort(eqpStrList, Collections.reverseOrder());
        Collections.sort(eqpDexList, Collections.reverseOrder());
        Collections.sort(eqpLukList, Collections.reverseOrder());
        // Autoassigner looks up the 1st/2nd placed equips for their stats to calculate the optimal upgrade.
        int eqpStr = getNthHighestStat(eqpStrList, (short) 0) + getNthHighestStat(eqpStrList, (short) 1);
        int eqpDex = getNthHighestStat(eqpDexList, (short) 0) + getNthHighestStat(eqpDexList, (short) 1);
        int eqpLuk = getNthHighestStat(eqpLukList, (short) 0) + getNthHighestStat(eqpLukList, (short) 1);
        // c.getPlayer().message("----------------------------------------");
        // c.getPlayer().message("SDL: s" + eqpStr + " d" + eqpDex + " l" + eqpLuk + " BASE STATS --> STR: " + chr.getStr() + " DEX: " + chr.getDex() + " INT: " + chr.getInt() + " LUK: " + chr.getLuk());
        // c.getPlayer().message("SUM EQUIP STATS -> STR: " + str + " DEX: " + dex + " LUK: " + luk + " INT: " + int_);
        MapleJob stance = c.getPlayer().getJobStyle(opt);
        int prStat = 0, scStat = 0, trStat = 0, temp, tempAp = chr.getRemainingAp(), CAP;
        MapleStat primary, secondary, tertiary = MapleStat.LUK;
        switch(stance) {
            case MAGICIAN:
                CAP = 165;
                scStat = (chr.getLevel() + 3) - (chr.getLuk() + luk - eqpLuk);
                if (scStat < 0)
                    scStat = 0;
                scStat = Math.min(scStat, tempAp);
                if (tempAp > scStat)
                    tempAp -= scStat;
                else
                    tempAp = 0;
                prStat = tempAp;
                int_ = prStat;
                luk = scStat;
                str = 0;
                dex = 0;
                if (luk + chr.getLuk() > CAP) {
                    temp = luk + chr.getLuk() - CAP;
                    luk -= temp;
                    int_ += temp;
                }
                primary = MapleStat.INT;
                secondary = MapleStat.LUK;
                tertiary = MapleStat.DEX;
                break;
            case BOWMAN:
                CAP = 125;
                scStat = (chr.getLevel() + 5) - (chr.getStr() + str - eqpStr);
                if (scStat < 0)
                    scStat = 0;
                scStat = Math.min(scStat, tempAp);
                if (tempAp > scStat)
                    tempAp -= scStat;
                else
                    tempAp = 0;
                prStat = tempAp;
                dex = prStat;
                str = scStat;
                int_ = 0;
                luk = 0;
                if (str + chr.getStr() > CAP) {
                    temp = str + chr.getStr() - CAP;
                    str -= temp;
                    dex += temp;
                }
                primary = MapleStat.DEX;
                secondary = MapleStat.STR;
                break;
            case GUNSLINGER:
            case CROSSBOWMAN:
                CAP = 120;
                scStat = chr.getLevel() - (chr.getStr() + str - eqpStr);
                if (scStat < 0)
                    scStat = 0;
                scStat = Math.min(scStat, tempAp);
                if (tempAp > scStat)
                    tempAp -= scStat;
                else
                    tempAp = 0;
                prStat = tempAp;
                dex = prStat;
                str = scStat;
                int_ = 0;
                luk = 0;
                if (str + chr.getStr() > CAP) {
                    temp = str + chr.getStr() - CAP;
                    str -= temp;
                    dex += temp;
                }
                primary = MapleStat.DEX;
                secondary = MapleStat.STR;
                break;
            case THIEF:
                CAP = 160;
                scStat = 0;
                if (chr.getDex() < 80) {
                    scStat = (2 * chr.getLevel()) - (chr.getDex() + dex - eqpDex);
                    if (scStat < 0)
                        scStat = 0;
                    scStat = Math.min(80 - chr.getDex(), scStat);
                    scStat = Math.min(tempAp, scStat);
                    tempAp -= scStat;
                }
                temp = (chr.getLevel() + 40) - Math.max(80, scStat + chr.getDex() + dex - eqpDex);
                if (temp < 0)
                    temp = 0;
                temp = Math.min(tempAp, temp);
                scStat += temp;
                tempAp -= temp;
                // thieves will upgrade STR as well only if a level-based threshold is reached.
                if (chr.getStr() >= Math.max(13, (int) (0.4 * chr.getLevel()))) {
                    if (chr.getStr() < 50) {
                        trStat = (chr.getLevel() - 10) - (chr.getStr() + str - eqpStr);
                        if (trStat < 0)
                            trStat = 0;
                        trStat = Math.min(50 - chr.getStr(), trStat);
                        trStat = Math.min(tempAp, trStat);
                        tempAp -= trStat;
                    }
                    temp = (20 + (chr.getLevel() / 2)) - Math.max(50, trStat + chr.getStr() + str - eqpStr);
                    if (temp < 0)
                        temp = 0;
                    temp = Math.min(tempAp, temp);
                    trStat += temp;
                    tempAp -= temp;
                }
                prStat = tempAp;
                luk = prStat;
                dex = scStat;
                str = trStat;
                int_ = 0;
                if (dex + chr.getDex() > CAP) {
                    temp = dex + chr.getDex() - CAP;
                    dex -= temp;
                    luk += temp;
                }
                if (str + chr.getStr() > CAP) {
                    temp = str + chr.getStr() - CAP;
                    str -= temp;
                    luk += temp;
                }
                primary = MapleStat.LUK;
                secondary = MapleStat.DEX;
                tertiary = MapleStat.STR;
                break;
            case BRAWLER:
                CAP = 120;
                scStat = chr.getLevel() - (chr.getDex() + dex - eqpDex);
                if (scStat < 0)
                    scStat = 0;
                scStat = Math.min(scStat, tempAp);
                if (tempAp > scStat)
                    tempAp -= scStat;
                else
                    tempAp = 0;
                prStat = tempAp;
                str = prStat;
                dex = scStat;
                int_ = 0;
                luk = 0;
                if (dex + chr.getDex() > CAP) {
                    temp = dex + chr.getDex() - CAP;
                    dex -= temp;
                    str += temp;
                }
                primary = MapleStat.STR;
                secondary = MapleStat.DEX;
                break;
            default:
                // warrior, beginner, ...
                CAP = 80;
                scStat = ((2 * chr.getLevel()) / 3) - (chr.getDex() + dex - eqpDex);
                if (scStat < 0)
                    scStat = 0;
                scStat = Math.min(scStat, tempAp);
                if (tempAp > scStat)
                    tempAp -= scStat;
                else
                    tempAp = 0;
                prStat = tempAp;
                str = prStat;
                dex = scStat;
                int_ = 0;
                luk = 0;
                if (dex + chr.getDex() > CAP) {
                    temp = dex + chr.getDex() - CAP;
                    dex -= temp;
                    str += temp;
                }
                primary = MapleStat.STR;
                secondary = MapleStat.DEX;
        }
        // -------------------------------------------------------------------------------------
        int extras = 0;
        extras = gainStatByType(chr, primary, statGain, prStat + extras);
        extras = gainStatByType(chr, secondary, statGain, scStat + extras);
        extras = gainStatByType(chr, tertiary, statGain, trStat + extras);
        if (extras > 0) {
            // redistribute surplus in priority order
            extras = gainStatByType(chr, primary, statGain, extras);
            extras = gainStatByType(chr, secondary, statGain, extras);
            extras = gainStatByType(chr, tertiary, statGain, extras);
            gainStatByType(chr, getQuaternaryStat(stance), statGain, extras);
        }
        int remainingAp = (chr.getRemainingAp() - getAccumulatedStatGain(statGain));
        chr.setRemainingAp(remainingAp);
        chr.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
        c.announce(MaplePacketCreator.enableActions());
        // ----------------------------------------------------------------------------------------
        c.announce(MaplePacketCreator.serverNotice(1, "Better AP applications detected:\r\nSTR: +" + statGain[0] + "\r\nDEX: +" + statGain[1] + "\r\nINT: +" + statGain[3] + "\r\nLUK: +" + statGain[2]));
    } else {
        int total = 0;
        int extras = 0;
        if (slea.available() < 16) {
            AutobanFactory.PACKET_EDIT.alert(chr, "Didn't send full packet for Auto Assign.");
            c.disconnect(false, false);
            return;
        }
        MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
        Collection<Item> equippedC = iv.list();
        for (Item item : equippedC) {
            // selecting the biggest AP value of each stat from each equipped item.
            Equip nEquip = (Equip) item;
            statEqpd[0] += nEquip.getStr();
            statEqpd[1] += nEquip.getDex();
            statEqpd[2] += nEquip.getLuk();
            statEqpd[3] += nEquip.getInt();
        }
        for (int i = 0; i < 2; i++) {
            int type = slea.readInt();
            int tempVal = slea.readInt();
            if (tempVal < 0 || tempVal > c.getPlayer().getRemainingAp()) {
                return;
            }
            total += tempVal;
            extras += gainStatByType(chr, MapleStat.getBy5ByteEncoding(type), statGain, tempVal);
        }
        int remainingAp = (chr.getRemainingAp() - total) + extras;
        chr.setRemainingAp(remainingAp);
        chr.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
        c.announce(MaplePacketCreator.enableActions());
    }
}
Also used : MapleCharacter(client.MapleCharacter) ArrayList(java.util.ArrayList) MapleStat(client.MapleStat) MapleInventory(client.inventory.MapleInventory) Item(client.inventory.Item) Equip(client.inventory.Equip) MapleJob(client.MapleJob)

Aggregations

MapleStat (client.MapleStat)2 MapleCharacter (client.MapleCharacter)1 MapleJob (client.MapleJob)1 Equip (client.inventory.Equip)1 Item (client.inventory.Item)1 MapleInventory (client.inventory.MapleInventory)1 Point (java.awt.Point)1 ArrayList (java.util.ArrayList)1 MaplePacketLittleEndianWriter (tools.data.output.MaplePacketLittleEndianWriter)1