Jump to content

Recommended Posts

Posted
1 hour ago, Carnifax said:

Do really wish all Procs logged like pet powers do, as a subpower of the main power. It'd make our lives so much easier here (procs in the pet / patches do, just wish it did the same thing for stuff like Freezing Touch). 

I have a thread for logging suggestions. The problem is that procs fires are odd side effects of damage. They come from different code sections which don't have power details.

 

1 hour ago, Carnifax said:

But I'd love to see your DPS calc code if you wouldn't mind because my graphs always end up the same way and your figures look way more correct (this is from a Yin I was just on)

It's a bit complicated, but here is the basics. Note, you can use Sqlite Studio to look at database in the output directory.
It starts with this view:

Spoiler

select

da1.summary_key,

da1.line_number,

da1.log_date,

da1.damage as damage,

(CASE

WHEN

ROUND(((julianday((select da2.log_date from damage_action da2 where da1.summary_key = da2.summary_key AND da2.line_number > da1.line_number limit 1)) - julianday(da1.log_date)) * 86400)) IS NULL

THEN 1000000

ELSE

ROUND(((julianday((select da2.log_date from damage_action da2 where da1.summary_key = da2.summary_key AND da2.line_number > da1.line_number limit 1)) - julianday(da1.log_date)) * 86400))

END)

as delta

from damage_action da1

where da1.source_type IN ('Player', 'PlayerPet')

order by da1.summary_key

 

You get a table of damage points with the time delta from the next point. Then group by time delta depending on the configured interval.

https://github.com/PaulBenHill/cyclops/blob/master/src/db/queries.rs

Spoiler

pub fn get_damage_intervals_query(
    conn: &mut SqliteConnection,
    key: i32,
    interval: i32,
) -> Vec<Vec<DamageIntervals>> {
    use crate::schema::damage_intervals::dsl::*;

    let intervals: Vec<DamageIntervals> = damage_intervals
        .filter(summary_key.eq(key))
        .load(conn)
        .expect("Unable to load damage intervals");

    let mut result: Vec<Vec<DamageIntervals>> = Vec::new();
    let mut current_interval: Vec<DamageIntervals> = Vec::new();

    for i in intervals {
        current_interval.push(i.to_owned());
        if i.delta >= interval {
            result.push(current_interval);
            current_interval = Vec::new();
        }
    }
    if !current_interval.is_empty() {
        result.push(current_interval);
    }

    result
}

 

Then there is some addition to code to total up the damage, calculate the elapsed time, end lines, and then dps.

https://github.com/PaulBenHill/cyclops/blob/master/src/web/dps_interval_table.rs

Spoiler

fn generate_dps_report(context: &AppContext, query: &TableQuery) -> Vec<Interval> {
    let mut conn1 = db::get_file_conn(query.db_path.clone().into());
    let binding = db::queries::get_summary(&mut conn1, query.key);
    let summary = binding.get(0).unwrap();
    let mut conn2 = db::get_file_conn(query.db_path.clone().into());
    let damage_intervals =
        db::queries::get_damage_intervals_query(&mut conn2, query.key, context.dps_interval as i32);
    let line_count = summary.last_line_number - summary.first_line_number;

    let mut result = Vec::<Interval>::new();

    for intervals in damage_intervals {
        let first_interval = intervals.first().unwrap();
        let last_interval = intervals.last().unwrap();

        let mut end_line: i32 = 0;
        if end_line < line_count {
            end_line = last_interval.line_number;
        } else {
            end_line = line_count;
        }

        let total_damage: i32 = intervals.iter().map(|i| i.damage).sum();

        let elapsed_seconds = DateTime::parse_from_rfc3339(last_interval.log_date.as_str())
            .unwrap()
            .timestamp()
            - DateTime::parse_from_rfc3339(first_interval.log_date.as_str())
                .unwrap()
                .timestamp();
        if elapsed_seconds > 0 {
            let elapsed_duration = Duration::from_secs(elapsed_seconds as u64).as_secs();
            let pretty_elapsed = format!(
                "{} min(s) {} second(s)",
                elapsed_duration / 60,
                elapsed_duration % 60
            );

            let mut dps = total_damage as i64;
            if elapsed_seconds > 0 {
                dps = dps / elapsed_seconds;
            }

            result.push(Interval {
                start_line: first_interval.line_number,
                end_line: end_line,
                total_lines: intervals.len() as i32,
                elapsed_seconds: elapsed_seconds,
                pretty_elapsed: pretty_elapsed,
                total_damage: total_damage,
                dps: dps as i32,
            });
        }
    }

    result
}

 

 

It was one the first things I wrote in the tool, so it could use some refactoring. My SQL Fu wasn't good enough at the time to do more in the database layer.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...