private static ExcelHyperLink CreateUserSheet(ExcelWorkbook wb, Members user, ExtendedStats exdata, ExcelWorksheet details) { var ws = wb.Worksheets.Add($"{user.playerServer}_{user.playerName}"); var rgc = new RaceGenderClass("Common", "Common", user.playerClass); ws.DefaultRowHeight = 30; ws.Cells.Style.Font.Size = 14; ws.Cells.Style.Font.Name = "Arial"; AddImage(ws, 1, 1, ClassIcons.Instance.GetBitmap((PlayerClass) Enum.Parse(typeof(PlayerClass), user.playerClass))); ws.Cells[1, 2].Value = $"{user.playerServer}: {user.playerName}"; ws.Cells[1, 2, 1, 11].Merge = true; ws.Cells[1, 2, 1, 11].Style.Font.Bold = true; ws.Cells[2, 2].Value = LP.SkillName; ws.Cells[2, 3].Value = LP.DamagePercent; ws.Cells[2, 4].Value = LP.Damage; ws.Cells[2, 5].Value = LP.CritPercent; ws.Cells[2, 6].Value = LP.Hits; ws.Cells[2, 7].Value = LP.Crits; ws.Cells[2, 8].Value = LP.MaxCrit; ws.Cells[2, 9].Value = LP.MinCrit; ws.Cells[2, 10].Value = LP.AverageCrit; ws.Cells[2, 11].Value = LP.AvgWhite; var i = 2; foreach (var stat in exdata.PlayerSkillsAggregated[user.playerServer+"/"+user.playerName].OrderByDescending(x => x.Amount())) { i++; ws.Cells[i, 1].Value = i - 2; foreach (var skillInfo in stat.Skills) { if (string.IsNullOrEmpty(skillInfo.Key.IconName)) continue; AddImage(ws, i, 1, BTD.Icons.GetBitmap(skillInfo.Key.IconName)); break; } ws.Cells[i, 2].Value = stat.Name; ws.Cells[i, 3].Value = stat.DamagePercent() / 100; ws.Cells[i, 3].Style.Numberformat.Format = "0.0%"; ws.Cells[i, 4].Value = stat.Amount(); ws.Cells[i, 4].Style.Numberformat.Format = @"#,#0,\k"; ws.Cells[i, 5].Value = stat.CritRate() / 100; ws.Cells[i, 5].Style.Numberformat.Format = "0.0%"; ws.Cells[i, 6].Value = stat.Hits(); ws.Cells[i, 7].Value = stat.Crits(); ws.Cells[i, 8].Value = stat.BiggestCrit(); ws.Cells[i, 8].Style.Numberformat.Format = @"#,#0,\k"; ws.Cells[i, 9].Value = stat.LowestCrit(); ws.Cells[i, 9].Style.Numberformat.Format = @"#,#0,\k"; ws.Cells[i, 10].Value = stat.AvgCrit(); ws.Cells[i, 10].Style.Numberformat.Format = @"#,#0,\k"; ws.Cells[i, 11].Value = stat.AvgWhite(); ws.Cells[i, 11].Style.Numberformat.Format = @"#,#0,\k"; } var border = ws.Cells[1, 1, i, 11].Style.Border; border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick; ws.Cells[2, 1, i, 11].AutoFilter = true; var j = i + 3; ws.Cells[j, 2].Value = LP.Name; ws.Cells[j, 2, j, 10].Merge = true; ws.Cells[j, 11].Value = "%"; ws.Cells[j, 2, j, 11].Style.Font.Bold = true; foreach (var buf in user.buffUptime) { j++; var hotdot = BTD.HotDotDatabase.Get(int.Parse(buf.Key)); ws.Cells[j, 1].Value = j - i - 3; AddImage(ws, j, 1, BTD.Icons.GetBitmap(hotdot.IconName)); ws.Cells[j, 2].Value = hotdot.Name; if (!string.IsNullOrEmpty(hotdot.Tooltip)) ws.Cells[j, 2].AddComment("" + hotdot.Tooltip, "info"); ws.Cells[j, 2, j, 10].Merge = true; ws.Cells[j, 11].Value = double.Parse(buf.Value) / 100; ws.Cells[j, 11].Style.Numberformat.Format = "0%"; if (!string.IsNullOrEmpty(hotdot.ItemName)) ws.Cells[j, 10].AddComment("" + hotdot.ItemName, "info"); } border = ws.Cells[i + 3, 1, j, 11].Style.Border; border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick; AddCharts(ws, exdata, details, j); ws.Column(1).Width = 5.6; ws.Column(2).AutoFit(); ws.Column(3).AutoFit(); ws.Column(4).AutoFit(); ws.Column(5).AutoFit(); ws.Column(6).AutoFit(); ws.Column(7).AutoFit(); ws.Column(8).AutoFit(); ws.Column(9).AutoFit(); ws.Column(10).AutoFit(); ws.Column(11).AutoFit(); ws.Column(2).Width = GetTrueColumnWidth(ws.Column(2).Width * scale); ws.Column(3).Width = GetTrueColumnWidth(ws.Column(3).Width * scale); ws.Column(4).Width = GetTrueColumnWidth(ws.Column(4).Width * scale); ws.Column(5).Width = GetTrueColumnWidth(ws.Column(5).Width * scale); ws.Column(6).Width = GetTrueColumnWidth(ws.Column(6).Width * scale); ws.Column(7).Width = GetTrueColumnWidth(ws.Column(7).Width * scale); ws.Column(8).Width = GetTrueColumnWidth(ws.Column(8).Width * scale); ws.Column(9).Width = GetTrueColumnWidth(ws.Column(9).Width * scale); ws.Column(10).Width = GetTrueColumnWidth(ws.Column(10).Width * scale); ws.Column(11).Width = GetTrueColumnWidth(ws.Column(11).Width * scale); ws.Cells[1, 1, j, 11].Style.VerticalAlignment = ExcelVerticalAlignment.Center; ws.Cells[1, 1, j, 11].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; ws.PrinterSettings.FitToPage = true; // I don't know why, but sometimes column height setting is lost. for (var x = 1; x <= j; ++x) { ws.Row(x).CustomHeight = true; ws.Row(x).Height = 30; } // If sheet name contains space character, name should be enclosed in single quotes. return new ExcelHyperLink($"'{user.playerServer}_{user.playerName}'!A1", $"{user.playerServer}: {user.playerName}"); }
private static ExtendedStats GenerateStats(NpcEntity entity, AbnormalityStorage abnormals) { if (!entity.Info.Boss) return null; var timedEncounter = false; /* modify timedEncounter depending on teradps.io need */ var entityInfo = Database.Database.Instance.GlobalInformationEntity(entity, timedEncounter); var skills = Database.Database.Instance.GetSkills(entityInfo.BeginTime, entityInfo.EndTime); var playersInfo = timedEncounter ? Database.Database.Instance.PlayerDamageInformation(entityInfo.BeginTime, entityInfo.EndTime) : Database.Database.Instance.PlayerDamageInformation(entity); var heals = Database.Database.Instance.PlayerHealInformation(entityInfo.BeginTime, entityInfo.EndTime); playersInfo.RemoveAll(x => x.Amount == 0); var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var interTick = lastTick - firstTick; var interval = interTick/TimeSpan.TicksPerSecond; if (interval == 0) { return null; } var totaldamage = entityInfo.TotalDamage; var partyDps = TimeSpan.TicksPerSecond*totaldamage/interTick; var teradpsData = new EncounterBase(); var extendedStats = new ExtendedStats(); var _abnormals = abnormals.Clone(entity, firstTick, lastTick); teradpsData.encounterUnixEpoch = new DateTimeOffset(new DateTime(lastTick,DateTimeKind.Utc)).ToUnixTimeSeconds(); extendedStats.Entity = entity; extendedStats.BaseStats = teradpsData; extendedStats.FirstTick = firstTick; extendedStats.LastTick = lastTick; teradpsData.areaId = entity.Info.HuntingZoneId + ""; teradpsData.bossId = entity.Info.TemplateId + ""; teradpsData.fightDuration = interval + ""; teradpsData.partyDps = partyDps + ""; extendedStats.Debuffs = _abnormals.Get(entity); foreach (var debuff in extendedStats.Debuffs.OrderByDescending(x => x.Value.Duration(firstTick, lastTick))) { var percentage = debuff.Value.Duration(firstTick, lastTick)*100/interTick; if (percentage == 0) { continue; } teradpsData.debuffUptime.Add(new KeyValuePair<string, string>( debuff.Key.Id + "", percentage + "" )); } foreach (var user in playersInfo.OrderByDescending(x=>x.Amount)) { var teradpsUser = new Members(); var damage = user.Amount; teradpsUser.playerTotalDamage = damage + ""; if (damage <= 0) { continue; } var buffs = _abnormals.Get(user.Source); teradpsUser.playerClass = user.Source.Class.ToString(); teradpsUser.playerName = user.Source.Name; teradpsUser.playerServer = BasicTeraData.Instance.Servers.GetServerName(user.Source.ServerId); teradpsUser.playerAverageCritRate = Math.Round(user.CritRate, 1) + ""; teradpsUser.healCrit = user.Source.IsHealer ? heals.FirstOrDefault(x => x.Source == user.Source)?.CritRate + "" : null; teradpsUser.playerDps = TimeSpan.TicksPerSecond*damage/interTick + ""; teradpsUser.playerTotalDamagePercentage = user.Amount*100/entityInfo.TotalDamage + ""; extendedStats.PlayerReceived.Add(user.Source.Name, Tuple.Create(skills.HitsReceived(user.Source.User, entity, timedEncounter), skills.DamageReceived(user.Source.User, entity, timedEncounter))); var death = buffs.Death; teradpsUser.playerDeaths = death.Count(firstTick, lastTick) + ""; teradpsUser.playerDeathDuration = death.Duration(firstTick, lastTick)/TimeSpan.TicksPerSecond + ""; var aggro = buffs.Aggro(entity); teradpsUser.aggro = 100*aggro.Duration(firstTick, lastTick)/interTick + ""; foreach (var buff in buffs.Times.OrderByDescending(x=>x.Value.Duration(firstTick, lastTick))) { var percentage = buff.Value.Duration(firstTick, lastTick)*100/interTick; if (percentage == 0) { continue; } teradpsUser.buffUptime.Add(new KeyValuePair<string, string>( buff.Key.Id + "", percentage + "" )); } var serverPlayerName = $"{teradpsUser.playerServer}_{teradpsUser.playerName}"; extendedStats.PlayerSkills.Add(serverPlayerName, skills.GetSkillsDealt(user.Source.User, entity, timedEncounter)); extendedStats.PlayerBuffs.Add(serverPlayerName, buffs); var skillsId = SkillAggregate.GetAggregate(user, entityInfo.Entity, skills, timedEncounter, Database.Database.Type.Damage); extendedStats.PlayerSkillsAggregated[teradpsUser.playerServer + "/" + teradpsUser.playerName] = skillsId; foreach (var skill in skillsId.OrderByDescending(x=>x.Amount())) { var skillLog = new SkillLog(); var skilldamage = skill.Amount(); skillLog.skillAverageCrit = Math.Round(skill.AvgCrit()) + ""; skillLog.skillAverageWhite = Math.Round(skill.AvgWhite()) + ""; skillLog.skillCritRate = skill.CritRate() + ""; skillLog.skillDamagePercent = skill.DamagePercent() + ""; skillLog.skillHighestCrit = skill.BiggestCrit() + ""; skillLog.skillHits = skill.Hits() + ""; var skillKey = skill.Skills.First().Key; skillLog.skillId= BasicTeraData.Instance.SkillDatabase.GetSkillByPetName(skillKey.NpcInfo?.Name, user.Source.RaceGenderClass)?.Id.ToString() ?? skillKey.Id.ToString(); skillLog.skillLowestCrit = skill.LowestCrit() + ""; skillLog.skillTotalDamage = skilldamage + ""; if (skilldamage == 0) { continue; } teradpsUser.skillLog.Add(skillLog); } teradpsData.members.Add(teradpsUser); } return extendedStats; }