Calculating Swift Slashes Extra Attacks

Introduction:

Like DotA's Yunero the Juggernaut, HoN's Swiftblade can perform a number of regular attacks during his ultimate, referred to as extra attacks. These attacks operate like any other regular attack: Attack and Exclusive modifiers are applied to the target, Swiftblade can critical strike the target, and Runed Axe splashes damage to nearby units.

The number of these regular attacks performed depend on the attack speed of Swiftblade. The higher his attack speed, the more extra attacks Swiftblade performs. The mechanics of Swift Slashes operates differently than Juggernaut's Omnislash (each Swift Slash not interrupting regular attacks, 20fps server limit, etc.), so the Omnislash table is not the correct graph to reference when determining the number of extra attacks performed.

Note that if you issue other commands during Swift Slashes (move, stop, attack, etc.), it will negatively affect the number of Swift Slashes performed. This formula and graph assumes you don't issue any other commands while Swift Slashing.

, where "RU" is the Roundup Function to the nearest 0.05 value and "RD" is the Rounddown Function to the nearest 0.05 value.

Determining Attack Speed:

To find Swiftblade's (or any unit's) current attack speed, hover the cursor over here:

And look here:

Graphs:

Because when asked, 98.7% of the population choose line graphs over algebra.

Explanation:

So I realize that simply posting the formula isn't going to be enough for my fellow HoN mechanics nerds, so here's step by step of how the formula works. The example I will be using is a level 25 Swiftblade with a 265 attack speed and his Swift Slashes maxed with Staff of the Master, granting him 10 slashes total.

Because each Swift Slash does not interrupt Swiftblade's normal attacks (extra attacks), the general idea of what I'm doing is calculating how many extra attacks can be performed during the entire duration of Swift Slashes.

Step 1: We'll start by getting the duration of Swift Slashes. resources\heroes\hiro\ability_hiro4.entity sets the duration of the first slash 400ms (0.4 seconds), and the same for each subsequent slash found in resources\heroes\hiro\affector_ability4.entity. We can therefore calculate the Swift Slashes duration in seconds as follows:

Where X = number of slashes performed,
Swift Slashes Duration = X*0.4

Example:10*0.4 = 4 seconds Swift Slashes duration

Step 2: Next we need to get Swiftblade's attack cooldown. I started by using the in-game displayed attack cooldown, but it just wasn't adding up with the other numbers. I found out that the in-game cooldown calculator does some goofy rounding, and as such, I needed to calculate the attack cooldown myself using Swiftblade's attack speed and his base attack time (attackcooldown in the resources file). Here's the formula:

We've still got one more step here. Because HoN operates at a 20fps server framerate, this cooldown is rounded up to the closest 0.05s.

Example: 1.7/(265*0.01) = 0.641509434, rounded up to 0.65

Step 3: Now the attack cooldown we just calculated is the complete time it takes to perform an entire attack, including animation backswing. However, the final attack doesn't need to complete the animation backswing; Swiftblade just needs to reach the damage point (referred to in HoN as attackactiontime). From the resources\heroes\hiro\hiro.entity file, we know that his base attackactiontime is 330. We can use his base attackactiontime in conjunction with his base attackcooldown and adjusted attack cooldown we just calculated in order to find his adjusted attackactiontime.

Again, we need to round this to the next 0.05 in order to comply with the framerate.

Example: 0.65*0.33/1.7 = 0.126176470, rounded up to 0.15

Step 4: Okay, we've got everything we need! Now for plugging them into the equation. We start by subtracting our adjusted attackactiontime from the total Swift Slashes duration, and adding 1 to our extra attack count for that. Even though that shortened duration applies to the last slash, we'll take it out at the beginning because it allows us to determine the number of full attacks that will fit in the rest of the duration.

Step 6: We then add the final attack, which we subtracted to get the adjusted duration, and that gives us the total number of extra attacks.

Total number of extra attacks = full extra attacks + final partial attack

Example:5 + 1 = 6 total extra attacks on a Swiftblade with 265 attack speed and 10 total attacks.

6 extra attacks, which after counting the slashes in slow motion, is correct!!

Verification:

I initially didn't take into account the fact that the game rounds each attack to the nearest 0.05 seconds, as Malle pointed out. I also was manually counting wrong, as Swiftblade will "drift" away from his target after the last slash and can perform extra attacks then, but not be in the effect of Swift Slashes. I found the easiest way to count extra attacks was at 10% game speed and with a Nullfire blade, as the mana burned appears on extra attacks but not the regular Swift Slashes.

Wow looks GREAT, I was just reading a thread somewhere asking for exactly this- very nicely laid out; love the colours (obviously I havn't tried to understand the mechanics behind it, but this is SURE to earn you a puzzlebox award, GJ!)

A link to a guide on how to calculate attack speed would be nice. That way you could figure out at level 6 and 11+ how to maximize your ult effectiveness. Though it looks like you won't be able to afford the needed items at those stages to jump from 2 to 3 or 3 to 4.

It's also debatable whether SotM is a good item on swiftblade. Maybe compare shieldbreaker's damage to SotM's.

Hehe, didn't think anyone would notice; had to do with Excel's automatic themes and how I selected the data from the spreadsheet.

Changelog:01-02-2009, 1:47 PM - Updated line graphs with more accurate data, calculating on every 1 attack speed instead of every 10. Linked to a large version of the graph for more accurate representation of extra attacks. Added zipped .xls spreadsheet of data to Thread Attachments.

Good work, but when you discarded the rounding the engine you added an error, which can be confirmed at, for instance, 480 attack speed. At that point, your model says 12 attacks, but the result is actually 10 attacks. (I did this test by modding the game files to print out every extra attack in console)

The game runs (by default, anyway) at 20 frames per second (in other words, intervals of .05 seconds) and everything, even attacks, can only be executed during a given frame. Thus, attack speed doesn't produce a continuous decrease in the time per attack but rather a discrete one (where the time per attack and time to action is rounded up to the closest integer amount of frames). See this thread for more information.

If you take the discrete nature of frames into account, everything seems to fit well and you get the following graphs:

I also tested with this how the action time was rounded and can confirm that it is calculated from the unrounded time per attack and not the rounded one. The effect wouldv'e been really small, differing only one attack on a small amount of the simulated attack speeds from 0 to 500, but this is the way it should be to be closer to the continuous case.

13^3

In my posts, cursive grey text indicates very detailed or less relevant information, while blue text highlights important points or conclusions.

I may have been a bit ambiguous: host_timescale shouldn't affect the result, but specifically changing the server frame rate only (I don't remember the command by heart) could possibly affect it, depending on how it is coded.

host_timescale shouldn't affect it since it can be seen as simply generating the frames at a slower rate, but each frame still does the exact same things as it would otherwise, which leads to the game running slower than normal.

13^3

In my posts, cursive grey text indicates very detailed or less relevant information, while blue text highlights important points or conclusions.

Thanks Malle for pointing out my lack of rounding-compliance. ElementUser, I'd update the post if you'd like to simplify it again, but don't feel obligated to by any means. I should do it myself, but you spoiled me. <3

In order to round up to the nearest 0.05 in excel, I had to use this work-around:

ROUNDUP((number I want rounded)/5, 2)*5

It takes the number I want rounded, divides it by 5, rounds up to the second digit after the decimal place, and multiplies it by 5. MROUND rounds to a multiple, but it rounds to the closest, not just rounding up like I need. If you can find a better way of doing it, let me know. :P