Elitist Jerks
Register
Blogs
Forums


Go Back   Elitist Jerks » Class Mechanics » Death Knights

Closed Thread
 
LinkBack Thread Tools
Old 10/17/10, 9:21 AM   #151
coca
Von Kaiser
 
Blood Elf Warlock
 
Dalaran
Yeah unless there is a B/F rune available you always want to SS instead.

On average my FS hits for 5891 and crits for 10869.
On average my SS hits for 7830 and crits for 12200.

Waiting on that 1 frost rune is fine. You really only use FS to refresh the diseases in the rotation and to get rid of that frost rune for more death runes.

Last edited by coca : 10/17/10 at 9:32 AM.

Offline
Old 10/17/10, 9:56 AM   #152
Ciuperci
Glass Joe
 
Ciuperci's Avatar
 
Orc Death Knight
 
Terenas
Originally Posted by Baadshah View Post
One issue I'd like to raise is with the ghoul macro that most of us have begun to adopt. The concept is simple: You add a Claw macro to your Scourge Strike ability, so that the ghoul is essentially spamming this ability for optimal DPS.

Mine, for instance, looks something like this:
#showtooltip Scourge Strike
/script UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE");
/cast Scourge Strike;
/cast [@pettarget,harm][harm] Claw;
/script UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")'

The problem comes in when your target dies to Scourge Strike- the ghoul then runs off at a new target and attacks it. Naturally, this has the potential to cause a lot of problems in 5 mans, for raid trash and for any boss encounter with significant numbers of adds.
Any suggestions?
If I'm not mistaken you should just switch the order of your /cast commands so Claw comes before Scourge Strike. Your target may switch if Claw kills the mob, but hopefully you'll know to not go off running and aggro a new pack.

Offline
Old 10/17/10, 10:47 AM   #153
forecore
Glass Joe
 
Orc Death Knight
 
Blackrock (EU)
I just did some math regarding trinket EP values. (used values of OP)

DBW hc 1233.0
DBW 1094.2
DC/DV hc 1047.9
STS hc 1046.2
HWT (96% uptime) 977.8
STS 927.5
DC 926.5
WFS hc 864.1

With haste/str being twice as useful as crit/ap STS lost quite a lot of its attractiveness.

all EP values assuming that crit was reforged to haste if possible

Offline
Old 10/17/10, 11:27 AM   #154
Shareth
Von Kaiser
 
Blood Elf Death Knight
 
