// Draws a report picture for each Match Player public byte[] DrawPlayerReport(DotaMatch match, MatchPlayers player) { var playerTeam = (player.team == 0) ? "Radiant" : "Dire"; var winState = ((playerTeam == match.winner) ? "Winner" : "Loser"); byte[] playerReportData = null; // 306:234 is split pane point using (var playerReport = Image.Load(this.assembly.GetManifestResourceStream($"OpenDotaApi.ref.assets.{playerTeam}.png"))) { playerReport.Mutate ( (imgContext) => { // Background Color // imgContext.Fill(Rgba32.Black); Image <Rgba32> boxBorder; // Drawing Pointers var x = 0; var y = 0; // Draw Player Text x = 20; y = 20; imgContext.DrawText( leftText, ((player.playerName != null) ? (player.playerName) : ""), verdanaTinyBold, Rgba32.White, new PointF(x, y) ); x = 286; imgContext.DrawText( rightText, $"{playerTeam} ({winState})", verdanaTiny, Rgba32.LightGray, new PointF(x, y) ); // Draw Hero Image x = 24; y = 56; boxBorder = new Image <Rgba32>(270, 154); boxBorder.Mutate(img => img.Fill(Rgba32.DarkSlateGray)); imgContext.DrawImage( boxBorder, 1, new Point((int)x - 2, (int)y - 2) ); Image <Rgba32> heroImage = null; var heroImagePath = $@"./imgcache/heroes/{player.hero.id}.png"; if (File.Exists(heroImagePath)) { heroImage = Image.Load(heroImagePath); heroImage.Mutate(img => img.Resize(266, 150)); } else { heroImage = new Image <Rgba32>(266, 150); heroImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32))); } imgContext.DrawImage( heroImage, 1, new Point(x, y) ); // Draw Player Hero Name x = 153; y = 226; imgContext.DrawText( centerText, $"{player.hero.name}", verdana, Rgba32.White, new PointF(x, y) ); // Draw Player Stats y = 262; imgContext.DrawText( centerText, player.netWorth.ToString(), verdanaBigBold, Rgba32.White, new PointF(x, y) ); y = 306; imgContext.DrawText( centerText, $@"KDA {player.kills} / {player.deaths} / {player.assists}", verdana, Rgba32.White, new PointF(x, y) ); // Draw Player Items x = 20; y = 346; boxBorder = new Image <Rgba32>(266, 136); boxBorder.Mutate(img => img.Fill(new Rgba32(64, 64, 64))); imgContext.DrawImage( boxBorder, 1, new Point((int)x, (int)y) ); for (var j = 0; j < 6; j++) { var item = player.items[j]; Image <Rgba32> itemImage = null; string itemImagePath; if (item != null) { itemImagePath = $@"./imgcache/items/{item.id}.png"; if (!File.Exists(itemImagePath)) { itemImage = new Image <Rgba32>(86, 65); itemImage.Mutate(img => img.Fill(Rgba32.DarkSlateGray)); } else { itemImage = Image.Load(itemImagePath); itemImage.Mutate(img => img.Resize(86, 65)); } } else { itemImage = new Image <Rgba32>(86, 65); itemImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32))); } imgContext.DrawImage( itemImage, 1, new Point((int)x + 2 + 88 * (j % 3), (int)y + 2 + 67 * (j / 3)) ); } // Draw Backpack Items x = 53; y = 480; boxBorder = new Image <Rgba32>(194, 49); boxBorder.Mutate(img => img.Fill(new Rgba32(48, 48, 48))); imgContext.DrawImage( boxBorder, 1, new Point((int)x, (int)y + 2) ); for (var j = 0; j < 3; j++) { var item = player.items[j + 6]; Image <Rgba32> itemImage = null; string itemImagePath; if (item != null) { itemImagePath = $@"./imgcache/items/{item.id}.png"; if (!File.Exists(itemImagePath)) { itemImage = new Image <Rgba32>(62, 47); itemImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20))); } else { itemImage = Image.Load(itemImagePath); itemImage.Mutate(img => img.Resize(62, 47)); } } else { itemImage = new Image <Rgba32>(62, 47); itemImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20))); } imgContext.DrawImage( itemImage, 1, new Point((int)x + 2 + 64 * (j % 3), (int)y + 2) ); } // Draw Permanent Buffs x = 153; y = 551; imgContext.DrawText( centerText, "PERMANENT BUFFS", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); if (player.permanentBuffs != null) { x = 20; y = 580; for (var j = 0; j < player.permanentBuffs.Length; j++) { var buff = player.permanentBuffs[j]; Image <Rgba32> buffImage = null; string buffImagePath; if (buff.buff.orgin == "Item") { buffImagePath = $@"./imgcache/items/{buff.buff.originId}.png"; } else { buffImagePath = $@"./imgcache/abilities/{buff.buff.originId}.png"; } if (!File.Exists(buffImagePath)) { buffImage = new Image <Rgba32>(42, 42); buffImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32))); } else { buffImage = Image.Load(buffImagePath); buffImage.Mutate(img => img.Crop(buffImage.Height, buffImage.Height).Resize(42, 42).Fill(new Rgba32(255, 255, 255, 64))); } var imgx = x + 3 + 44 * (j % 6); boxBorder = new Image <Rgba32>(44, 44); boxBorder.Mutate(img => img.Fill(Rgba32.Gold)); imgContext.DrawImage( boxBorder, 1, new Point((int)imgx - 1, (int)y - 1) ); imgContext.DrawImage( buffImage, 1, new Point((int)imgx, (int)y) ); imgContext.DrawText( centerMiddleText, buff.value.ToString(), verdanaTinyBold, Rgba32.Black, new Point((int)imgx + 21, (int)y + 21) ); } } else { y = 580; imgContext.DrawText( centerMiddleText, "---", verdanaTinyBold, Rgba32.White, new Point((int)x, (int)y) ); } // Draw a Line through the Middle x = 306; imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, 20), new PointF(x, 624) }); // Draw More Player Stats x = 326; var x2 = 520; y = 34; imgContext.DrawText( leftMiddleText, "LEVEL", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.level}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 60; imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) }); y = 80; imgContext.DrawText( leftMiddleText, "LAST HITS", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.lastHits}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 108; imgContext.DrawText( leftMiddleText, "DENIES", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.denies}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 134; imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) }); y = 154; imgContext.DrawText( leftMiddleText, "GOLD PER MINUTE", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.goldPerMinute}\n", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 182; imgContext.DrawText( leftMiddleText, "XP PER MINUTE", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.experiencePerMinute}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 208; imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) }); y = 228; imgContext.DrawText( leftMiddleText, "HERO DAMAGE", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.heroDamage}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 256; imgContext.DrawText( leftMiddleText, "TOWER DAMAGE", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.towerDamage}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); y = 284; imgContext.DrawText( leftMiddleText, "HERO HEAL", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); imgContext.DrawText( rightMiddleText, $"{player.heroHealing}", verdanaTinyBold, Rgba32.White, new PointF(x2, y) ); // Draw Skill Build y = 310; imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) }); x = 423; y = 332; imgContext.DrawText( centerMiddleText, "SKILL BUILD", verdanaTinyBold, Rgba32.LightGray, new PointF(x, y) ); x = 326; y = 360; var skillLevel = 0; var talentNumber = 0; for (var j = 0; j < player.skillBuild.Length; j++) { var skill = player.skillBuild[j]; var imgx = x + 2 + 32 * (j % 6); var imgy = y + 2 + 64 * (j / 6); boxBorder = new Image <Rgba32>(34, 34); boxBorder.Mutate(img => img.Fill(new Rgba32(48, 48, 48))); imgContext.DrawImage( boxBorder, 1, new Point((int)imgx - 2, (int)imgy - 2) ); Image <Rgba32> skillImage = null; if (skill.codeName == "talent") { if (skillLevel < (9 + talentNumber * 5)) { skillLevel = 9 + talentNumber * 5; } skillImage = Image.Load(this.assembly.GetManifestResourceStream($"OpenDotaApi.ref.assets.Talent.png")); skillImage.Mutate(img => img.Resize(30, 30)); talentNumber++; } else { string skillImagePath = $@"./imgcache/abilities/{skill.id}.png"; if (!File.Exists(skillImagePath)) { skillImage = new Image <Rgba32>(30, 30); skillImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20))); } else { skillImage = Image.Load(skillImagePath); skillImage.Mutate(img => img.Resize(30, 30)); } } imgContext.DrawImage( skillImage, 1, new Point((int)imgx, (int)imgy) ); imgContext.DrawText( centerText, (skillLevel + 1).ToString(), verdanaTinyBold, Rgba32.White, new Point((int)imgx + 16, (int)imgy + 34) ); if (skillLevel < 25) { skillLevel++; } } using (MemoryStream memoryStream = new MemoryStream()) { playerReport.SaveAsPng(memoryStream); playerReportData = memoryStream.ToArray(); } } ); } return(playerReportData); }
public byte[] DrawPlayerReport(DotaMatch match, MatchPlayers player) { return(this.drawer.DrawPlayerReport(match, player)); }