Hello all, I'm wondering if anyone's tried the simulator and varied up the sample rotation I put? I'd like people to test to see if the script needs additional features in order for you to write your rotations. Also if there are any bugs or inconsistencies in the way it handles more complex priority lists.
Furthermore, here is the source code for the "UI". As you can see it is extremely simple. Should people want to create their own graphical UI I welcome you to do so - all you need are hooks to the engine and parser's events and you're good to go. It simply isn't a big focus for me because the goal is to output the raw data people need to come to their own conclusions - if you want to use a graphic interface, if you want to export it to mathematica and do statistical analysis, go right ahead!
Simply reference the needed dll (SimFF.dll and SimFF.Script.dll) and you're golden.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using SimFF;
using SimFF.Script;
using System.IO;
using System.Diagnostics;
namespace SimFF.UI
{
static class Program
{
static Engine eg;
static Stopwatch timer;
static StreamWriter sw;
static TextWriter ow;
static Boolean hasOutput;
static double dps;
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
// print some menu crap (pshhhhh)
Console.WriteLine("SimFF v0.4 (2015-06-30 release) (c) Cheng Chen");
Console.WriteLine("Please view the README for license information.\n\n\n");
Console.Write("Enter input script file: ");
String input = Console.ReadLine();
// setup grammar
FFParser p = new FFParser();
// parse the script file
p.Parse(input);
// get our engine
eg = p.Context.Engine;
// setup timer
timer = new Stopwatch(); // trial time
Stopwatch timer2 = new Stopwatch(); // total time
// setup vars
dps = 0;
// attach handlers
if (eg.Diagnostic)
{
// only attach detailed handlers if diagnostic mode is on
// slows down performance drastically - will also output all
eg.RegisterDamageHandler(DamageHandler);
eg.RegisterAuraHandler(AuraHandler);
eg.RegisterAuraEndHandler(AuraEndHandler);
}
eg.RegisterTrialStartHandler(TrialStartHandler);
eg.RegisterTrialEndHandler(TrialEndHandler);
Console.WriteLine("Starting{1}Simulation ({0} Trials)\n\n", (eg.Diagnostic? 1 : eg.Trials), (eg.Diagnostic? " Diagnostic " : " "));
// setup output
FileStream fs = null;
sw = null;
ow = null;
hasOutput = (p.Context.Output != null && p.Context.Output.Length > 0);
if (hasOutput)
{
fs = new FileStream(p.Context.Output, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
ow = Console.Out;
Console.SetOut(sw);
}
// init and run
timer.Start();
eg.Run();
timer.Stop();
//cleanup
if (hasOutput)
{
Console.SetOut(ow);
sw.Close();
fs.Close();
}
//print end stuff
Console.WriteLine("\nSimulation Complete {0} Trials. Time taken: {1}", eg.Trials, timer.Elapsed);
// pause before program exit
Console.ReadLine();
}
static void TrialStartHandler(TrialEventArgs e)
{
//
}
static void TrialEndHandler(TrialEventArgs e)
{
Console.WriteLine("Trial {0}: {3} dps\t{1} damage", e.TrialNumber, e.Damage, timer.Elapsed, e.Damage/e.Duration);
dps += e.Damage / e.Duration;
//print to console if output file
if(hasOutput)
{
Console.SetOut(ow);
Console.Write("\rRunning Trial {0} ({1}ms elapsed)\tAvg DPS {2}", e.TrialNumber, timer.ElapsedMilliseconds, (dps/e.TrialNumber).ToString("#.##"));
Console.SetOut(sw);
}
}
static void DamageHandler(DamageEventArgs e)
{
Console.Write("[{0}]{4}\t{1}\t({2}{3})\n", eg.Time.ToString("#0.00"), e.Spell, e.Damage.ToString("#0.00"), (e.Crit ? "!" : ""), (e.Spell[e.Spell.Length - 1] == ')' || e.Spell.IndexOf("Autoattack") >= 0 ? "\t" : ""));
}
static void AuraHandler(AuraEventArgs e)
{
// discard system events
if (e.Aura.Spell[0] == 'Z')
return;
Console.Write("[{0}]\t\t\t{1} applied to {2}\t({3}sec)\n", eg.Time.ToString("#0.00"), e.Aura.Spell, e.Target.Name, e.Aura.Duration);
}
static void AuraEndHandler(AuraEventArgs e)
{
// discard system events
if (e.Aura.Spell[0] == 'Z')
return;
Console.Write("[{0}]\t\t\t{1} on {2} ends\n", eg.Time.ToString("#0.00"), e.Aura.Spell, e.Target.Name);
}
}
}
EDIT: I will attempt to put in the new lvl 60 formulas at some point today, though I am working on other tweaks at the moment. I am also pretty caught up in fourth of july stuff with friends and family, so likely not much work will be done until next week. Have a safe holiday.