Tarren Mill (EU)
Seems like Unholy was lucky enough to get another bug in its face. Basically, sometimes some runes get their cooldown increased by 0.5-1 second out of nowhere. This works only for Unholy (tested with Blood - nothing happened, didn't test Frost).

Tested it in Lua while fighting this bug in my own addon and I definitely see RUNE_POWER_UPDATE event firing twice sometimes for the same rune. For example, after I use Blood Strike it fires RUNE_POWER_UPDATE with GetRuneCooldown returning 10 seconds cooldown for a rune. In like 0.5 seconds or so it fires another RUNE_POWER_UPDATE with GetRuneCooldown returning some value which can be even higher than those 10 seconds you got from first event. This happens only when I spec Unholy, even when Im naked with 0% haste, in non-Unholy presence and without procing Runic Corruption (thought it had something to do with haste, but no). This doesn't happen in Blood spec, didn't test Frost. Probably it has something to do with talented Runic Corruption.

Anyone experiencing the same bug?

Author of DKM.

Russia Offline
Old 10/17/10, 1:00 PM   #155
dr_AllCOM3
Great Tiger
 
dr_AllCOM3's Avatar
 
Orc Death Knight
 
Blutkessel (EU)
Originally Posted by Shareth View Post
Anyone experiencing the same bug?
and I thought my rune addon was broken . The runes tend to jump back a tiny bit after you use the rune. This does only happen for Unholy DK's with RC.


Offline
Old 10/17/10, 1:11 PM   #156
Cayseth
Glass Joe
 
Orc Death Knight
 
Blackmoore (EU)
Originally Posted by Shareth View Post
Seems like Unholy was lucky enough to get another bug in its face. Basically, sometimes some runes get their cooldown increased by 0.5-1 second out of nowhere. This works only for Unholy (tested with Blood - nothing happened, didn't test Frost).
Originally Posted by dr_AllCOM3
and I thought my rune addon was broken . The runes tend to jump back a tiny bit after you use the rune. This does only happen for Unholy DK's with RC.
I've also noticed this as Frost when using Rime.

Offline
Old 10/17/10, 2:03 PM   #157
Flyx
Glass Joe
 
Night Elf Death Knight
 
Outland (EU)
I thought it was just a display error, but I've been seeing the same thing as frost while hitting a dummy. Runes on cooldown get pushed back a tiny amount everytime I use howling blast.

It seems to be the same time as it takes a rune to be refreshed if you had missed the howling blast. It's like the game is treating even successful howling blasts as a miss, and so adding a slight cooldown to the rune as it does normally when howling blast misses.



Edit: Just been hitting the dummy and I've had this bug occur on most howling blasts, but not all. Then I saw that sometimes if you have two frost runes on cooldown, then you use a howling blast as soon as the first one comes off cooldown, they with both start to refresh at the same time, giving you both frost runes back in the time you should only recieve the second one.

Edit 2: Seem to have found out why both frost runes are coming off CD at the same time. Whenever your howling blast misses it actually puts the rune on full CD if the 2nd rune is on cooldown and starts to bring both of them back together, rather than resetting one instantly and keeping the other refreshing

Last edited by Flyx : 10/17/10 at 2:25 PM.

Offline
Old 10/17/10, 2:05 PM   #158
NemoX
Glass Joe
 
Draenei Death Knight
 
Bleeding Hollow
Originally Posted by Baadshah View Post
The problem comes in when your target dies to Scourge Strike- the ghoul then runs off at a new target and attacks it. Naturally, this has the potential to cause a lot of problems in 5 mans, for raid trash and for any boss encounter with significant numbers of adds.
Any suggestions?
You could try adding "combat" into the conditionals for Claw, he still might run off in combat if it picks a new target, but may stop a few mistakes.

Offline
Old 10/17/10, 2:50 PM   #159
dr_AllCOM3
Great Tiger
 
dr_AllCOM3's Avatar
 
Orc Death Knight
 
Blutkessel (EU)
Ebon Plague has been fixed. My FeS does increase it's duration.


Offline
Old 10/17/10, 4:24 PM   #160
SublimeBL
Glass Joe
 
Orc Death Knight
 
Burning Legion
Quick question on haste:
I'm seeing that the haste from Improved Unholy Presence isn't showing up on my tooltip. If that's the case, should I only be aiming for about 25% haste for the "soft cap" on haste? Or still be shooting for 30%?

Offline
Old 10/17/10, 6:39 PM   #161
Nyxxie
Glass Joe
 
Blood Elf Death Knight
 
Lightninghoof
I want to share this Java program I coded which finds the best way to reforge your gear based on Unholy stat weights.

The program works by taking the stats on your gear, and the stat weights of all relevant reforge-able stats. Then it exhaustively tests every combination of possible reforges, weights the results, and reports the combination which yielded the best weight.

Because there are so many combinations (268,435,456, which is 7^16 for 16 pieces of gear which you could do 7 things with: reforging each of 2 stats to 3 other stats, plus 1 for deciding to not reforge the item), the program filters out stupid reforge choices like Haste -> Crit on a piece-by-piece basis to lower the number of combinations that need to be tried. My fat-trimming algorithm can cut it down to 65,536 - 43,046,721 combinations depending on the gear.

A limitation of this program is that it doesn't yet support pieces of gear with 3 reforge-able stats (do they even exist?) This would raise the number of combinations that might need to be tried, I don't know yet whether it'd be feasible.

It'd be cool if someone with more time than me could improve this algorithm and make it into a public utility. Maybe make it download stats from the armory, have a nice UI for entering stat weights. I'd recommend implementing it as either a Java Applet or writing equivalent JavaScript so that the calculation can run client-side in a browser.

A sample output looks like:

Tested 3779136 combinations in 35123 ms
Best Weight: 7965.95
-----------------
Alternative1
CRIT: 1147
HASTE: 898
EXPERTISE: 105
HIT: 246
HEAD: Don't Reforge
NECK: Don't Reforge
SHOULDER: CRIT -> HIT
BACK: CRIT -> HASTE
CHEST: Don't Reforge
WRIST: HIT -> HASTE
HANDS: CRIT -> HASTE
WAIST: Don't Reforge
LEGS: Don't Reforge
FEET: CRIT -> HASTE
RING1: HIT -> HASTE
RING2: CRIT -> HASTE
TRINKET1: CRIT -> HASTE
TRINKET2: CRIT -> HASTE
MAINHAND: Don't Reforge
RELIC: Don't Reforge

Here's the code:
package reforging;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;

/**
 *
 * @author Nyxxie
 */
public class Main {

    private static final LinkedHashMap<Stat, Double> statWeights = new LinkedHashMap();
    private static final LinkedHashMap<BaseStat, Double> baseStats = new LinkedHashMap();
    private static final LinkedHashMap<Slot, Gear> gear = new LinkedHashMap();
    private static final int ABILITY_HIT_CAP = 246;
    private static final int SPELL_HIT_CAP = 446;//tweak this
    private static final int WHITE_HIT_CAP = 446;//tweak this

    public static void main(String[] args) {
        //Define stat weights in order of weight, high to low
        statWeights.put(Stat.ABILITY_HIT, 5.83);
        statWeights.put(Stat.HASTE, 4.28);
        statWeights.put(Stat.CRIT, 2.19);
        statWeights.put(Stat.EXPERTISE, 1.68);
        statWeights.put(Stat.MASTERY, 1.41);
        statWeights.put(Stat.SPELL_HIT, 0.0);
        statWeights.put(Stat.WHITE_HIT, 0.0);//not ready yet

        //Define Base Stats
        baseStats.put(BaseStat.SPELL_HIT_PCT, 6.0);//not ready yet
        baseStats.put(BaseStat.EXPERTISE_PCT, 0.0);//not ready yet

        //Define Gear
        final Gear helm = new Gear();
        helm.stats.put(Stat.CRIT, 100);
        helm.stats.put(Stat.HASTE, 92);
        gear.put(Slot.HEAD, helm);

        final Gear neck = new Gear();
        neck.stats.put(Stat.CRIT, 62);
        neck.stats.put(Stat.HASTE, 49);
        gear.put(Slot.NECK, neck);

        final Gear shoulder = new Gear();
        shoulder.stats.put(Stat.CRIT, 80);
        shoulder.stats.put(Stat.HASTE, 72);
        gear.put(Slot.SHOULDER, shoulder);

        final Gear back = new Gear();
        back.stats.put(Stat.CRIT, 65);
        back.stats.put(Stat.EXPERTISE, 45);
        gear.put(Slot.BACK, back);

        final Gear chest = new Gear();
        chest.stats.put(Stat.CRIT, 108);
        chest.stats.put(Stat.HASTE, 92);
        gear.put(Slot.CHEST, chest);

        final Gear wrist = new Gear();
        wrist.stats.put(Stat.HIT, 60);
        wrist.stats.put(Stat.CRIT, 68);
        gear.put(Slot.WRIST, wrist);

        final Gear hands = new Gear();
        hands.stats.put(Stat.HIT, 72);
        hands.stats.put(Stat.CRIT, 80);
        gear.put(Slot.HANDS, hands);

        final Gear waist = new Gear();
        waist.stats.put(Stat.CRIT, 75);
        waist.stats.put(Stat.HASTE, 68);
        gear.put(Slot.WAIST, waist);

        final Gear legs = new Gear();
        legs.stats.put(Stat.CRIT, 108);
        legs.stats.put(Stat.HASTE, 84);
        gear.put(Slot.LEGS, legs);

        final Gear feet = new Gear();
        feet.stats.put(Stat.HIT, 70);
        feet.stats.put(Stat.CRIT, 86);
        gear.put(Slot.FEET, feet);

        final Gear ring1 = new Gear();
        ring1.stats.put(Stat.HIT, 59);
        ring1.stats.put(Stat.CRIT, 59);
        gear.put(Slot.RING1, ring1);

        final Gear ring2 = new Gear();
        ring2.stats.put(Stat.CRIT, 68);
        ring2.stats.put(Stat.EXPERTISE, 60);
        gear.put(Slot.RING2, ring2);

        final Gear trinket1 = new Gear();
        trinket1.stats.put(Stat.CRIT, 163);
        gear.put(Slot.TRINKET1, trinket1);

        final Gear trinket2 = new Gear();
        trinket2.stats.put(Stat.CRIT, 155);
        gear.put(Slot.TRINKET2, trinket2);

        final Gear mainhand = new Gear();
        mainhand.stats.put(Stat.CRIT, 114);
        mainhand.stats.put(Stat.HASTE, 114);
        gear.put(Slot.MAINHAND, mainhand);

        final Gear relic = new Gear();
        relic.stats.put(Stat.CRIT, 34);
        relic.stats.put(Stat.HASTE, 34);
        gear.put(Slot.RELIC, relic);

        //For each piece of gear, assemble all viable reforge orders for each piece of gear
        final LinkedHashMap<Slot, LinkedHashSet<ReforgeOrder>> allReforgeOrders = assembleReforgeOrders();

        //Do calculations
        final long startTime = Calendar.getInstance().getTimeInMillis();

        long maxCombinations = 1;
        for (LinkedHashSet<ReforgeOrder> roSet : allReforgeOrders.values()) {
            maxCombinations *= roSet.size();
        }

        int counter = 0;
        final LinkedHashMap<Slot, ReforgeOrder> reforgeOrders = new LinkedHashMap();
        double bestWeight = 0.0;
        final ArrayList<LinkedHashMap<Slot, ReforgeOrder>> setOfBestReforgeOrders = new ArrayList();
        final ArrayList<CalculationResult> setOfBestResults = new ArrayList();
        while (cycleReforgeOrder(0, reforgeOrders, allReforgeOrders)) {
            counter += 1;
            if (counter % 100000 == 0) {
                System.out.println("Tested combination " + counter + " of " + maxCombinations);
            }
            final CalculationResult result = calculateReforgeResult(reforgeOrders);
            final double weight = result.totalWeight;
            if (weight >= bestWeight) {
                if (weight > bestWeight) {
                    bestWeight = weight;
                    setOfBestReforgeOrders.clear();
                    setOfBestResults.clear();
                }
                setOfBestReforgeOrders.add(copyReforgeOrders(reforgeOrders));
                setOfBestResults.add(copyCalculationResult(result));
            }
        }

        final long endTime = Calendar.getInstance().getTimeInMillis();

        //Print results
        System.out.println("Tested " + String.valueOf(counter) + " combinations in " + String.valueOf(endTime - startTime) + " ms");
        System.out.println("Best Weight: " + bestWeight);
        printResults(setOfBestResults, setOfBestReforgeOrders);
    }//end of program

    private static void printResults(ArrayList<CalculationResult> setOfBestResults, ArrayList<LinkedHashMap<Slot, ReforgeOrder>> setOfBestReforgeOrders) {
        for (int i = 0; i < setOfBestResults.size(); i++) {
            final LinkedHashMap<Slot, ReforgeOrder> bestReforgeOrders = setOfBestReforgeOrders.get(i);
            final CalculationResult result = setOfBestResults.get(i);

            System.out.println("-----------------");
            System.out.println("Alternative" + String.valueOf(i + 1));
            for (Stat st : result.newStats.keySet()) {
                System.out.println(st.name() + ": " + result.newStats.get(st));
            }
            for (Slot sl : bestReforgeOrders.keySet()) {
                final ReforgeOrder r = bestReforgeOrders.get(sl);
                if (r.leaveAlone) {
                    System.out.println(sl.name() + ": Don't Reforge");
                } else {
                    System.out.println(sl.name() + ": " + r.oldStat.name() + " -> " + r.newStat.name());
                }
            }
        }
    }

    private static LinkedHashMap<Slot, ReforgeOrder> copyReforgeOrders(LinkedHashMap<Slot, ReforgeOrder> reforgeOrders) {
        final LinkedHashMap<Slot, ReforgeOrder> copyOfReforgeOrders = new LinkedHashMap();

        for (Slot sl : reforgeOrders.keySet()) {
            final ReforgeOrder copyOfReforgeOrder;

            final ReforgeOrder reforgeOrder = reforgeOrders.get(sl);
            if (reforgeOrder.leaveAlone) {
                copyOfReforgeOrder = new ReforgeOrder();//leave alone
            } else {
                copyOfReforgeOrder = new ReforgeOrder(reforgeOrder.oldStat, reforgeOrder.newStat);
            }

            copyOfReforgeOrders.put(sl, copyOfReforgeOrder);
        }

        return copyOfReforgeOrders;
    }

    private static CalculationResult copyCalculationResult(CalculationResult calculationResult) {
        final LinkedHashMap<Stat, Integer> copyOfNewStats = new LinkedHashMap();

        final LinkedHashMap<Stat, Integer> newStats = calculationResult.newStats;
        for (Stat st : newStats.keySet()) {
            copyOfNewStats.put(st, newStats.get(st));
        }

        final CalculationResult copyOfCalculationResult = new CalculationResult(copyOfNewStats, calculationResult.totalWeight);
        return copyOfCalculationResult;
    }

    private static CalculationResult calculateReforgeResult(LinkedHashMap<Slot, ReforgeOrder> reforgeOrders) {
        final LinkedHashMap<Stat, Integer> newStats = new LinkedHashMap();
        //Prepare newStats using exising stats on gear
        for (Gear g : gear.values()) {
            for (Stat st : g.stats.keySet()) {
                if (!newStats.containsKey(st)) {
                    newStats.put(st, 0);
                }
            }
        }
        //Prepare newStats using stats not had before reforging
        for (ReforgeOrder ro : reforgeOrders.values()) {
            if (ro.leaveAlone) {
                continue;
            }
            if (!newStats.containsKey(ro.newStat)) {
                newStats.put(ro.newStat, 0);
            }
        }
        //Tally up newStats after reforging
        for (Slot sl : gear.keySet()) {
            final Gear g = gear.get(sl);
            final ReforgeOrder ro = reforgeOrders.get(sl);
            if (ro != null && !ro.leaveAlone) {
                //factor in reduced oldStat
                newStats.put(ro.oldStat, newStats.get(ro.oldStat) + (int) Math.ceil(0.60 * g.stats.get(ro.oldStat)));
                //factor in newStat
                newStats.put(ro.newStat, newStats.get(ro.newStat) + (int) Math.floor(0.40 * g.stats.get(ro.oldStat)));
                //factor in other stats
                for (Stat st : g.stats.keySet()) {
                    if (st == ro.oldStat) {
                        continue;//oldStat already factored in
                    }
                    newStats.put(st, newStats.get(st) + (int) (g.stats.get(st)));
                }
            } else {
                //chose not to reforge this piece
                //factor in all stats
                for (Stat st : g.stats.keySet()) {
                    newStats.put(st, newStats.get(st) + (int) (g.stats.get(st)));
                }
            }
        }


        //weight newStats
        double totalWeight = 0.0;
        for (Stat st : newStats.keySet()) {
            if (st == Stat.HIT) {
                final int hitRating = newStats.get(Stat.HIT);
                //Ability hit
                if (hitRating <= ABILITY_HIT_CAP) {
                    totalWeight += hitRating * statWeights.get(Stat.ABILITY_HIT);
                } else {
                    totalWeight += ABILITY_HIT_CAP * statWeights.get(Stat.ABILITY_HIT);
                    //Spell hit
                    if (hitRating <= 315) {
                        totalWeight += (hitRating - ABILITY_HIT_CAP) * statWeights.get(Stat.SPELL_HIT);
                    } else {
                        totalWeight += (SPELL_HIT_CAP - ABILITY_HIT_CAP) * statWeights.get(Stat.SPELL_HIT);
                        //White hit
                        if (hitRating <= 777) {
                            totalWeight += (hitRating - SPELL_HIT_CAP) * statWeights.get(Stat.WHITE_HIT);
                        } else {
                            totalWeight += (WHITE_HIT_CAP - SPELL_HIT_CAP) * statWeights.get(Stat.WHITE_HIT);
                        }
                    }
                }
            } else {
                totalWeight += newStats.get(st) * statWeights.get(st);
            }
        }

        final CalculationResult result = new CalculationResult(newStats, totalWeight);

        return result;
    }

    private static class CalculationResult {

        final LinkedHashMap<Stat, Integer> newStats;
        final double totalWeight;

        CalculationResult(LinkedHashMap<Stat, Integer> newStats, double totalWeight) {
            this.newStats = newStats;
            this.totalWeight = totalWeight;
        }
    }

    private static boolean cycleReforgeOrder(int level, LinkedHashMap<Slot, ReforgeOrder> reforgeOrders, LinkedHashMap<Slot, LinkedHashSet<ReforgeOrder>> allReforgeOrders) {
        //is this the first iteration?
        if (reforgeOrders.isEmpty()) {
            for (Slot sl : allReforgeOrders.keySet()) {//set first combination to try
                reforgeOrders.put(sl, allReforgeOrders.get(sl).toArray(new ReforgeOrder[0])[0]);
            }
            return true;
        }

        //does this level exist?
        final Slot[] slots = reforgeOrders.keySet().toArray(new Slot[0]);
        if (level >= slots.length) {
            return false;
        }
        final Slot sl = slots[level];//slot this level represents

        ReforgeOrder finalOrder = null;
        {
            final Iterator<ReforgeOrder> i = allReforgeOrders.get(sl).iterator();
            while (i.hasNext()) {
                finalOrder = i.next();
            }
        }

        if (reforgeOrders.get(sl).equals(finalOrder)) {//is this level at max?
            final boolean isNextLevel = cycleReforgeOrder(level + 1, reforgeOrders, allReforgeOrders);//inc the next level
            if (isNextLevel) {
                reforgeOrders.put(sl, allReforgeOrders.get(sl).toArray(new ReforgeOrder[0])[0]);//set to min
                return true;
            } else {
                return false;
            }
        } else {
            //set to next
            final Iterator<ReforgeOrder> i = allReforgeOrders.get(sl).iterator();
            while (i.hasNext()) {
                if (reforgeOrders.get(sl).equals(i.next())) {
                    reforgeOrders.put(sl, i.next());
                    break;
                }
            }
            return true;
        }
    }

    private static LinkedHashMap<Slot, LinkedHashSet<ReforgeOrder>> assembleReforgeOrders() {
        //This function filters out always-inferior reforge-orders in order to cut down the number of combinations that need to be tested
        final LinkedHashMap<Slot, LinkedHashSet<ReforgeOrder>> allReforgeOrders = new LinkedHashMap();
        final Stat _2ndBestStat = statWeights.keySet().toArray(new Stat[0])[1];
        final Stat _3rdBestStat = statWeights.keySet().toArray(new Stat[0])[2];
        for (Slot sl : gear.keySet()) {
            final Gear g = gear.get(sl);
            final LinkedHashSet<ReforgeOrder> viableReforgeOrders = new LinkedHashSet();
            final boolean hasHit = g.stats.containsKey(Stat.HIT);
            final boolean has2ndBestStat = g.stats.containsKey(_2ndBestStat);
            final boolean has3rdBestStat = g.stats.containsKey(_3rdBestStat);
            if (hasHit) {
                if (has2ndBestStat) {
                    viableReforgeOrders.add(new ReforgeOrder(Stat.HIT, _3rdBestStat));
                    viableReforgeOrders.add(new ReforgeOrder());//leave alone
                } else {//!has2ndBestStat
                    viableReforgeOrders.add(new ReforgeOrder(Stat.HIT, _2ndBestStat));
                    Stat otherStat = null;
                    for (Stat st : g.stats.keySet()) {
                        if (st != Stat.HIT) {
                            otherStat = st;
                            break;
                        }
                    }
                    if (otherStat == null) {//no other stat
                        viableReforgeOrders.add(new ReforgeOrder());//leave alone
                    } else {
                        viableReforgeOrders.add(new ReforgeOrder(otherStat, _2ndBestStat));
                    }
                }
            } else {//!hasHit
                //Reforge each stat to HIT
                for (Stat st : g.stats.keySet()) {
                    viableReforgeOrders.add(new ReforgeOrder(st, Stat.HIT));
                }
                if (has2ndBestStat) {
                    if (has3rdBestStat) {
                        viableReforgeOrders.add(new ReforgeOrder());//leave alone
                    } else {//!has3rdBestStat
                        Stat otherStat = null;
                        for (Stat st : g.stats.keySet()) {
                            if (st != _2ndBestStat) {
                                otherStat = st;
                                break;
                            }
                        }
                        if (otherStat == null) {//no other stat
                            viableReforgeOrders.add(new ReforgeOrder());//leave alone
                        } else {
                            viableReforgeOrders.add(new ReforgeOrder(otherStat, _3rdBestStat));
                        }
                    }
                } else {//!has2ndBestStat
                    //Figure out which stat should be reforged into 2ndBestStat
                    final Stat betterStat;
                    final Stat worseStat;
                    final Stat[] stats = g.stats.keySet().toArray(new Stat[0]);
                    if (stats.length == 1) {//no other stat
                        viableReforgeOrders.add(new ReforgeOrder(stats[0], _2ndBestStat));
                    } else {
                        if (statWeights.get(stats[0]) >= statWeights.get(stats[1])) {
                            betterStat = stats[0];
                            worseStat = stats[1];
                        } else {
                            betterStat = stats[1];
                            worseStat = stats[0];
                        }
                        if (Math.ceil(0.60 * g.stats.get(worseStat)) * statWeights.get(worseStat) + Math.floor(0.40 * g.stats.get(worseStat)) * statWeights.get(_2ndBestStat)
                                >= Math.ceil(0.60 * g.stats.get(betterStat)) * statWeights.get(betterStat) + Math.floor(0.40 * g.stats.get(betterStat)) * statWeights.get(_2ndBestStat)) {
                            viableReforgeOrders.add(new ReforgeOrder(worseStat, _2ndBestStat));
                        } else {
                            viableReforgeOrders.add(new ReforgeOrder(betterStat, _2ndBestStat));
                        }
                    }
                }
            }
            allReforgeOrders.put(sl, viableReforgeOrders);
        }//end gear loop
        return allReforgeOrders;
    }

    private static class ReforgeOrder {

        final boolean leaveAlone;
        final Stat oldStat;
        final Stat newStat;

        ReforgeOrder(Stat oldStat, Stat newStat) {
            leaveAlone = false;
            this.oldStat = oldStat;
            this.newStat = newStat;
        }

        ReforgeOrder() {
            leaveAlone = true;
            this.oldStat = null;
            this.newStat = null;
        }
    }

    private static class Gear {

        final LinkedHashMap<Stat, Integer> stats = new LinkedHashMap();
    }

    private enum Slot {

        HEAD, NECK, SHOULDER, BACK, CHEST, WRIST,
        HANDS, WAIST, LEGS, FEET, RING1, RING2, TRINKET1, TRINKET2,
        MAINHAND, OFFHAND, RELIC;
    }

    private enum Stat {

        HIT, HASTE, CRIT, MASTERY, EXPERTISE,
        ABILITY_HIT, SPELL_HIT, WHITE_HIT;
    }

    private enum BaseStat {

        EXPERTISE_PCT, ABILITY_HIT_PCT, SPELL_HIT_PCT, WHITE_HIT_PCT;
    }
}

Last edited by Nyxxie : 10/17/10 at 6:52 PM.

Offline
Old 10/17/10, 6:46 PM   #162
Theogrim
Glass Joe
 
Dwarf Rogue
 
Khadgar (EU)
Nyxxie, you've got to take into account gems and enchants too, which can change to make room for more hit reforging, for example.

Offline
Old 10/17/10, 6:52 PM   #163
Nyxxie
Glass Joe
 
Blood Elf Death Knight
 
Lightninghoof
Originally Posted by Theogrim View Post
Nyxxie, you've got to take into account gems and enchants too, which can change to make room for more hit reforging, for example.
Oh yeah. The user is supposed to set those up in the baseStats variable, which unfortunately doesn't tie into the rest of the program yet.

For my own reforging purposes, I worked around it by lowering the ABILITY_HIT_CAP constant by however many points of hit rating I had already gemmed or enchanted for.

What'd be best is if this program could also tell you which chants and gems to use in combination with reforging in order to get your hit, but that might be a little more complicated than what I'm willing to get into.

Offline
Old 10/17/10, 11:22 PM   #164
Destrùctor
Glass Joe
 
Orc Death Knight
 
Archimonde
I am sure answer is somewhere in this thread but I could not seem to find it, does the "believed" haste cap include Windfury/Improved Icy Talons?

And how close are we at finding the actual haste cap?

-

Offline
Old 10/18/10, 7:28 AM   #165
Sahlia
Von Kaiser
 
Human Death Knight
 
Zuluhed (EU)
Wouldn't it always make sense to enchant 15 strength on hands?

It would purely come down to the question: is 15 strength better than 20 crit(!!)? As all stat weights show, this is always the case. That extra hit would come from reforging crit to hit or by simply reforging crit to haste instead of hit to haste. I see endless possibilities, why 15 strength on hands is better.

Last edited by Sahlia : 10/18/10 at 5:04 PM.

Offline
Closed Thread

Go Back   Elitist Jerks » Class Mechanics » Death Knights

Thread Tools