I was thinking about the event driven system, which I assume is some sort of linked list. How would you handle the searching, add/delete, and reordering of the event queue possibly more than once for each event? For example if you crit and gain flurry, you have to add an event at the correct time for flurry to fade, possibly delete an old flurry fade time, and adjust the swing time of both weapons plus any procs that happened on the hit.
This is what I have done. I have an eventnode which represents one tick(0.01s). There can be many events in one eventnode. Events are separated in 3 categories: high priority events, low priority events and auto attack swings. If there are all of those events in one tick, high priority events are executed first(cooldowns mostly), then auto attacks and then low priority events(buff fades etc.).
So when I add and event, I first search the eventnode linked list for the right spot and make a new eventnode. Sometimes I don't have to make a new one because there is already an eventnode for that particular tick. Then I add the event to the eventnode and thats it.
About the flurry example. I do not delete the old fade time. I handle it internally in my talent, skill etc. classes with one varialbe which is proc_stack_. It is increased every time there is a fade event added to event queue and decreased every time the fade event is executed. When it reaches 0, I know its time to actually take off the buff. (In my sim, I don't actually model flurry buff time...it is not possible for it to fade in sim with current weapon speeds. It would slower the sim).
About haste in mid-swing...my auto attack events are actually just boolean values in every eventnode. I keep a pointer to next auto attack eventnode, so I can cancel the auto attack if needed and make a new onw.
Then to the proccing system. I have arrays for every possible proc event. For example mh hit, mh crit, oh swing, spell hit, stormstrike. Before the sim, I register the procs to these arrays. When mh hit happens, the mh hit array is went through and the procs are executed.
That was bit about the insides of my sim. Hope it helps someone to design his own.
I have a list, where I put everything in with a timestamp and then sort it. No need for ticks, nodes or roundings. Just handle the next event.
Haste changes aren't that elegant, but they don't happen very often anyways. Search for the autoattack and change the time accordingly.
Sorting is too slow to be done each time you add a new event. A better approach would be to search for the correct insertion point, and place the event there by relinking, if you're using a doubly-linked list, which I think that's what you meant by "list". If you keep track of a few nice reference events in that list - like the last event added, next swing - they become very nice starting points for you search, making the whole event handling thing a set of very fast operations.
For haste changes, since you were already keeping track of the next swing event, you'd simply have to relink it again at the correct position in the list. All of these events should be fairly close together, making this also a very fast and clean operation, with very little searching. All you have to do is, starting at the next swing iterator/pointer, search backwards until you find the place you should be inserted, unlink from current position and relink there.
If you don't want to keep track of these reference points, you can use some simple logic to find the place to start your search for insertion point. For example, if the event will happen in less than 10secs start from the head of the list, otherwise start from the end. So for example, for long cooldowns, it would be fairly obvious that most likely they would be at the tail of the list, instead of at the start where all the "cool" stuff is happening. This will still be much faster than sorting.
Originally Posted by dr_tukez
Your way is cleaner, although I think my way is faster, because there is no sorting. But can't really say for sure until it's done.
Cleaner is just a matter of how well things are encapsulated. You can provide a very clean interface to a very bloated and ugly implementation that nobody has to look at, as long as this interface is clean and well (self)documented. When you're writing time-critical code, you can't rely on it being beautiful and the most efficient at the time. Sometimes you can make a little trade-off, for all the other times, you just have to encapsulate it behind some class that hides all the "dirty" details from the rest of the code in your project.
Sorting is too slow to be done each time you add a new event. A better approach would be to search for the correct insertion point, and place the event there by relinking, if you're using a doubly-linked list, which I think that's what you meant by "list".
I have been optimizing my event queue a bit.
My first system I already explained. On that system I did a linear seach from the beginning of the list and I recored how many nodes I had to pass to find the correct place. It was about 11 if I remember right.
I tried a lot of different systems, at least map, heap, binary tree and none were faster than my system. Then I dropped the eventnode idea and placed every event as own node in the list. I also made it double linked list so I could remove nodes easily. This change made it already faster than the old system and avg nodes passed was about 8, starting the search from beginning.
Then I tried to set a constant treshold to decide where to start the search, start or end. It improved the performance too and the avg node passed was just under 6. Then I figured that I could record the last inserted node, start the search from that point, to start or to end. This increased performance a bit too and avg nodes passed decreased to under 4.
I remember you had posted some suggestions to do the event queue and came back to read it again...and Dang! You had suggested everything I tried, which made some improvements. Do you have any other good ideas?
Took the time and made it WotLK compatible/only. Now I can start with the interesting part, the simulation. The addon provides a big need for stuff like this.
I just don't know what to show in the DPS window, besides damage distribution or proc uptimes.
I also wonder if I get any usable feedback here .
Wouldn't it be 35% for Lv73/83 bosses? %Reduction = (Armor / ([467.5 * Enemy_Level] + Armor - 22167.5)) * 100
I believe the 'Enemy_Level' variable is the attacker, not the target, as per PaperDollFrame.lua.
function PaperDollFrame_GetArmorReduction(armor, attackerLevel)
local levelModifier = attackerLevel;
if ( levelModifier > 59 ) then
levelModifier = levelModifier + (4.5 * (levelModifier-59));
local temp = 0.1*armor/(8.5*levelModifier + 40);
temp = temp/(1+temp);
if ( temp > 0.75 ) then
if ( temp < 0 ) then
return format("%.2f", (temp*100));
I used the official holiday (in germany) on friday to do some maths about PvE Fury warrior. I tried to put as much knowledge into as I could but there are some points I'm not sure about - they are marked yellow. So this is not the final version . But I think here in this forum is the best place to put the file online and to get some productive discussion and help on it.
The Excel-Sheet includes:
You can compare some talents and 2x1-hand vs. 2x2-hand. You can insert yout stats and the stats of your 2x2-hand vs. 2x1-hand weapons.
To view the results you must scroll down a little ^^
-> For all sceptic: It shows quite easy that TG is an DPS increase, on paper.