Guest User

Untitled

a guest
Jun 26th, 2020
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 110.31 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Windows.Forms;
  6. using System.Drawing;
  7. using System.Timers;
  8. using System.IO;
  9. using System.Collections;
  10.  
  11. using System.Drawing.Drawing2D;
  12.  
  13. /* ################# TO DO ##################### */
  14. /*Можно сделать так чтобы программа спрашивала у пользователя разрешение планетсайда, затем брала разрешение экрана у винды и умножала все на коэффициент-разницу разрешений
  15. add magazine size into burst stats?
  16.  
  17.     Кстати, зная ширину паттерна (количество киков) можно рассчитать расстояние на котором цель гарантированно умрет за 1 бурст
  18.  
  19.  
  20.  
  21.     incorporate target movement if we're firing from a moving stance? subject to ADS multiplier
  22. add croshair movement while CoF resets in TTK simulation
  23.  
  24. add the ability for user to control recoil with mouse
  25. */
  26.  
  27.  
  28. class Shot
  29. {
  30.     public Double X; //Crosshair Position
  31.     public Double Y;
  32.     public Double Vertical_Recoil; //recoil produced by this shot (not recoil affecting this shot)
  33.     public Double Horizontal_Recoil;
  34.     public Double Recoil_Angle;
  35.     public Double Accumulated_Horizontal_Recoil;
  36.     public PointF[] bullets;
  37.     public PointF pellet_spread_coords;
  38.     public double CoF;
  39.     public double Pellet_Spread;
  40.  
  41.     public Shot(Double x, Double y, Double ACR, Weapon wpn)
  42.     {
  43.         X = x;
  44.         Y = y;
  45.         Accumulated_Horizontal_Recoil = ACR;
  46.         bullets = new PointF[wpn.Pellets];
  47.     }
  48. }
  49.  
  50. class Weapon : IEnumerable<Weapon>
  51. {
  52.     public double Vertical_Recoil, Horizontal_Recoil_Minimum, Horizontal_Recoil_Maximum,
  53. Horizontal_Recoil_Tolerance, First_Shot_Recoil_Multiplier, Headshot_Damage_Multiplier,
  54. Short_Reload, Long_Reload, CoF_Standing_Still_ADS, CoF_Standing_Moving_ADS, CoF_Crouching_Still_ADS,
  55. CoF_Crouching_Moving_ADS, CoF_Standing_Still_Hip, CoF_Standing_Moving_Hip, CoF_Crouching_Still_Hip, CoF_Sprint,
  56. CoF_Crouching_Moving_HIP, CoF_Bloom_ADS, CoF_Bloom_Hip, Recoil_Angle_Minimum, Recoil_Angle_Maximum, Equip_Time, ADS_Movement_Speed_Multiplier, Pellet_Spread_ADS, Pellet_Spread_HIP;
  57.  
  58.     public int Rate_of_Fire, Maximum_Damage, Maximum_Damage_Range, Minimum_Damage, Minimum_Damage_Range,
  59.         Projectile_Velocity, Magazine_Size, Recoil_Recovery_Rate, Pellets, Ammo_Pool, Refire_Time;
  60.     public string Weapon_Name, Faction, Type, Fire_Mode, Attachments, Stats;
  61.     public int ID;
  62.     public float Starting_X, Starting_Y;
  63.     public int ShotNumber;
  64.     public bool dragging = false, TargetDragging = false;
  65.     public Shot[] shot;
  66.     public Button GetStats;
  67.     public double CurrentCoF;
  68.     public float Target_X, Target_Y, Target_W, Target_H;
  69.  
  70.     public Weapon() { Init(); }
  71.     public Weapon(Weapon w)
  72.     {
  73.         Vertical_Recoil = w.Vertical_Recoil;
  74.         Horizontal_Recoil_Minimum = w.Horizontal_Recoil_Minimum;
  75.         Horizontal_Recoil_Maximum = w.Horizontal_Recoil_Maximum;
  76.         Horizontal_Recoil_Tolerance = w.Horizontal_Recoil_Tolerance;
  77.         First_Shot_Recoil_Multiplier = w.First_Shot_Recoil_Multiplier;
  78.         Headshot_Damage_Multiplier = w.Headshot_Damage_Multiplier;
  79.         Short_Reload = w.Short_Reload;
  80.         Long_Reload = w.Long_Reload;
  81.         CoF_Standing_Still_ADS = w.CoF_Standing_Still_ADS;
  82.         CoF_Standing_Moving_ADS = w.CoF_Standing_Moving_ADS;
  83.         CoF_Crouching_Still_ADS = w.CoF_Crouching_Still_ADS;
  84.         CoF_Crouching_Moving_ADS = w.CoF_Crouching_Moving_ADS;
  85.         CoF_Standing_Still_Hip = w.CoF_Standing_Still_Hip;
  86.         CoF_Standing_Moving_Hip = w.CoF_Standing_Moving_Hip;
  87.         CoF_Crouching_Still_Hip = w.CoF_Crouching_Still_Hip;
  88.         CoF_Sprint = w.CoF_Sprint;
  89.         CoF_Crouching_Moving_HIP = w.CoF_Crouching_Moving_HIP;
  90.         CoF_Bloom_ADS = w.CoF_Bloom_ADS;
  91.         CoF_Bloom_Hip = w.CoF_Bloom_Hip;
  92.         Recoil_Angle_Minimum = w.Recoil_Angle_Minimum;
  93.         Recoil_Angle_Maximum = w.Recoil_Angle_Maximum;
  94.         Equip_Time = w.Equip_Time;
  95.         ADS_Movement_Speed_Multiplier = w.ADS_Movement_Speed_Multiplier;
  96.         Rate_of_Fire = w.Rate_of_Fire;
  97.         Maximum_Damage = w.Maximum_Damage;
  98.         Maximum_Damage_Range = w.Maximum_Damage_Range;
  99.         Minimum_Damage_Range = w.Minimum_Damage_Range;
  100.         Minimum_Damage = w.Minimum_Damage;
  101.         Projectile_Velocity = w.Projectile_Velocity;
  102.         Magazine_Size = w.Magazine_Size;
  103.         Recoil_Recovery_Rate = w.Recoil_Recovery_Rate;
  104.         Pellets = w.Pellets;
  105.         Ammo_Pool = w.Ammo_Pool;
  106.         Refire_Time = w.Refire_Time;
  107.         Weapon_Name = w.Weapon_Name;
  108.         Faction = w.Faction;
  109.         Type = w.Type;
  110.         ID = w.ID;
  111.         Pellet_Spread_ADS = w.Pellet_Spread_ADS;
  112.         Pellet_Spread_HIP = w.Pellet_Spread_HIP;
  113.         Fire_Mode = w.Fire_Mode;
  114.         Attachments = w.Attachments;
  115.         Target_X = w.Target_X;
  116.         Target_Y = w.Target_Y;
  117.         Init();
  118.     }
  119.     public void InitButton()
  120.     {
  121.         GetStats = new Button();
  122.         GetStats.Text = "Get stats";
  123.         GetStats.Size = new Size(60, 30);
  124.         GetStats.Location = new Point((int)Starting_X - 65, (int)Starting_Y + 10);
  125.         GetStats.Click += GetStats_Click;
  126.     }
  127.  
  128.     private void GetStats_Click(object sender, EventArgs e)
  129.     {
  130.         if (Attachments != "") MessageBox.Show(Stats + "\n\n" + "ATTACHMENTS:\n" + Attachments + "\n" + "You can press Ctrl + C to copy\nthe contents of this message box.", "Weapon Stats");
  131.         else MessageBox.Show(Stats + "\n\n" + "You can press Ctrl + C to copy\nthe contents of this message box.", "Weapon Stats");
  132.     }
  133.  
  134.     public void Init()
  135.     {
  136.         shot = new Shot[200];
  137.         ShotNumber = 0;
  138.     }
  139.     public int CompareTo(Weapon other)
  140.     {
  141.         throw new NotImplementedException();
  142.     }
  143.  
  144.     public IEnumerator<Weapon> GetEnumerator()
  145.     {
  146.         throw new NotImplementedException();
  147.     }
  148.  
  149.     IEnumerator IEnumerable.GetEnumerator()
  150.     {
  151.         throw new NotImplementedException();
  152.     }
  153.     public double GetCurrentCoF(bool ADSing, bool Standing, bool Still)
  154.     {
  155.         double Minimum_CoF = GetCurrentMinimumCoF(ADSing, Standing, Still);
  156.         if (CurrentCoF < Minimum_CoF || ShotNumber == 0) CurrentCoF = Minimum_CoF;
  157.         if (ADSing && CurrentCoF > 3) CurrentCoF = 3;
  158.         else if (CurrentCoF > 7) CurrentCoF = 7;
  159.         return CurrentCoF;
  160.     }
  161.     public double GetCurrentMinimumCoF(bool ADSing, bool Standing, bool Still)
  162.     {
  163.         double Minimum_CoF = 0;
  164.         switch (Convert.ToString(Convert.ToInt32(ADSing)) + Convert.ToString(Convert.ToInt32(Standing)) + Convert.ToString(Convert.ToInt32(Still)))
  165.         {
  166.             case "111": Minimum_CoF = CoF_Standing_Still_ADS; break;
  167.             case "011": Minimum_CoF = CoF_Standing_Still_Hip; break;
  168.  
  169.             case "101": Minimum_CoF = CoF_Crouching_Still_ADS; break;
  170.             case "001": Minimum_CoF = CoF_Crouching_Still_Hip; break;
  171.  
  172.             case "110": Minimum_CoF = CoF_Standing_Moving_ADS; break;
  173.             case "010": Minimum_CoF = CoF_Standing_Moving_Hip; break;
  174.  
  175.             case "100": Minimum_CoF = CoF_Crouching_Moving_ADS; break;
  176.             case "000": Minimum_CoF = CoF_Crouching_Moving_HIP; break;
  177.  
  178.         }
  179.         return Minimum_CoF;
  180.     }
  181.     public void Fire(Random rand, double Left_or_Right, bool ADSing, bool Standing, bool Still, bool Ignore_Vertical_Recoil)
  182.     {
  183.         if (ShotNumber >= shot.Length) Init();
  184.         PointF pt = new PointF(0, 0);
  185.         double Minimum_CoF = 0;
  186.  
  187.         switch (Convert.ToString(Convert.ToInt32(ADSing)) + Convert.ToString(Convert.ToInt32(Standing)) + Convert.ToString(Convert.ToInt32(Still)))
  188.         {
  189.             case "111": Minimum_CoF = CoF_Standing_Still_ADS; break;
  190.             case "011": Minimum_CoF = CoF_Standing_Still_Hip; break;
  191.  
  192.             case "101": Minimum_CoF = CoF_Crouching_Still_ADS; break;
  193.             case "001": Minimum_CoF = CoF_Crouching_Still_Hip; break;
  194.  
  195.             case "110": Minimum_CoF = CoF_Standing_Moving_ADS; break;
  196.             case "010": Minimum_CoF = CoF_Standing_Moving_Hip; break;
  197.  
  198.             case "100": Minimum_CoF = CoF_Crouching_Moving_ADS; break;
  199.             case "000": Minimum_CoF = CoF_Crouching_Moving_HIP; break;
  200.  
  201.         }
  202.  
  203.         //creating a new shot instance and giving it crosshair position and accumulated horizontal recoil
  204.         if (ShotNumber == 0)
  205.         {
  206.             shot[0] = new Shot(0, 0, 0, this);
  207.             CurrentCoF = Minimum_CoF;
  208.         }
  209.         else
  210.         {
  211.             pt = CalculateAngle(shot[ShotNumber - 1].X, shot[ShotNumber - 1].Y, shot[ShotNumber - 1].Recoil_Angle, shot[ShotNumber - 1].Vertical_Recoil);
  212.             pt = CalculateAngle(pt.X, pt.Y, 90 + shot[ShotNumber - 1].Recoil_Angle, shot[ShotNumber - 1].Horizontal_Recoil);
  213.             shot[ShotNumber] = new Shot(pt.X, pt.Y, shot[ShotNumber - 1].Accumulated_Horizontal_Recoil, this);
  214.         }
  215.  
  216.         //checking CoF stance
  217.         if (CurrentCoF < Minimum_CoF) CurrentCoF = Minimum_CoF;
  218.         shot[ShotNumber].CoF = CurrentCoF;
  219.         //storing pellet spread for this shot
  220.         if (ADSing) shot[ShotNumber].Pellet_Spread = Pellet_Spread_ADS;
  221.         else shot[ShotNumber].Pellet_Spread = Pellet_Spread_HIP;
  222.  
  223.  
  224.         //assign bullet positions
  225.         shot[ShotNumber].pellet_spread_coords = Random_Bullet_Position(rand, pt.X, pt.Y, CurrentCoF);
  226.         for (int i = 0; i < Pellets; i++)
  227.             shot[ShotNumber].bullets[i] = Random_Bullet_Position(rand, shot[ShotNumber].pellet_spread_coords.X, shot[ShotNumber].pellet_spread_coords.Y, shot[ShotNumber].Pellet_Spread);
  228.        
  229.  
  230.         //assign vertical recoil
  231.         if (ShotNumber == 0) shot[0].Vertical_Recoil = -Vertical_Recoil * First_Shot_Recoil_Multiplier * Convert.ToInt32(!Ignore_Vertical_Recoil);
  232.         else shot[ShotNumber].Vertical_Recoil = -Vertical_Recoil * Convert.ToInt32(!Ignore_Vertical_Recoil);
  233.  
  234.         //assign recoil angle
  235.         shot[ShotNumber].Recoil_Angle = Recoil_Angle_Minimum + rand.NextDouble() * (Recoil_Angle_Maximum - Recoil_Angle_Minimum);
  236.  
  237.         //assign horizontal recoil
  238.         if (Left_or_Right > 0.5) shot[ShotNumber].Horizontal_Recoil = (Horizontal_Recoil_Minimum + rand.NextDouble() * (Horizontal_Recoil_Maximum - Horizontal_Recoil_Minimum));
  239.         else shot[ShotNumber].Horizontal_Recoil = -1 * (Horizontal_Recoil_Minimum + rand.NextDouble() * (Horizontal_Recoil_Maximum - Horizontal_Recoil_Minimum));
  240.  
  241.         //force horizontal recoil to be in tolerance
  242.         if (ShotNumber > 0 && Math.Abs(shot[ShotNumber - 1].Accumulated_Horizontal_Recoil) > (Horizontal_Recoil_Tolerance / 2))
  243.         {
  244.             if (shot[ShotNumber - 1].Accumulated_Horizontal_Recoil > 0) shot[ShotNumber].Horizontal_Recoil = -1 * Math.Abs(shot[ShotNumber].Horizontal_Recoil);
  245.             else shot[ShotNumber].Horizontal_Recoil = Math.Abs(shot[ShotNumber].Horizontal_Recoil);
  246.         }
  247.         shot[ShotNumber].Accumulated_Horizontal_Recoil += shot[ShotNumber].Horizontal_Recoil;
  248.  
  249.         ShotNumber++;
  250.         //Assign CoF. Add stance checking here
  251.         if (ADSing) CurrentCoF += CoF_Bloom_ADS;
  252.         else CurrentCoF += CoF_Bloom_Hip;
  253.  
  254.         if (ADSing && CurrentCoF > 3) CurrentCoF = 3;
  255.         else if (CurrentCoF > 7) CurrentCoF = 7;
  256.     }
  257.     PointF CalculateAngle(Double X, Double Y, Double Angle, Double Length)
  258.     {
  259.         Double angle1 = (90 + Angle) * Math.PI / 180;
  260.         PointF pt = new PointF((float)(X + Math.Cos(angle1) * Length), (float)(Y + Math.Sin(angle1) * Length));
  261.         return pt;
  262.     }
  263.     PointF Random_Bullet_Position(Random rand, float X, float Y, Double CoF)
  264.     {
  265.         var angle = rand.NextDouble() * Math.PI * 2;
  266.         var radius = Math.Sqrt(rand.NextDouble()) * (CoF / 2);
  267.         var x = X + radius * Math.Cos(angle);
  268.         var y = Y + radius * Math.Sin(angle);
  269.         return new PointF((float)x, (float)y);
  270.     }
  271. }
  272.  
  273. class MainWindow : Form
  274. {
  275.     System.Timers.Timer timer;
  276.  
  277.     public float Vertical_Pixels;
  278.  
  279.     CheckBox chk_ShowCoF, chk_ShowTolerance, chk_ShowRecoilPattern, chk_ShowGrid, chk_ShowConnectors, chk_AngledGrid,
  280.         btn_Record, chk_Ignore_Vertical_Recoil, chk_Draw_Crosshair_Positions, chk_Draw_Bullet_Hits, chk_Draw_Target;
  281.  
  282.     //attachment checkboxes
  283.     CheckBox chk_SPA, chk_HVA, chk_Slugs, chk_SmartChoke, chk_FG, chk_AFG, chk_ExMags, chk_Compensator, chk_Suppressor, chk_LS, chk_ALS;
  284.     RadioButton Optic_1x, Optic_2x, Optic_3_4x, Optic_4x, Optic_6x, Optic_7x, Optic_8x, Optic_10x, Optic_12x;
  285.     RadioButton rb_Crouching, rb_Standing, rb_Moving, rb_Still, rb_ADSing, rb_HipFiring;
  286.     RadioButton mode_Graphs, mode_Simulation;
  287.     GroupBox group_Still_Moving, group_ADSing, group_Stand_Crouch, group_thresholds, group_target;
  288.     Label ConfigPanel_Label3, ConfigPanel_Label7, ConfigPanel_Label10, ConfigPanel_Label11;
  289.     Button btn_show_help, btn_headshot, btn_bodyshot, btn_legshot, btn_Fire_Burst, btn_Reset;
  290.     //calculations    GroupBox calculations;
  291.  
  292.     ListBox lb; //choose weapon
  293.     TextBox tb, burst_stats, tb_thresholds, tb_target_health, tb_damage_multiplier, tb_bonus_headshots, tb_target, tb_pause; //weapon stats
  294.     TextBox tb_Burst_Length;
  295.     public int ConfigX, ConfigY;
  296.     public int distance = 5;
  297.     public float time_elapsed = 0;
  298.     public int assign_damage = 0, target_health = 1000, headshots = 0, legshots = 0, bodyshots = 0;
  299.  
  300.     string Database_Date;
  301.     int Zoom = 1;
  302.     Random rand;
  303.     Pen pen, pen_red, pen_blue;
  304.     Brush brush, brush_black, brush_red;
  305.     Image img, img2;
  306.  
  307.     bool Recording = false, show_help = false;
  308.     int MX, MY; //MX, MY - how far you dragged with middle mouse.
  309.  
  310.     int number_of_weapons;
  311.  
  312.     Weapon[] weapons;
  313.     Weapon[] weapons_comparison;
  314.     int number_of_weapons_in_comparison = 1;
  315.     Weapon weapon_orig; //weapon stats with attachments and without any
  316.     public Double ADS_Magnification = 1.35;
  317.     // Double FPS = 8.3333333333333333333333333333333
  318.  
  319.     public MainWindow()
  320.     {
  321.         Text = "PlanetSide 2 Weapon Simulator";    // WINDOW CONFIGURATION
  322.         Rectangle resolution = Screen.PrimaryScreen.Bounds; //getting screen resolution and setting window to match
  323.         Height = resolution.Height - 65;
  324.         Width = resolution.Width - 20;
  325.         AutoScroll = true;
  326.         Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("de-DE"); //avoid issues with decimal symbol in system locale
  327.         Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("de-DE");
  328.         this.WindowState = FormWindowState.Maximized;   //window starts maximimzed just to be sure
  329.         this.DoubleBuffered = true;
  330.         ConfigX = Width - 450;
  331.         ConfigY = 10;
  332.         KeyPreview = true;
  333.  
  334.         rb_ADSing = new RadioButton();
  335.         rb_ADSing.Location = new Point(10, 12);
  336.         rb_ADSing.Size = new Size(80, 30);
  337.         rb_ADSing.Text = "Aiming Down Sights";
  338.         rb_ADSing.CheckedChanged += Rb_ADSing_CheckedChanged;
  339.         rb_ADSing.CheckedChanged += CheckAttachments;
  340.  
  341.         weapons = new Weapon[1000];
  342.         weapons_comparison = new Weapon[10];
  343.  
  344.         rand = new Random();
  345.         pen = new Pen(Color.Black);
  346.         pen_red = new Pen(Color.Red);
  347.         brush = new SolidBrush(Color.Orange);
  348.         brush_black = new SolidBrush(Color.Black);
  349.         pen_blue = new Pen(Color.Blue);
  350.         brush_red = new SolidBrush(Color.Red);
  351.  
  352.         this.MouseDown += new System.Windows.Forms.MouseEventHandler(MainWindow_MouseDown); //register mouse controls
  353.         this.MouseUp += new System.Windows.Forms.MouseEventHandler(MainWindow_MouseUp);
  354.         this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
  355.  
  356.         timer = new System.Timers.Timer();
  357.         timer.Elapsed += Fire;
  358.  
  359.         ParseFile();
  360.         ConfigurationPanel();
  361.         LoadDefaults();
  362.         if (File.Exists("target.jpg")) img = Image.FromFile("target.jpg");
  363.         else { chk_Draw_Target.Enabled = false; MessageBox.Show("Target.jpg not found. Draw Target mode disabled.", "Error"); }
  364.         if (File.Exists("help.jpg")) img2 = Image.FromFile("help.jpg");
  365.         else
  366.         {
  367.                 btn_show_help.Enabled = false;
  368.                 MessageBox.Show("Help.jpg not found. \"Legend\" button disabled.", "Error");
  369.         }
  370.         chk_FG.Checked = true;
  371.         chk_FG.Checked = false;
  372.  
  373.         Show();
  374.         Reset();
  375.     }
  376.  
  377.     private void Rb_ADSing_CheckedChanged(object sender, EventArgs e)
  378.     {
  379.         CalculatePixels();
  380.         UpdateBurstStats();
  381.     }
  382.  
  383.     void Fire(object sender, EventArgs e)
  384.     {
  385.         FireWeapons();
  386.     }
  387.     void FireWeapons()
  388.     {
  389.         for (int i = 0; i < number_of_weapons_in_comparison; i++) weapons_comparison[i].Fire(rand, rand.NextDouble(), rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked, chk_Ignore_Vertical_Recoil.Checked);
  390.         if(weapons_comparison[0].ShotNumber > 1) time_elapsed += (float)weapons_comparison[0].Refire_Time / 1000;
  391.         Invalidate();
  392.     }
  393.  
  394.     /* DRAWING DRAWING DRAWING DRAWING DRAWING DRAWING DRAWING DRAWING DRAWING */
  395.     protected override void OnPaint(PaintEventArgs e)       //ф-я рисования
  396.     {
  397.         base.OnPaint(e);
  398.  
  399.  
  400.         if (mode_Graphs.Checked) DrawGraphs(e);
  401.         if (mode_Simulation.Checked)
  402.         {
  403.             e.Graphics.FillRectangle(Brushes.White, 0, 0, ConfigX - 228, Height); //white background
  404.             if (!chk_Draw_Target.Checked) e.Graphics.FillRectangle(Brushes.White, 0, 715, ConfigX - 10, Height);
  405.             for (int i = 0; i < number_of_weapons_in_comparison; i++) DrawForWeapon(e, weapons_comparison[i]);
  406.             UpdateBurstStats();
  407.             if (show_help) e.Graphics.DrawImage(img2, ConfigX - 536, ConfigY + 565);
  408.         }
  409.     }
  410.     void DrawForWeapon(PaintEventArgs e, Weapon weapon)
  411.     {
  412.         if (chk_Draw_Target.Checked)
  413.         {
  414.             e.Graphics.DrawImage(img, weapon.Starting_X + weapon.Target_X - weapon.Target_W / 2, weapon.Starting_Y + weapon.Target_Y - weapon.Target_H / 4, weapon.Target_W, weapon.Target_H);
  415.             e.Graphics.FillEllipse(Brushes.Blue, weapon.Starting_X + weapon.Target_X - 5, weapon.Starting_Y + weapon.Target_Y + weapon.Target_H / 1.4F - 10, 10, 10);
  416.         }
  417.         if (chk_ShowGrid.Checked) DrawGrid(e, weapon);
  418.         if (chk_ShowCoF.Checked) DrawCoF(e, weapon);
  419.         if (chk_ShowConnectors.Checked) DrawConnectors(e, weapon);
  420.         if (chk_ShowRecoilPattern.Checked) DrawPattern(e, weapon);
  421.         if (chk_ShowTolerance.Checked) DrawTolerance(e, weapon);
  422.         if (chk_Draw_Crosshair_Positions.Checked) DrawShots(e, weapon);
  423.         if (chk_Draw_Bullet_Hits.Checked) DrawBullets(e, weapon);
  424.  
  425.         e.Graphics.DrawString(weapon.Weapon_Name, DefaultFont, Brushes.Black, weapon.Starting_X, weapon.Starting_Y + 18);
  426.         e.Graphics.DrawString(weapon.Attachments, DefaultFont, Brushes.Black, weapon.Starting_X, weapon.Starting_Y + 34);
  427.  
  428.         if (weapon.GetStats != null) weapon.GetStats.Location = new Point((int)weapon.Starting_X - 65, (int)weapon.Starting_Y + 10);
  429.     }
  430.     void DrawTolerance(PaintEventArgs e, Weapon weapon)
  431.     {
  432.         int i;
  433.         PointF pt1, pt2;
  434.  
  435.         pen.Width = 2; //drawing center black line
  436.         DrawAngledLine(e, pen, weapon.Starting_X, weapon.Starting_Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2, -(weapon.ShotNumber + 1) * weapon_orig.Vertical_Recoil * Vertical_Pixels - Vertical_Pixels);
  437.         pen.Color = Color.Cyan;
  438.  
  439.         for (i = 0; i < weapon.ShotNumber; i++)
  440.         {
  441.             // one side
  442.             pt1 = CalculateAngle(weapon.shot[i].X, weapon.shot[i].Y, 90 + weapon.shot[i].Recoil_Angle, weapon.Horizontal_Recoil_Tolerance / 2 - weapon.shot[i].Accumulated_Horizontal_Recoil + weapon.shot[i].Horizontal_Recoil);
  443.             pt2 = CalculateAngle(pt1.X, pt1.Y, weapon.shot[i].Recoil_Angle, weapon.shot[i].Vertical_Recoil - 1);
  444.             e.Graphics.DrawLine(pen, weapon.Starting_X + pt1.X * Vertical_Pixels, weapon.Starting_Y + pt1.Y * Vertical_Pixels, weapon.Starting_X + pt2.X * Vertical_Pixels, weapon.Starting_Y + pt2.Y * Vertical_Pixels);
  445.             //other side
  446.             pt1 = CalculateAngle(weapon.shot[i].X, weapon.shot[i].Y, 90 + weapon.shot[i].Recoil_Angle, -weapon.Horizontal_Recoil_Tolerance / 2 - weapon.shot[i].Accumulated_Horizontal_Recoil + weapon.shot[i].Horizontal_Recoil);
  447.             pt2 = CalculateAngle(pt1.X, pt1.Y, weapon.shot[i].Recoil_Angle, weapon.shot[i].Vertical_Recoil - 1);
  448.             e.Graphics.DrawLine(pen, weapon.Starting_X + pt1.X * Vertical_Pixels, weapon.Starting_Y + pt1.Y * Vertical_Pixels, weapon.Starting_X + pt2.X * Vertical_Pixels, weapon.Starting_Y + pt2.Y * Vertical_Pixels);
  449.         }
  450.  
  451.         pen.Color = Color.Black;
  452.         pen.Width = 1;
  453.     }
  454.     void DrawShots(PaintEventArgs e, Weapon weapon)
  455.     {
  456.         int i;
  457.         for (i = 0; i < weapon.ShotNumber; i++) e.Graphics.FillRectangle(brush, weapon.Starting_X + (float)weapon.shot[i].X * Vertical_Pixels - 3, weapon.Starting_Y + (float)weapon.shot[i].Y * Vertical_Pixels - 3, 7, 7);
  458.     }
  459.     void DrawBullets(PaintEventArgs e, Weapon weapon)
  460.     {
  461.         int i, j;
  462.         Brush b = new SolidBrush(Color.Red);
  463.         for (i = 0; i < weapon.ShotNumber; i++)
  464.             if(weapon.shot[i].Pellet_Spread != 0)
  465.             for (j = 0; j < weapon.Pellets; j++) e.Graphics.FillEllipse(b, weapon.Starting_X + weapon.shot[i].bullets[j].X * Vertical_Pixels - 3, weapon.Starting_Y + weapon.shot[i].bullets[j].Y * Vertical_Pixels - 3, 7, 7);
  466.             else e.Graphics.FillEllipse(b, weapon.Starting_X + weapon.shot[i].bullets[0].X * Vertical_Pixels - 3, weapon.Starting_Y + weapon.shot[i].bullets[0].Y * Vertical_Pixels - 3, 7, 7);
  467.     }
  468.     void DrawGrid(PaintEventArgs e, Weapon weapon)
  469.     {
  470.         int i, j;
  471.         e.Graphics.FillEllipse(Brushes.Blue, weapon.Starting_X - 5, weapon.Starting_Y - 5, 10, 10);
  472.  
  473.         if (!chk_AngledGrid.Checked)
  474.         {
  475.             for (j = 1; j < System.Convert.ToInt32(weapon_orig.Vertical_Recoil * weapon.ShotNumber) + 2; j++)
  476.             {
  477.                 for (i = 0; i < 4; i++) e.Graphics.DrawRectangle(pen_blue, weapon.Starting_X + Vertical_Pixels * i, weapon.Starting_Y - Vertical_Pixels * j, Vertical_Pixels, Vertical_Pixels);
  478.                 for (i = 1; i < 5; i++) e.Graphics.DrawRectangle(pen_blue, weapon.Starting_X - Vertical_Pixels * i, weapon.Starting_Y - Vertical_Pixels * j, Vertical_Pixels, Vertical_Pixels);
  479.             }
  480.         }
  481.         else
  482.         {
  483.             PointF pt = new PointF(weapon.Starting_X, weapon.Starting_Y);
  484.             PointF pt_center = new PointF(weapon.Starting_X, weapon.Starting_Y);
  485.  
  486.             for (i = 0; i < weapon_orig.Vertical_Recoil * weapon.ShotNumber + 2; i++)
  487.             {
  488.                 pt = pt_center;
  489.                 for (j = 0; j < 2; j++)
  490.                 {
  491.                     pt = DrawAngledLine(e, pen_blue, pt.X, pt.Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2 + 90, Vertical_Pixels);
  492.                     DrawAngledLine(e, pen_blue, pt.X, pt.Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2 + 180, Vertical_Pixels);
  493.                 }
  494.  
  495.                 pt = pt_center;
  496.                 for (j = 1; j < 3; j++)
  497.                 {
  498.                     pt = DrawAngledLine(e, pen_blue, pt.X, pt.Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2 + 90, -Vertical_Pixels);
  499.                     DrawAngledLine(e, pen_blue, pt.X, pt.Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2 + 180, Vertical_Pixels);
  500.                 }
  501.  
  502.                 pt = pt_center;
  503.                 pt_center = DrawAngledLine(e, pen_blue, pt.X, pt.Y, (weapon.Recoil_Angle_Maximum + weapon.Recoil_Angle_Minimum) / 2 + 180, Vertical_Pixels);
  504.             }
  505.             //   e.Graphics.DrawString("1 notch = 1 degree", DefaultFont, brush_black, pt_center.X, pt_center.Y - Vertical_Pixels);
  506.         }
  507.  
  508.     }
  509.     void DrawConnectors(PaintEventArgs e, Weapon weapon)
  510.     {
  511.         int i;
  512.         pen.Color = Color.Green;
  513.         pen.Width = 3;
  514.         for (i = 0; i + 1 < weapon.ShotNumber; i++)
  515.         {
  516.             e.Graphics.DrawLine(pen, (float)(weapon.Starting_X + weapon.shot[i].X * Vertical_Pixels), (float)(weapon.Starting_Y + weapon.shot[i].Y * Vertical_Pixels), (float)(weapon.Starting_X + weapon.shot[i + 1].X * Vertical_Pixels), (float)(weapon.Starting_Y + weapon.shot[i + 1].Y * Vertical_Pixels));
  517.         }
  518.         pen.Color = Color.Black;
  519.         pen.Width = 1;
  520.     }
  521.     void DrawPattern(PaintEventArgs e, Weapon weapon)
  522.     {
  523.         PointF pt1, pt2;
  524.         int i;
  525.         for (i = 0; i < weapon.ShotNumber; i++)
  526.         {
  527.             pt1 = CalculateAngle(weapon.shot[i].X, weapon.shot[i].Y, weapon.shot[i].Recoil_Angle, weapon.shot[i].Vertical_Recoil);
  528.             pt2 = CalculateAngle(pt1.X, pt1.Y, 90 + weapon.shot[i].Recoil_Angle, weapon.shot[i].Horizontal_Recoil);
  529.             e.Graphics.DrawLine(pen, (float)(weapon.Starting_X + weapon.shot[i].X * Vertical_Pixels), (float)(weapon.Starting_Y + weapon.shot[i].Y * Vertical_Pixels), weapon.Starting_X + pt1.X * Vertical_Pixels, weapon.Starting_Y + pt1.Y * Vertical_Pixels);
  530.             e.Graphics.DrawLine(pen_red, weapon.Starting_X + pt1.X * Vertical_Pixels, weapon.Starting_Y + pt1.Y * Vertical_Pixels, weapon.Starting_X + pt2.X * Vertical_Pixels, weapon.Starting_Y + pt2.Y * Vertical_Pixels);
  531.         }
  532.     }
  533.     void DrawCoF(PaintEventArgs e, Weapon weapon)
  534.     {
  535.         int i;
  536.         float size;
  537.         for (i = 0; i < weapon.ShotNumber; i++)
  538.         {
  539.             size = (float)weapon.shot[i].CoF * Vertical_Pixels;
  540.  
  541.             e.Graphics.DrawEllipse(pen, (float)(weapon.Starting_X + weapon.shot[i].X * Vertical_Pixels) - size / 2, (float)(weapon.Starting_Y + weapon.shot[i].Y * Vertical_Pixels) - size / 2, size, size);
  542.  
  543.             if (weapon.Pellet_Spread_ADS > 0 && rb_ADSing.Checked || weapon.Pellet_Spread_HIP > 0 && !rb_ADSing.Checked)
  544.                 //if (!weapon.Attachments.Contains("Slug Ammunition"))
  545.                 {
  546.                     pen.Color = Color.LightGreen;
  547.  
  548.                     size = (float)weapon.shot[i].Pellet_Spread * Vertical_Pixels;
  549.                     //draw pellet spread
  550.                     e.Graphics.DrawEllipse(pen, (float)(weapon.Starting_X + weapon.shot[i].pellet_spread_coords.X * Vertical_Pixels) - size / 2, (float)(weapon.Starting_Y + weapon.shot[i].pellet_spread_coords.Y * Vertical_Pixels) - size / 2, size, size);
  551.                     //draw center of the pellet spread
  552.                     e.Graphics.FillEllipse(new SolidBrush(Color.LightGreen), (float)(weapon.Starting_X + weapon.shot[i].pellet_spread_coords.X * Vertical_Pixels) - 3, (float)(weapon.Starting_Y + weapon.shot[i].pellet_spread_coords.Y * Vertical_Pixels) - 3, 7, 7);
  553.                     pen.Color = Color.Black;
  554.                 }
  555.         }
  556.     }
  557.     void DrawGraphs(PaintEventArgs e)
  558.     {
  559.         int x = 100, y = 50;
  560.         int z;
  561.         int workspace_w = ConfigX - 278 - x;
  562.         int workspace_h = Height - 100;
  563.         Font font = new Font(DefaultFont.FontFamily, 14);
  564.         int longest_minimum_damage_range = 0;
  565.         int lowest_damage = 100000;
  566.         int highest_damage = 0;
  567.      //   int[][] arr;
  568.  
  569.         Pen[] pens = new Pen[10];
  570.         pens[0] = new Pen(Color.FromArgb(64, 166, 255));
  571.         pens[1] = new Pen(Color.FromArgb(153, 38, 38));
  572.         pens[2] = new Pen(Color.FromArgb(32, 128, 32));
  573.         pens[3] = new Pen(Color.FromArgb(102, 50, 181));
  574.         pens[4] = new Pen(Color.FromArgb(0, 242, 226));
  575.         pens[5] = new Pen(Color.FromArgb(242, 129, 0));
  576.         pens[6] = new Pen(Color.FromArgb(255, 0, 136));
  577.         pens[7] = new Pen(Color.FromArgb(179, 164, 134));
  578.         pens[8] = new Pen(Color.FromArgb(217, 163, 199));
  579.         pens[9] = new Pen(Color.FromArgb(242, 255, 64));
  580.         for (int i = 0; i < 10; i++) pens[i].Width = 4;
  581.  
  582.         PointF[] pt = new PointF[4];
  583.  
  584.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  585.         {
  586.             if (longest_minimum_damage_range < weapons_comparison[i].Minimum_Damage_Range)
  587.                 longest_minimum_damage_range = weapons_comparison[i].Minimum_Damage_Range;
  588.             if (lowest_damage > weapons_comparison[i].Minimum_Damage) lowest_damage = weapons_comparison[i].Minimum_Damage;
  589.             if (highest_damage < weapons_comparison[i].Maximum_Damage) highest_damage = weapons_comparison[i].Maximum_Damage;
  590.         }
  591.  
  592.         float pixel_x = (float)workspace_w / (longest_minimum_damage_range + 10);
  593.         float pixel_y = (float)(workspace_h - y) / highest_damage;
  594.  
  595.         e.Graphics.FillRectangle(Brushes.White, 0, 0, ConfigX - 10, Height); //white background
  596.         e.Graphics.FillRectangle(Brushes.Beige, x, y - 30, workspace_w, workspace_h - y + 30);
  597.  
  598.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  599.         {
  600.             pt[0] = new Point(0, -weapons_comparison[i].Maximum_Damage);
  601.             pt[1] = new Point(weapons_comparison[i].Maximum_Damage_Range, -weapons_comparison[i].Maximum_Damage);
  602.             pt[2] = new Point(weapons_comparison[i].Minimum_Damage_Range, -weapons_comparison[i].Minimum_Damage);
  603.             pt[3] = new Point(longest_minimum_damage_range + 10, -weapons_comparison[i].Minimum_Damage);
  604.  
  605.             for (int j = 0; j < 4; j++) { pt[j].X *= pixel_x; pt[j].X += x; pt[j].Y *= pixel_y; pt[j].Y += workspace_h; }
  606.  
  607.             e.Graphics.DrawLine(pens[i], pt[0], pt[1]);
  608.             e.Graphics.DrawString(Convert.ToString(weapons_comparison[i].Maximum_Damage), font, brush_black, pt[0].X - 45, pt[0].Y - 12);
  609.             e.Graphics.DrawLine(pens[i], pt[1], pt[2]);
  610.             e.Graphics.DrawLine(pens[i], pt[2], pt[3]);
  611.             e.Graphics.DrawString(Convert.ToString(weapons_comparison[i].Minimum_Damage), font, brush_black, pt[3].X + 10, pt[3].Y - 12);
  612.  
  613.             z = 0; //drawing vertical grid lines
  614.             while (z * 5 <= longest_minimum_damage_range + 10)
  615.             {
  616.                 /* if(z%2 == 1 && longest_minimum_damage_range > 200) e.Graphics.DrawLine(pen_red, x + z * pixel_x * 5, workspace_h, x + z * pixel_x * 5, y);
  617.                  else*/
  618.                 if (chk_ShowGrid.Checked || z < 1) e.Graphics.DrawLine(pen_blue, x + z * pixel_x * 5, workspace_h, x + z * pixel_x * 5, y - 30);
  619.                 // e.Graphics.DrawString(z * 5+"m", DefaultFont, brush_black, x + z * pixel_x * 5, workspace_h + 10 + 15 * (z % 2)* Convert.ToInt32(longest_minimum_damage_range > 200));
  620.                 e.Graphics.DrawString(z * 5 + "m", DefaultFont, brush_black, x + z * pixel_x * 5 - 5, workspace_h + 10);
  621.                 z++;
  622.                 if (longest_minimum_damage_range > 200) z++;
  623.             }
  624.  
  625.             z = 0; //drawing horizontal grid lines
  626.             while (z * 10 * pixel_y < workspace_h - 30)
  627.             {
  628.                 e.Graphics.DrawLine(pen_blue, x, workspace_h - z * 10 * pixel_y, x + workspace_w, workspace_h - z * 10 * pixel_y);
  629.                 if (!chk_ShowGrid.Checked) break;
  630.                 z++;
  631.                 if (highest_damage > 200) z++;
  632.                 if (highest_damage > 400) z++;
  633.                 if (highest_damage > 600) z++;
  634.             }
  635.  
  636.             //draw BTK thresholds
  637.             /*
  638.             arr = Calculate_tb_thresholds(weapons_comparison[i], (float)Convert.ToDouble(tb_target_health.Text), (float)Convert.ToDouble(tb_damage_multiplier.Text), Convert.ToInt32(tb_bonus_headshots.Text));
  639.             for (int j = 0; j < arr.Length; j++)
  640.             {
  641.                 e.Graphics.DrawLine(pens[j], arr[j][1] * pixel_x + x, workspace_h - arr[j][3] * pixel_y, arr[j][2] * pixel_x + x, workspace_h - arr[j][4] * pixel_y);
  642.              //   e.Graphics.DrawRectangle(pens[i], arr[j][1] * pixel_x + x - 3, workspace_h - arr[j][3] * pixel_y - 3, 7, 7);
  643.                // e.Graphics.DrawRectangle(pens[i], arr[j][2] * pixel_x + x - 3, workspace_h - arr[j][4] * pixel_y - 3, 7, 7);
  644.             }*/
  645.  
  646.             //drawing weapon nanems and moving "get stats" buttons
  647.             e.Graphics.DrawString(weapons_comparison[i].Weapon_Name, font, new SolidBrush(pens[i].Color), ConfigX - 228, ConfigY + i * 110);
  648.             if (i > 0) weapons_comparison[i].GetStats.Location = new Point(ConfigX - 225, ConfigY + 30 + i * 110);
  649.             e.Graphics.DrawString(weapons_comparison[i].Attachments, DefaultFont, Brushes.Black, ConfigX - 155, ConfigY + 30 + i * 110);
  650.  
  651.             if (MX >= x && MX <= workspace_w + x && MY >= y - 30 && MY <= workspace_h) //Drawing mouse lines over graph
  652.             {
  653.                 e.Graphics.DrawLine(pen_red, MX, y - 30, MX, workspace_h);
  654.                 e.Graphics.DrawLine(pen_red, x, MY, workspace_w + x, MY);
  655.                 e.Graphics.DrawString(Convert.ToInt32((MX - x) / pixel_x) + "m", font, brush_red, MX, workspace_h + 30);
  656.                 e.Graphics.DrawString(Convert.ToString(Convert.ToInt32((workspace_h - MY) / pixel_y)), font, brush_red, x - 90, MY - 12);
  657.             }
  658.  
  659.         }
  660.         /*    for (int i = 0; i < longest_minimum_damage_range; i += 10) for (int j = y; j > 0; j -= 10)
  661.                 {
  662.                     e.Graphics.DrawLine(pen_blue, x + i, y - j, x + i + 10, y - j);
  663.                    // e.Graphics.DrawLine(pen_blue, x + i, y - j, x + i + 10, y - j);
  664.                 }*/
  665.     }
  666.     PointF Random_Bullet_Position(float X, float Y, Double CoF)
  667.     {
  668.         var angle = rand.NextDouble() * Math.PI * 2;
  669.         var radius = Math.Sqrt(rand.NextDouble()) * (CoF / 2);
  670.         var x = X + radius * Math.Cos(angle);
  671.         var y = Y + radius * Math.Sin(angle);
  672.         return new PointF((float)x, (float)y);
  673.     }
  674.     PointF DrawAngledLine(PaintEventArgs e, Double X, Double Y, Double Angle, Double Length)
  675.     {
  676.         PointF pt = CalculateAngle(X, Y, Angle, Length);
  677.         e.Graphics.DrawLine(pen, (float)X, (float)Y, pt.X, pt.Y);
  678.         return pt;
  679.     }
  680.     PointF DrawAngledLine(PaintEventArgs e, Pen pen, Double X, Double Y, Double Angle, Double Length)
  681.     {
  682.         PointF pt = CalculateAngle(X, Y, Angle, Length);
  683.         e.Graphics.DrawLine(pen, (float)X, (float)Y, pt.X, pt.Y);
  684.         return pt;
  685.     }
  686.     PointF CalculateAngle(Double X, Double Y, Double Angle, Double Length)
  687.     {
  688.         Double angle1 = (90 + Angle) * Math.PI / 180;
  689.         PointF pt = new PointF((float)(X + Math.Cos(angle1) * Length), (float)(Y + Math.Sin(angle1) * Length));
  690.         return pt;
  691.     }
  692.     void MainWindow_MouseDown(object sender, MouseEventArgs arg)
  693.     {
  694.         chk_AngledGrid.Focus();
  695.         if (arg.Button == MouseButtons.Left)
  696.         {
  697.             for (int i = 0; i < number_of_weapons_in_comparison; i++)
  698.             {
  699.                 if (arg.X > weapons_comparison[i].Starting_X - 10 && arg.X < weapons_comparison[i].Starting_X + 10 && arg.Y > weapons_comparison[i].Starting_Y - 10 && arg.Y < weapons_comparison[i].Starting_Y + 10)
  700.                 { Cursor.Current = Cursors.Hand; weapons_comparison[i].dragging = true; return; }
  701.                 if (arg.X > weapons_comparison[i].Starting_X + weapons_comparison[i].Target_X - 5 && arg.X < weapons_comparison[i].Starting_X + weapons_comparison[i].Target_X + weapons_comparison[i].Target_W / 2 + 10 && arg.Y > weapons_comparison[i].Starting_Y + weapons_comparison[i].Target_Y + weapons_comparison[i].Target_H / 1.4F - 10 && arg.Y < weapons_comparison[i].Starting_Y + weapons_comparison[i].Target_Y + weapons_comparison[i].Target_H / 1.4F)
  702.                 { Cursor.Current = Cursors.Hand; weapons_comparison[i].TargetDragging = true; return; }
  703.             }
  704.  
  705.             FireWeapons();
  706.             timer.Start();
  707.         }
  708.         if (arg.Button == MouseButtons.Middle)
  709.         {
  710.             Cursor.Current = Cursors.Hand;
  711.             MX = arg.X;
  712.             MY = arg.Y;
  713.         }
  714.         Invalidate();
  715.         //  if (arg.Button == MouseButtons.Right) {  }
  716.     }
  717.     protected override void OnMouseMove(MouseEventArgs arg)
  718.     {
  719.         base.OnMouseMove(arg);
  720.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  721.         {
  722.             if (arg.X > weapons_comparison[i].Starting_X - 10 && arg.X < weapons_comparison[i].Starting_X + 10 && arg.Y > weapons_comparison[i].Starting_Y - 10 && arg.Y < weapons_comparison[i].Starting_Y + 10)
  723.                 Cursor.Current = Cursors.Hand;
  724.             if (arg.X > weapons_comparison[i].Starting_X + weapons_comparison[i].Target_X - 5 && arg.X < weapons_comparison[i].Starting_X + weapons_comparison[i].Target_X + weapons_comparison[i].Target_W / 2 + 10 && arg.Y > weapons_comparison[i].Starting_Y + weapons_comparison[i].Target_Y + weapons_comparison[i].Target_H / 1.4F - 10 && arg.Y < weapons_comparison[i].Starting_Y + weapons_comparison[i].Target_Y + weapons_comparison[i].Target_H / 1.4F)
  725.                 Cursor.Current = Cursors.Hand;
  726.         }
  727.  
  728.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  729.         {
  730.             if (weapons_comparison[i].dragging)
  731.             { weapons_comparison[i].Starting_X = arg.X; weapons_comparison[i].Starting_Y = arg.Y; Invalidate(); }
  732.             if (weapons_comparison[i].TargetDragging)
  733.             {
  734.                 weapons_comparison[i].Target_X = arg.X - weapons_comparison[i].Starting_X;
  735.                 weapons_comparison[i].Target_Y = arg.Y - weapons_comparison[i].Starting_Y + 5 - weapons_comparison[i].Target_H / 1.4F;
  736.                 Invalidate();
  737.             }
  738.         }
  739.  
  740.         if (mode_Graphs.Checked)
  741.         {
  742.             MX = arg.X;
  743.             MY = arg.Y;
  744.             Invalidate();
  745.         }
  746.     }
  747.     void MainWindow_MouseUp(object sender, MouseEventArgs arg)
  748.     {
  749.         if (arg.Button == MouseButtons.Left)
  750.         {
  751.             timer.Stop();
  752.             for (int i = 0; i < number_of_weapons_in_comparison; i++) if (weapons_comparison[i].dragging || weapons_comparison[i].TargetDragging) { weapons_comparison[i].dragging = false; weapons_comparison[i].TargetDragging = false; Cursor.Current = Cursors.Default; }
  753.         }
  754.         if (arg.Button == MouseButtons.Middle)
  755.         {
  756.             for (int i = 0; i < number_of_weapons_in_comparison; i++)
  757.             {
  758.                 weapons_comparison[i].Starting_X -= MX - arg.X;
  759.                 weapons_comparison[i].Starting_Y -= MY - arg.Y;
  760.             }
  761.             Invalidate();
  762.         }
  763.         if (arg.Button == MouseButtons.Right)
  764.         {
  765.             if (rb_ADSing.Checked) rb_HipFiring.Checked = true;
  766.             else rb_ADSing.Checked = true;
  767.             CalculatePixels();
  768.         }
  769.     }
  770.     private void MainWindow_KeyDown(object sender, KeyEventArgs e)
  771.     {
  772.         if (Recording)
  773.         {
  774.             if (e.KeyCode == Keys.A)
  775.             {
  776.                 for (int i = 0; i < number_of_weapons_in_comparison; i++)
  777.                     weapons_comparison[i].Fire(rand, 1, rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked, chk_Ignore_Vertical_Recoil.Checked);
  778.                 if (weapons_comparison[0].ShotNumber > 1) time_elapsed += (float)weapons_comparison[0].Refire_Time / 1000;
  779.                 Invalidate();
  780.             }
  781.             if (e.KeyCode == Keys.D)
  782.             {
  783.                 for (int i = 0; i < number_of_weapons_in_comparison; i++)
  784.                     weapons_comparison[i].Fire(rand, -1, rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked, chk_Ignore_Vertical_Recoil.Checked);
  785.                 if (weapons_comparison[0].ShotNumber > 1) time_elapsed += (float)weapons_comparison[0].Refire_Time / 1000;
  786.                 Invalidate();
  787.             }
  788.         }
  789.         if (e.KeyCode == Keys.W && distance > 1)
  790.         {
  791.             distance--;
  792.             CalculatePixels();
  793.             Invalidate();
  794.         }
  795.         if (e.KeyCode == Keys.S)
  796.         {
  797.             distance++;
  798.             CalculatePixels();
  799.             Invalidate();
  800.         }
  801.     }
  802.  
  803.     private void DrawCalculations(PaintEventArgs e)
  804.     {
  805.  
  806.  
  807.  
  808.  
  809.  
  810.     }
  811.  
  812.     int[][] Calculate_tb_thresholds(Weapon w, float health, float damage_multiplier, int headshots)
  813.     {
  814.         int[][] arr = new int[w.Minimum_Damage_Range][];
  815.         float adjusted_health;
  816.         int range = 0;
  817.         int BTKn = 0;
  818.         arr[BTKn] = new int[5];
  819.         adjusted_health = (health - (float)(headshots * CalculateDamage(w, range) * (w.Headshot_Damage_Multiplier + 1))) / damage_multiplier;
  820.         arr[BTKn][0] = Convert.ToInt32(Math.Ceiling(adjusted_health / CalculateDamage(w, range)));
  821.         arr[BTKn][1] = 0;
  822.         arr[BTKn][3] = Convert.ToInt32(CalculateDamage(w, range));
  823.  
  824.         for (range = 0; range < w.Minimum_Damage_Range; range++)
  825.         {
  826.             adjusted_health = (health - (float)(headshots * CalculateDamage(w, range) * (w.Headshot_Damage_Multiplier + 1))) / damage_multiplier;
  827.             if (arr[BTKn][0] < Convert.ToInt32(Math.Ceiling(adjusted_health / CalculateDamage(w, range))))
  828.             {
  829.                 arr[BTKn][2] = range - 1;
  830.                 arr[BTKn][4] = Convert.ToInt32(CalculateDamage(w, range));
  831.                 BTKn++;
  832.                 arr[BTKn] = new int[5];
  833.                 arr[BTKn][0] = Convert.ToInt32(Math.Ceiling(adjusted_health / CalculateDamage(w, range)));
  834.                 arr[BTKn][1] = range;
  835.                 arr[BTKn][3] = Convert.ToInt32(CalculateDamage(w, range));
  836.             }
  837.         }
  838.         arr[BTKn][2] = range;
  839.  
  840.         return arr.Where(c => c != null).ToArray(); // removing empty members
  841.     }
  842.     protected override void OnMouseWheel(MouseEventArgs e)
  843.     {
  844.         //base.OnMouseWheel(e);
  845.         btn_Record.Focus();
  846.         Zoom += e.Delta / 120;
  847.         if (Zoom < 1) Zoom = 1;
  848.         CalculatePixels();
  849.     }
  850.     void btn_Reset_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  851.     {
  852.         Reset();
  853.     }
  854.     void btn_About_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  855.     {
  856.         MessageBox.Show("Version 1.7.\n\nWeapon database from: " + Database_Date + "\n\nOpen \"ReadMe.txt\" in the program folder for instructions.", "PlanetSide 2 Weapon Simulator");
  857.     }
  858.     void btn_Fire_Burst_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  859.     {
  860.         for (int i = 0; i < System.Convert.ToInt32(tb_Burst_Length.Text); i++) FireWeapons();
  861.         Invalidate();
  862.     }
  863.     void btn_Record_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  864.     {
  865.         Recording = !Recording;
  866.         Invalidate();
  867.     }
  868.     void btn_Save_Defaults_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  869.     {
  870.         if (File.Exists("settings.ini")) File.Delete("settings.ini");
  871.  
  872.         TextWriter tw = new StreamWriter("settings.ini", true);
  873.  
  874.         tw.WriteLine("ShowCoF=" + chk_ShowCoF.Checked);
  875.         tw.WriteLine("DrawBulletHits=" + chk_Draw_Bullet_Hits.Checked);
  876.         tw.WriteLine("ShowTolerance=" + chk_ShowTolerance.Checked);
  877.         tw.WriteLine("ShowRecoilPattern=" + chk_ShowRecoilPattern.Checked);
  878.         tw.WriteLine("DrawTarget=" + chk_Draw_Target.Checked);
  879.         tw.WriteLine("ShowConnectors=" + chk_ShowConnectors.Checked);
  880.         tw.WriteLine("ShowGrid=" + chk_ShowGrid.Checked);
  881.         tw.WriteLine("AngledGrid=" + chk_AngledGrid.Checked);
  882.         tw.WriteLine("IgnoreVerticalRecoil=" + chk_Ignore_Vertical_Recoil.Checked);
  883.         tw.WriteLine("DrawCrosshairPositions=" + chk_Draw_Crosshair_Positions.Checked);
  884.  
  885.         string mode = "Simulation";
  886.         if (mode_Simulation.Checked) mode = "Simulation";
  887.         if (mode_Graphs.Checked) mode = "Graphs";
  888.  
  889.         tw.WriteLine("Mode=" + mode);
  890.         tw.Close();
  891.         Invalidate();
  892.     }
  893.     void btn_Load_Defaults_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  894.     {
  895.         LoadDefaults();
  896.     }
  897.     void btn_Add_Comparison_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  898.     {
  899.         if (number_of_weapons_in_comparison < 9)
  900.         {
  901.             weapons_comparison[number_of_weapons_in_comparison++] = new Weapon(weapons_comparison[0]);
  902.             weapons_comparison[number_of_weapons_in_comparison - 1].Starting_X = weapons_comparison[number_of_weapons_in_comparison - 2].Starting_X - Vertical_Pixels * 4;
  903.             weapons_comparison[number_of_weapons_in_comparison - 1].Starting_Y = weapons_comparison[number_of_weapons_in_comparison - 2].Starting_Y;
  904.             weapons_comparison[number_of_weapons_in_comparison - 1].Stats = tb.Text;
  905.             weapons_comparison[number_of_weapons_in_comparison - 1].InitButton();
  906.             Controls.Add(weapons_comparison[number_of_weapons_in_comparison - 1].GetStats);
  907.         }
  908.         CalculatePixels();
  909.     }
  910.     void btn_Reset_Comparison_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  911.     {
  912.         for (int i = 1; i < number_of_weapons_in_comparison; i++) Controls.Remove(weapons_comparison[i].GetStats);
  913.         number_of_weapons_in_comparison = 1;
  914.         weapons_comparison[0].Starting_X = Width / 2;
  915.         weapons_comparison[0].Starting_Y = Height / 2;
  916.  
  917.         Invalidate();
  918.     }
  919.     void LoadDefaults()
  920.     {
  921.         //setting factory defaults if settings file doesn't exist
  922.         if (!File.Exists("settings.ini"))
  923.         {
  924.             TextWriter tw = new StreamWriter("settings.ini", true);
  925.             tw.WriteLine("ShowCoF=False");
  926.             tw.WriteLine("DrawBulletHits=False");
  927.             tw.WriteLine("ShowTolerance=True");
  928.             tw.WriteLine("ShowRecoilPattern=False");
  929.             tw.WriteLine("DrawTarget=False");
  930.             tw.WriteLine("ShowConnectors=True");
  931.             tw.WriteLine("ShowGrid=True");
  932.             tw.WriteLine("AngledGrid=True");
  933.             tw.WriteLine("IgnoreVerticalRecoil=False");
  934.             tw.WriteLine("DrawCrosshairPositions=True");
  935.             tw.WriteLine("Mode=Simulation");
  936.             tw.Close();
  937.             MessageBox.Show("Factory default settings loaded.", "settings.ini recreated");
  938.         }
  939.  
  940.         StreamReader reader = File.OpenText("settings.ini");
  941.         string line;
  942.         while ((line = reader.ReadLine()) != null)
  943.         {
  944.             if (line.StartsWith("ShowCoF=")) chk_ShowCoF.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  945.             if (line.StartsWith("DrawBulletHits=")) chk_Draw_Bullet_Hits.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  946.             if (line.StartsWith("ShowTolerance=")) chk_ShowTolerance.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  947.             if (line.StartsWith("ShowRecoilPattern=")) chk_ShowRecoilPattern.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  948.             if (line.StartsWith("DrawTarget=")) chk_Draw_Target.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  949.             if (line.StartsWith("ShowConnectors=")) chk_ShowConnectors.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  950.             if (line.StartsWith("ShowGrid=")) chk_ShowGrid.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  951.             if (line.StartsWith("AngledGrid=")) chk_AngledGrid.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  952.             if (line.StartsWith("IgnoreVerticalRecoil=")) chk_Ignore_Vertical_Recoil.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  953.             if (line.StartsWith("DrawCrosshairPositions=")) chk_Draw_Crosshair_Positions.Checked = System.Convert.ToBoolean(line.Substring(line.LastIndexOf('=') + 1));
  954.             if (line.StartsWith("Mode="))
  955.             {
  956.                 line = line.Substring(line.LastIndexOf('=') + 1);
  957.                 if (line == "Simulation") mode_Simulation.Checked = true;
  958.                 if (line == "Graphs") mode_Graphs.Checked = true;
  959.             }
  960.         }
  961.         reader.Close();
  962.         Invalidate();
  963.     }
  964.  
  965.  
  966.     void CalculatePixels()
  967.     {
  968.         /*if (ADSing == true) Vertical_Pixels = Zoom * GameResolution_Height / ((float)74 / (float)(ADS_Magnification * Zoom));
  969.         else Vertical_Pixels = GameResolution_Height / ((float)74 / (float)Zoom);*/
  970.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  971.         {
  972.             if (weapons_comparison[i] != null)
  973.             {
  974.                 //  weapons_comparison[i].Target_X -= weapons_comparison[i].Starting_X; //вычисляем расстояние между паттернами в градусах
  975.                 weapons_comparison[i].Target_X /= Vertical_Pixels;
  976.                 //  weapons_comparison[i].Target_Y -= weapons_comparison[i].Starting_Y; //вычисляем расстояние между паттернами в градусах
  977.                 weapons_comparison[i].Target_Y /= Vertical_Pixels;
  978.             }
  979.         }
  980.         for (int i = 1; i < number_of_weapons_in_comparison; i++)
  981.         {
  982.             weapons_comparison[i].Starting_X -= weapons_comparison[0].Starting_X; //вычисляем расстояние между паттернами в градусах
  983.             weapons_comparison[i].Starting_X /= Vertical_Pixels;
  984.             weapons_comparison[i].Starting_Y -= weapons_comparison[0].Starting_Y; //вычисляем расстояние между паттернами в градусах
  985.             weapons_comparison[i].Starting_Y /= Vertical_Pixels;
  986.         }
  987.  
  988.         if (rb_ADSing.Checked) Vertical_Pixels = (float)(33.3 * Zoom * ADS_Magnification);
  989.         else Vertical_Pixels = (float)33.3 * Zoom;
  990.  
  991.         for (int i = 1; i < number_of_weapons_in_comparison; i++)
  992.         {
  993.             weapons_comparison[i].Starting_X *= Vertical_Pixels; //вычисляем расстояние между паттернами в градусах
  994.             weapons_comparison[i].Starting_X += weapons_comparison[0].Starting_X;
  995.             weapons_comparison[i].Starting_Y *= Vertical_Pixels;
  996.             weapons_comparison[i].Starting_Y += weapons_comparison[0].Starting_Y;
  997.         }
  998.  
  999.  
  1000.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  1001.         {
  1002.             if (weapons_comparison[i] != null)
  1003.             {
  1004.                 weapons_comparison[i].Target_H = 32.02F * Vertical_Pixels / distance;
  1005.                 weapons_comparison[i].Target_W = 12.48F * Vertical_Pixels / distance;
  1006.  
  1007.                 weapons_comparison[i].Target_X *= Vertical_Pixels;
  1008.                 //weapons_comparison[i].Target_X += weapons_comparison[i].Starting_X; //вычисляем расстояние между паттернами в градусах
  1009.                 weapons_comparison[i].Target_Y *= Vertical_Pixels;
  1010.                 // weapons_comparison[i].Target_Y += weapons_comparison[i].Starting_Y; //вычисляем расстояние между паттернами в градусах
  1011.             }
  1012.         }
  1013.         Invalidate();
  1014.     }
  1015.     void Reset()
  1016.     {
  1017.         for (int i = 0; i < number_of_weapons_in_comparison; i++) weapons_comparison[i].Init();
  1018.         CalculatePixels();
  1019.         time_elapsed = 0;
  1020.  
  1021.         //RESET DAMAGE IN TTK SIMULATION
  1022.         headshots = 0; bodyshots = 0; legshots = 0;
  1023.         assign_damage = 0;
  1024.         target_health = Convert.ToInt32(tb_target_health.Text);
  1025.         Invalidate();
  1026.     }
  1027.     void chk_ShowCoF_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1028.     {
  1029.         Invalidate();
  1030.     }
  1031.     void chk_ShowTolerance_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1032.     {
  1033.         Invalidate();
  1034.     }
  1035.     void chk_ShowRecoilPattern_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1036.     {
  1037.         Invalidate();
  1038.     }
  1039.     void chk_ShowGrid_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1040.     {
  1041.         if (chk_ShowGrid.Checked && !mode_Graphs.Checked) chk_AngledGrid.Enabled = true;
  1042.         else chk_AngledGrid.Enabled = false;
  1043.         Invalidate();
  1044.     }
  1045.     void chk_ShowConnectors_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1046.     {
  1047.         Invalidate();
  1048.     }
  1049.     void chk_AngledGrid_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1050.     {
  1051.         Invalidate();
  1052.     }
  1053.     void chk_Draw_Crosshair_Positions_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1054.     {
  1055.         Invalidate();
  1056.     }
  1057.     void chk_Draw_Bullet_Hits_Click(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1058.     {
  1059.         Invalidate();
  1060.     }
  1061.     void chk_Draw_Target_CheckedChanged(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1062.     {
  1063.         for (int i = 0; i < number_of_weapons_in_comparison; i++)
  1064.         {
  1065.             if (weapons_comparison[i] != null)
  1066.             {
  1067.                 weapons_comparison[i].Target_X = 0;
  1068.                 weapons_comparison[i].Target_Y = 0;
  1069.             }
  1070.         }
  1071.         if(chk_Draw_Target.Checked && chk_Draw_Target.Enabled)
  1072.         {
  1073.             ConfigPanel_Label11.Show();
  1074.             group_target.Show();
  1075.             assign_damage = 0;
  1076.         }
  1077.         else
  1078.         {
  1079.             ConfigPanel_Label11.Hide();
  1080.             group_target.Hide();
  1081.         }
  1082.         Invalidate();
  1083.     }
  1084.     void ConfigurationPanel()
  1085.     {
  1086.  
  1087.         /*
  1088.         calculations = new GroupBox();
  1089.         calculations.Location = new Point(10, 10);
  1090.         calculations.Size = new Size(ConfigX - 20, Height - 15);
  1091.         Controls.Add(calculations);
  1092.         calculations.Hide();
  1093.  
  1094.  
  1095.  
  1096.         //TextBox Base_Health, Damage_Multiplier, Effective_Health, Range, BTK_tb_thresholds;
  1097.         //RadioButton SetHealth_Infantry, SetHealth_Infiltrator, SetHealth_MAX;
  1098.        // RadioButton SetResistance_Nano1, SetResistance_Nano2, SetResistance_Nano3, SetResistance_Nano4, SetResistance_Nano5;
  1099.  
  1100.  
  1101.  
  1102.         GroupBox target = new GroupBox();
  1103.         target.Size = new Size(300, 300);
  1104.         target.Location = new Point(10, 10);
  1105.  
  1106.         TextBox Base_Health = new TextBox();
  1107.         Base_Health.Location = new Point(10, 40);
  1108.         Base_Health.Text = "1000";
  1109.         Base_Health.Size = new Size(40, 10);
  1110.         target.Controls.Add(Base_Health);
  1111.         AddLabel(10, 20, 100, 20, "Base Health", DefaultFont, target);
  1112.  
  1113.         calculations.Controls.Add(target);*/
  1114.  
  1115.  
  1116.         // ================ END OF CALCULATIONS ============================
  1117.         btn_Reset = new Button();
  1118.         btn_Reset.Location = new Point(ConfigX + 5, ConfigY + 275);
  1119.         btn_Reset.Size = new Size(110, 30);
  1120.         btn_Reset.Text = "Reset Burst";
  1121.         btn_Reset.Click += new System.EventHandler(btn_Reset_Click);
  1122.         Controls.Add(btn_Reset);
  1123.  
  1124.         btn_Record = new CheckBox();
  1125.         btn_Record.Location = new Point(ConfigX + 125, ConfigY + 275);
  1126.         btn_Record.Size = new Size(110, 30);
  1127.         btn_Record.Text = "Record Pattern";
  1128.         btn_Record.Appearance = Appearance.Button;
  1129.         btn_Record.Checked = false;
  1130.         btn_Record.TextAlign = ContentAlignment.MiddleCenter;
  1131.         btn_Record.Click += new System.EventHandler(btn_Record_Click);
  1132.         Controls.Add(btn_Record);
  1133.  
  1134.         btn_Fire_Burst = new Button();
  1135.         btn_Fire_Burst.Location = new Point(ConfigX + 5, ConfigY + 310);
  1136.         btn_Fire_Burst.Size = new Size(110, 30);
  1137.         btn_Fire_Burst.Text = "Fire Fixed Burst";
  1138.         btn_Fire_Burst.Click += new System.EventHandler(btn_Fire_Burst_Click);
  1139.         Controls.Add(btn_Fire_Burst);
  1140.  
  1141.         Button btn_About = new Button();
  1142.         btn_About.Location = new Point(ConfigX + 5, ConfigY + 415);
  1143.         btn_About.Size = new Size(230, 30);
  1144.         btn_About.Text = "Help / About";
  1145.         btn_About.Click += new System.EventHandler(btn_About_Click);
  1146.         Controls.Add(btn_About);
  1147.  
  1148.         Button btn_Save_Defaults = new Button();
  1149.         btn_Save_Defaults.Location = new Point(ConfigX + 5, ConfigY + 380);
  1150.         btn_Save_Defaults.Size = new Size(110, 30);
  1151.         btn_Save_Defaults.Text = "Save Configuration";
  1152.         btn_Save_Defaults.Click += new System.EventHandler(btn_Save_Defaults_Click);
  1153.         Controls.Add(btn_Save_Defaults);
  1154.  
  1155.         Button btn_Load_Defaults = new Button();
  1156.         btn_Load_Defaults.Location = new Point(ConfigX + 125, ConfigY + 380);
  1157.         btn_Load_Defaults.Size = new Size(110, 30);
  1158.         btn_Load_Defaults.Text = "Load Configuration";
  1159.         btn_Load_Defaults.Click += new System.EventHandler(btn_Load_Defaults_Click);
  1160.         Controls.Add(btn_Load_Defaults);
  1161.  
  1162.         Label ConfigPanel_Label = AddLabel(ConfigX + 50, ConfigY - 10, 141, 30, "Configuration", new Font(DefaultFont.FontFamily, 16));
  1163.         Label ConfigPanel_Label2 = AddLabel(ConfigX + 70, ConfigY + 240, 95, 30, "Controls", new Font(DefaultFont.FontFamily, 16));
  1164.         ConfigPanel_Label3 = AddLabel(ConfigX - 218, ConfigY - 10, 208, 30, "Firing Session Stats", new Font(DefaultFont.FontFamily, 16));
  1165.         Label ConfigPanel_Label4 = AddLabel(ConfigX + 50, ConfigY + 455, 150, 30, "Weapon Stats", new Font(DefaultFont.FontFamily, 16));
  1166.         Label ConfigPanel_Label5 = AddLabel(ConfigX + 50, ConfigY + 770, 180, 30, "Attachments", new Font(DefaultFont.FontFamily, 16));
  1167.         Label ConfigPanel_Label6 = AddLabel(ConfigX + 90, ConfigY + 920, 150, 30, "Optic", new Font(DefaultFont.FontFamily, 12));
  1168.         ConfigPanel_Label7 = AddLabel(ConfigX - 160, ConfigY + 275, 80, 30, "Stance", new Font(DefaultFont.FontFamily, 16));
  1169.         Label ConfigPanel_Label8 = AddLabel(ConfigX + 300, ConfigY + 120, 150, 30, "Weapon", new Font(DefaultFont.FontFamily, 16));
  1170.         Label ConfigPanel_Label9 = AddLabel(ConfigX + 270, ConfigY - 10, 200, 30, "Program Mode", new Font(DefaultFont.FontFamily, 16));
  1171.         ConfigPanel_Label10 = AddLabel(ConfigX - 185, ConfigY + 435, 140, 30, "Bullets to Kill", new Font(DefaultFont.FontFamily, 16));
  1172.         ConfigPanel_Label11 = AddLabel(ConfigX - 195, ConfigY + 700, 160, 30, "TTK Simulation", new Font(DefaultFont.FontFamily, 16));
  1173.  
  1174.         chk_ShowCoF = new CheckBox();
  1175.         chk_ShowCoF.Location = new Point(ConfigX + 5, ConfigY + 20);
  1176.         chk_ShowCoF.Text = "Show Cone of Fire";
  1177.         chk_ShowCoF.Size = new Size(120, 30);
  1178.         chk_ShowCoF.Click += new System.EventHandler(chk_ShowCoF_Click);
  1179.         Controls.Add(chk_ShowCoF);
  1180.  
  1181.         chk_ShowTolerance = new CheckBox();
  1182.         chk_ShowTolerance.Location = new Point(ConfigX + 5, ConfigY + 50);
  1183.         chk_ShowTolerance.Text = "Show Horizontal Recoil Tolerance";
  1184.         chk_ShowTolerance.Size = new Size(200, 30);
  1185.         chk_ShowTolerance.Click += new System.EventHandler(chk_ShowTolerance_Click);
  1186.         Controls.Add(chk_ShowTolerance);
  1187.  
  1188.         chk_ShowRecoilPattern = new CheckBox();
  1189.         chk_ShowRecoilPattern.Location = new Point(ConfigX + 5, ConfigY + 80);
  1190.         chk_ShowRecoilPattern.Text = "Show Recoil Pattern";
  1191.         chk_ShowRecoilPattern.Size = new Size(125, 30);
  1192.         chk_ShowRecoilPattern.Click += new System.EventHandler(chk_ShowRecoilPattern_Click);
  1193.         Controls.Add(chk_ShowRecoilPattern);
  1194.  
  1195.         chk_ShowConnectors = new CheckBox();
  1196.         chk_ShowConnectors.Location = new Point(ConfigX + 5, ConfigY + 110);
  1197.         chk_ShowConnectors.Text = "Show Connectors";
  1198.         chk_ShowConnectors.Size = new Size(110, 30);
  1199.         chk_ShowConnectors.Click += new System.EventHandler(chk_ShowConnectors_Click);
  1200.         Controls.Add(chk_ShowConnectors);
  1201.  
  1202.         chk_ShowGrid = new CheckBox();
  1203.         chk_ShowGrid.Location = new Point(ConfigX + 5, ConfigY + 140);
  1204.         chk_ShowGrid.Text = "Show Grid";
  1205.         chk_ShowGrid.Size = new Size(100, 30);
  1206.         chk_ShowGrid.Click += new System.EventHandler(chk_ShowGrid_Click);
  1207.         Controls.Add(chk_ShowGrid);
  1208.  
  1209.         chk_AngledGrid = new CheckBox();
  1210.         chk_AngledGrid.Location = new Point(ConfigX + 135, ConfigY + 140);
  1211.         chk_AngledGrid.Text = "Angled Grid";
  1212.         chk_AngledGrid.Size = new Size(100, 30);
  1213.         chk_AngledGrid.Enabled = true;
  1214.         chk_AngledGrid.Click += new System.EventHandler(chk_AngledGrid_Click);
  1215.         Controls.Add(chk_AngledGrid);
  1216.  
  1217.         chk_Ignore_Vertical_Recoil = new CheckBox();
  1218.         chk_Ignore_Vertical_Recoil.Location = new Point(ConfigX + 5, ConfigY + 170);
  1219.         chk_Ignore_Vertical_Recoil.Text = "Ignore Vertical Recoil";
  1220.         chk_Ignore_Vertical_Recoil.Size = new Size(200, 30);
  1221.         chk_Ignore_Vertical_Recoil.CheckedChanged += CheckAttachments;
  1222.         Controls.Add(chk_Ignore_Vertical_Recoil);
  1223.  
  1224.         //weapon stats textbox
  1225.         tb = new TextBox();
  1226.         tb.Location = new Point(ConfigX, ConfigY + 485);
  1227.         tb.Size = new Size(240, 280);
  1228.         tb.ScrollBars = ScrollBars.Vertical;
  1229.         tb.Multiline = true;
  1230.         tb.ReadOnly = true;
  1231.         Controls.Add(tb);
  1232.  
  1233.         //weapon list
  1234.         lb = new ListBox();
  1235.         lb.Location = new Point(Width - 200, 160);
  1236.         lb.Size = new Size(200, 855);
  1237.         Controls.Add(lb);
  1238.  
  1239.         lb.BeginUpdate();
  1240.         for (int i = 0; i < number_of_weapons; i++) lb.Items.Add(weapons[i].Type + "   " + weapons[i].Weapon_Name);
  1241.         lb.EndUpdate();
  1242.         lb.SelectedIndexChanged += Lb_Click;
  1243.  
  1244.         chk_Draw_Crosshair_Positions = new CheckBox();
  1245.         chk_Draw_Crosshair_Positions.Location = new Point(ConfigX + 5, ConfigY + 200);
  1246.         chk_Draw_Crosshair_Positions.Text = "Show Crosshair Positions";
  1247.         chk_Draw_Crosshair_Positions.Size = new Size(200, 30);
  1248.         chk_Draw_Crosshair_Positions.Click += new System.EventHandler(chk_Draw_Bullet_Hits_Click);
  1249.         Controls.Add(chk_Draw_Crosshair_Positions);
  1250.  
  1251.         chk_Draw_Bullet_Hits = new CheckBox();
  1252.         chk_Draw_Bullet_Hits.Location = new Point(ConfigX + 135, ConfigY + 20);
  1253.         chk_Draw_Bullet_Hits.Text = "Draw Bullet Hits";
  1254.         chk_Draw_Bullet_Hits.Size = new Size(105, 30);
  1255.         chk_Draw_Bullet_Hits.Click += new System.EventHandler(chk_Draw_Bullet_Hits_Click);
  1256.         Controls.Add(chk_Draw_Bullet_Hits);
  1257.  
  1258.         chk_Draw_Target = new CheckBox();
  1259.         chk_Draw_Target.Location = new Point(ConfigX + 135, ConfigY + 80);
  1260.         chk_Draw_Target.Text = "Draw Target";
  1261.         chk_Draw_Target.Size = new Size(100, 30);
  1262.         chk_Draw_Target.CheckedChanged += new System.EventHandler(chk_Draw_Target_CheckedChanged);
  1263.         chk_Draw_Target.EnabledChanged += new System.EventHandler(chk_Draw_Target_CheckedChanged);
  1264.         Controls.Add(chk_Draw_Target);
  1265.  
  1266.         tb_Burst_Length = new TextBox();
  1267.         tb_Burst_Length.Size = new Size(110, 30);
  1268.         tb_Burst_Length.Multiline = true;
  1269.         tb_Burst_Length.Location = new Point(ConfigX + 125, ConfigY + 310);
  1270.         tb_Burst_Length.Text = "10";
  1271.         Controls.Add(tb_Burst_Length);
  1272.  
  1273.         //Firing Session stats textbox
  1274.         burst_stats = new TextBox();
  1275.         burst_stats.Size = new Size(209, 250);
  1276.         burst_stats.Multiline = true;
  1277.         burst_stats.Location = new Point(ConfigX - 218, ConfigY + 20);
  1278.         burst_stats.ReadOnly = true;
  1279.         Controls.Add(burst_stats);
  1280.  
  1281.         Button btn_Add_Comparison = new Button();
  1282.         btn_Add_Comparison.Location = new Point(ConfigX + 5, ConfigY + 345);
  1283.         btn_Add_Comparison.Size = new Size(110, 30);
  1284.         btn_Add_Comparison.Text = "Add to comparison";
  1285.         btn_Add_Comparison.Click += new System.EventHandler(btn_Add_Comparison_Click);
  1286.         Controls.Add(btn_Add_Comparison);
  1287.  
  1288.         Button btn_Reset_Comparison = new Button();
  1289.         btn_Reset_Comparison.Location = new Point(ConfigX + 125, ConfigY + 345);
  1290.         btn_Reset_Comparison.Size = new Size(110, 30);
  1291.         btn_Reset_Comparison.Text = "Reset comparison";
  1292.         btn_Reset_Comparison.Click += new System.EventHandler(btn_Reset_Comparison_Click);
  1293.         Controls.Add(btn_Reset_Comparison);
  1294.  
  1295.         // ===== BTK tb_thresholds textbox
  1296.         group_thresholds = new GroupBox();
  1297.         group_thresholds.Location = new Point(ConfigX - 218, ConfigY + 465);
  1298.         group_thresholds.Size = new Size(209, 230);
  1299.         Controls.Add(group_thresholds);
  1300.  
  1301.         btn_show_help = new Button();
  1302.         btn_show_help.Size = new Size(90, 40);
  1303.         btn_show_help.Location = new Point(109, 180);
  1304.         btn_show_help.Click += btn_show_help_Click;
  1305.         btn_show_help.Text = "Legend";
  1306.         group_thresholds.Controls.Add(btn_show_help);
  1307.  
  1308.         tb_bonus_headshots = new TextBox();
  1309.         tb_bonus_headshots.Location = new Point(10, 200);
  1310.         tb_bonus_headshots.Size = new Size(90, 30);
  1311.         tb_bonus_headshots.Text = "0";
  1312.         tb_bonus_headshots.TextChanged += tb_damage_multiplier_TextChanged;
  1313.         group_thresholds.Controls.Add(tb_bonus_headshots);
  1314.         AddLabel(10, 180, 100, 20, "Bonus Headshots", DefaultFont, group_thresholds);
  1315.  
  1316.         tb_thresholds = new TextBox();
  1317.         tb_thresholds.Location = new Point(5, 60);
  1318.         tb_thresholds.Size = new Size(199, 110);
  1319.         tb_thresholds.Multiline = true; tb_thresholds.ReadOnly = true;
  1320.         tb_thresholds.ScrollBars = ScrollBars.Vertical;
  1321.         group_thresholds.Controls.Add(tb_thresholds);
  1322.  
  1323.         tb_target_health = new TextBox();
  1324.         tb_target_health.Location = new Point(10, 30);
  1325.         tb_target_health.Size = new Size(90, 30);
  1326.         tb_target_health.Text = "1000";
  1327.         tb_target_health.TextChanged += tb_damage_multiplier_TextChanged;
  1328.         tb_target_health.TextChanged += tb_target_health_TextChanged;
  1329.         group_thresholds.Controls.Add(tb_target_health);
  1330.  
  1331.         tb_damage_multiplier = new TextBox();
  1332.         tb_damage_multiplier.Location = new Point(110, 30);
  1333.         tb_damage_multiplier.Size = new Size(90, 30);
  1334.         tb_damage_multiplier.Text = "1,0";
  1335.         tb_damage_multiplier.TextChanged += tb_damage_multiplier_TextChanged;
  1336.         group_thresholds.Controls.Add(tb_damage_multiplier);
  1337.         AddLabel(110, 10, 90, 20, "Damage Mult.", DefaultFont, group_thresholds);
  1338.  
  1339.         AddLabel(10, 10, 90, 20, "Target Health", DefaultFont, group_thresholds);
  1340.  
  1341.        
  1342.         //TTK SIMULATION
  1343.         group_target = new GroupBox();
  1344.         group_target.Location = new Point(ConfigX - 218, ConfigY + 730);
  1345.         group_target.Size = new Size(209, 250);
  1346.         Controls.Add(group_target);
  1347.  
  1348.         tb_target = new TextBox();
  1349.         tb_target.Size = new Size(199, 100);
  1350.         tb_target.Location = new Point(5, 10);
  1351.         tb_target.ReadOnly = true; tb_target.Multiline = true;
  1352.         group_target.Controls.Add(tb_target);
  1353.  
  1354.         tb_pause = new TextBox();
  1355.         tb_pause.Location = new Point(5, 120);
  1356.         tb_pause.Size = new Size(95, 30);
  1357.         tb_pause.ReadOnly = true;
  1358.         group_target.Controls.Add(tb_pause);
  1359.  
  1360.         Button btn_pause = new Button();
  1361.         btn_pause.Text = "Reset CoF";
  1362.         btn_pause.Size = new Size(100, 30);
  1363.         btn_pause.Location = new Point(105, 115);
  1364.         btn_pause.Click += btn_pause_Click;
  1365.         group_target.Controls.Add(btn_pause);
  1366.  
  1367.         AddLabel(40, 150, 140, 30, "Assign Damage", new Font(DefaultFont.FontFamily,12), group_target);
  1368.  
  1369.         btn_headshot = new Button();
  1370.         btn_headshot.Location = new Point(5, 180);
  1371.         btn_headshot.Size = new Size(95, 30);
  1372.         btn_headshot.Text = "Head";
  1373.         btn_headshot.Click += btn_headshot_Click;
  1374.         group_target.Controls.Add(btn_headshot);
  1375.  
  1376.         btn_bodyshot = new Button();
  1377.         btn_bodyshot.Location = new Point(110, 180);
  1378.         btn_bodyshot.Size = new Size(95, 30);
  1379.         btn_bodyshot.Text = "Body";
  1380.         btn_bodyshot.Click += btn_bodyshot_Click;
  1381.         group_target.Controls.Add(btn_bodyshot);
  1382.  
  1383.         btn_legshot = new Button();
  1384.         btn_legshot.Location = new Point(5, 215);
  1385.         btn_legshot.Size = new Size(95, 30);
  1386.         btn_legshot.Text = "Legs";
  1387.         btn_legshot.Click += btn_legshot_Click;
  1388.         group_target.Controls.Add(btn_legshot);
  1389.  
  1390.         Button btn_reset_damage = new Button();
  1391.         btn_reset_damage.Location = new Point(110, 215);
  1392.         btn_reset_damage.Size = new Size(95, 30);
  1393.         btn_reset_damage.Text = "Reset";
  1394.         btn_reset_damage.Click += btn_reset_damage_Click;
  1395.         group_target.Controls.Add(btn_reset_damage);
  1396.  
  1397.         ConfigPanel_Label11.Hide();
  1398.         group_target.Hide();
  1399.  
  1400.         // ############ ATTACHMENTS #############
  1401.         {
  1402.             chk_FG = CreateCheckBox("Forward Grip", ConfigX + 80, ConfigY + 800);
  1403.             chk_AFG = CreateCheckBox("Advanced", ConfigX, ConfigY + 800);
  1404.  
  1405.             chk_LS = CreateCheckBox("Laser Sight", ConfigX + 80, ConfigY + 820);
  1406.             chk_ALS = CreateCheckBox("Advanced", ConfigX, ConfigY + 820);
  1407.  
  1408.             chk_ExMags = CreateCheckBox("Extended Magazine", ConfigX, ConfigY + 840);
  1409.             chk_ExMags.Size = new Size(150, 30);
  1410.  
  1411.             chk_SPA = CreateCheckBox("Soft Point Ammo", ConfigX + 130, ConfigY + 865);
  1412.             chk_SPA.Size = new Size(150, 30);
  1413.             chk_HVA = CreateCheckBox("High Velocity Ammo", ConfigX, ConfigY + 865);
  1414.             chk_HVA.Size = new Size(150, 30);
  1415.  
  1416.             chk_Slugs = CreateCheckBox("Slug Ammunition", ConfigX, ConfigY + 865);
  1417.             chk_Slugs.Size = new Size(120, 30);
  1418.             chk_SmartChoke = CreateCheckBox("Smart Choke", ConfigX + 130, ConfigY + 865);
  1419.             chk_SmartChoke.Size = new Size(120, 30);
  1420.  
  1421.             chk_Compensator = CreateCheckBox("Compensator", ConfigX, ConfigY + 890);
  1422.             chk_Suppressor = CreateCheckBox("Suppressor", ConfigX + 130, ConfigY + 890);
  1423.  
  1424.             Optic_1x = CreateRadioButton("1x", ConfigX, ConfigY + 950);
  1425.             Optic_2x = CreateRadioButton("2x", ConfigX + 40, ConfigY + 950);
  1426.             Optic_3_4x = CreateRadioButtonW("3.4x", ConfigX + 80, ConfigY + 950);
  1427.             Optic_4x = CreateRadioButton("4x", ConfigX + 125, ConfigY + 950);
  1428.             Optic_6x = CreateRadioButton("6x", ConfigX + 165, ConfigY + 950);
  1429.  
  1430.             Optic_7x = CreateRadioButtonW("7x", ConfigX, ConfigY + 975);
  1431.             Optic_8x = CreateRadioButtonW("8x", ConfigX + 45, ConfigY + 975);
  1432.             Optic_10x = CreateRadioButtonW("10x", ConfigX + 90, ConfigY + 975);
  1433.             Optic_12x = CreateRadioButtonW("12x", ConfigX + 135, ConfigY + 975);
  1434.             Optic_1x.Checked = true;
  1435.         }
  1436.         lb.SetSelected(0, true);
  1437.  
  1438.         //STANCE
  1439.         group_Stand_Crouch = new GroupBox();
  1440.         group_Stand_Crouch.Location = new Point(ConfigX - 218, ConfigY + 300);
  1441.         group_Stand_Crouch.Size = new Size(208, 50);
  1442.  
  1443.         rb_Standing = new RadioButton();
  1444.         rb_Standing.Location = new Point(10, 12);
  1445.         rb_Standing.Size = new Size(80, 30);
  1446.         rb_Standing.Text = "Standing";
  1447.         group_Stand_Crouch.Controls.Add(rb_Standing);
  1448.  
  1449.  
  1450.         rb_Crouching = new RadioButton();
  1451.         rb_Crouching.Location = new Point(100, 12);
  1452.         rb_Crouching.Size = new Size(80, 30);
  1453.         rb_Crouching.Text = "Crouching";
  1454.         group_Stand_Crouch.Controls.Add(rb_Crouching);
  1455.  
  1456.         rb_Standing.Checked = true;
  1457.         rb_Standing.CheckedChanged += Rb_Moving_CheckedChanged;
  1458.         Controls.Add(group_Stand_Crouch);
  1459.  
  1460.         group_Still_Moving = new GroupBox();
  1461.         group_Still_Moving.Location = new Point(ConfigX - 218, ConfigY + 340);
  1462.         group_Still_Moving.Size = new Size(208, 50);
  1463.  
  1464.         rb_Still = new RadioButton();
  1465.         rb_Still.Location = new Point(10, 12);
  1466.         rb_Still.Size = new Size(80, 30);
  1467.         rb_Still.Text = "Still";
  1468.         group_Still_Moving.Controls.Add(rb_Still);
  1469.  
  1470.  
  1471.         rb_Moving = new RadioButton();
  1472.         rb_Moving.Location = new Point(100, 12);
  1473.         rb_Moving.Size = new Size(80, 30);
  1474.         rb_Moving.Text = "Moving";
  1475.  
  1476.         group_Still_Moving.Controls.Add(rb_Moving);
  1477.  
  1478.         rb_Still.Checked = true;
  1479.         rb_Moving.CheckedChanged += Rb_Moving_CheckedChanged;
  1480.         Controls.Add(group_Still_Moving);
  1481.  
  1482.  
  1483.         group_ADSing = new GroupBox();
  1484.         group_ADSing.Location = new Point(ConfigX - 218, ConfigY + 380);
  1485.         group_ADSing.Size = new Size(208, 50);
  1486.  
  1487.  
  1488.         group_ADSing.Controls.Add(rb_ADSing);
  1489.  
  1490.  
  1491.         rb_HipFiring = new RadioButton();
  1492.         rb_HipFiring.Location = new Point(100, 12);
  1493.         rb_HipFiring.Size = new Size(80, 30);
  1494.         rb_HipFiring.Text = "Hip firing";
  1495.         group_ADSing.Controls.Add(rb_HipFiring);
  1496.  
  1497.         rb_HipFiring.Checked = true;
  1498.         Controls.Add(group_ADSing);
  1499.  
  1500.         GroupBox mode = new GroupBox();
  1501.         mode.Location = new Point(ConfigX + 250, ConfigY + 20);
  1502.         mode.Size = new Size(200, 90);
  1503.  
  1504.         mode_Graphs = new RadioButton();
  1505.         mode_Graphs.Text = "Graphs";
  1506.         mode_Graphs.Font = new Font(DefaultFont.FontFamily, 14);
  1507.         mode_Graphs.Size = new Size(150, 30);
  1508.         mode_Graphs.Location = new Point(30, 10);
  1509.         mode_Graphs.CheckedChanged += mode_Graphs_CheckedChanged;
  1510.         mode.Controls.Add(mode_Graphs);
  1511.  
  1512.         mode_Simulation = new RadioButton();
  1513.         mode_Simulation.Text = "Simulation";
  1514.         mode_Simulation.Font = new Font(DefaultFont.FontFamily, 14);
  1515.         mode_Simulation.Size = new Size(150, 30);
  1516.         mode_Simulation.Location = new Point(30, 50);
  1517.         mode_Simulation.CheckedChanged += mode_Simulation_CheckedChanged;
  1518.  
  1519.         mode.Controls.Add(mode_Simulation);
  1520.         Controls.Add(mode);
  1521.     }
  1522.  
  1523.     void btn_legshot_Click(object sender, EventArgs e)
  1524.     {
  1525.         if (weapons_comparison[0].ShotNumber * weapons_comparison[0].Pellets - assign_damage > 0)
  1526.         {
  1527.             legshots++;
  1528.             assign_damage++;
  1529.             target_health -= Convert.ToInt32(0.9 * Convert.ToDouble(tb_damage_multiplier.Text) * CalculateDamage(weapons_comparison[0], distance));
  1530.             Invalidate();
  1531.         }
  1532.     }
  1533.  
  1534.     void btn_bodyshot_Click(object sender, EventArgs e)
  1535.     {
  1536.         if (weapons_comparison[0].ShotNumber * weapons_comparison[0].Pellets - assign_damage > 0)
  1537.         {
  1538.             bodyshots++;
  1539.             assign_damage++;
  1540.             target_health -= Convert.ToInt32(Convert.ToDouble(tb_damage_multiplier.Text) * CalculateDamage(weapons_comparison[0], distance));
  1541.             Invalidate();
  1542.         }
  1543.     }
  1544.  
  1545.     void btn_pause_Click(object sender, EventArgs e)
  1546.     {
  1547.         time_elapsed += (float)Convert.ToDouble(tb_pause.Text);
  1548.         weapons_comparison[0].CurrentCoF = weapons_comparison[0].GetCurrentMinimumCoF(rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked);
  1549.         Invalidate();
  1550.     }
  1551.  
  1552.     void tb_target_health_TextChanged(object sender, EventArgs e)
  1553.     {
  1554.         target_health = Convert.ToInt32(tb_target_health.Text);
  1555.         Invalidate();
  1556.     }
  1557.  
  1558.     void btn_reset_damage_Click(object sender, EventArgs e)
  1559.     {
  1560.         headshots = 0; bodyshots = 0; legshots = 0;
  1561.         assign_damage = 0;
  1562.         target_health = Convert.ToInt32(tb_target_health.Text);
  1563.         Invalidate();
  1564.     }
  1565.  
  1566.     void btn_headshot_Click(object sender, EventArgs e)
  1567.     {
  1568.         if (weapons_comparison[0].ShotNumber * weapons_comparison[0].Pellets - assign_damage > 0)
  1569.         {
  1570.             headshots++;
  1571.             assign_damage++;
  1572.             target_health -= Convert.ToInt32((weapons_comparison[0].Headshot_Damage_Multiplier +1) * CalculateDamage(weapons_comparison[0], distance));
  1573.             Invalidate();
  1574.         }
  1575.     }
  1576.  
  1577.     private void btn_show_help_Click(object sender, EventArgs e)
  1578.     {
  1579.         show_help = !show_help;
  1580.         Invalidate();
  1581.     }
  1582.  
  1583.     private void tb_damage_multiplier_TextChanged(object sender, EventArgs e)
  1584.     {
  1585.         WriteWeaponStats();
  1586.     }
  1587.  
  1588.     private void mode_Simulation_CheckedChanged(object sender, EventArgs e)
  1589.     {
  1590.         if (mode_Simulation.Checked)
  1591.         {
  1592.             chk_Draw_Bullet_Hits.Enabled = true;
  1593.             chk_Draw_Crosshair_Positions.Enabled = true;
  1594.             chk_Draw_Target.Enabled = true;
  1595.             chk_Ignore_Vertical_Recoil.Enabled = true;
  1596.             chk_ShowConnectors.Enabled = true;
  1597.             chk_ShowRecoilPattern.Enabled = true;
  1598.             chk_ShowTolerance.Enabled = true;
  1599.             chk_ShowCoF.Enabled = true;
  1600.            
  1601.             if (chk_ShowGrid.Checked) chk_AngledGrid.Enabled = true;
  1602.             ConfigPanel_Label3.Show();
  1603.             burst_stats.Show();
  1604.             ConfigPanel_Label10.Show();
  1605.             group_thresholds.Show();
  1606.             tb_thresholds.Show();
  1607.             ConfigPanel_Label7.Show();
  1608.             group_Still_Moving.Show();
  1609.             group_ADSing.Show();
  1610.             group_Stand_Crouch.Show();
  1611.             btn_Fire_Burst.Enabled = true;
  1612.             btn_Reset.Enabled = true;
  1613.             btn_Record.Enabled = true;
  1614.             tb_Burst_Length.Enabled = true;
  1615.         }
  1616.         Invalidate();
  1617.     }
  1618.  
  1619.     private void mode_Graphs_CheckedChanged(object sender, EventArgs e)
  1620.     {
  1621.         if (mode_Graphs.Checked)
  1622.         {
  1623.             chk_Draw_Bullet_Hits.Enabled = false;
  1624.             chk_Draw_Crosshair_Positions.Enabled = false;
  1625.             chk_Draw_Target.Enabled = false;
  1626.             chk_Ignore_Vertical_Recoil.Enabled = false;
  1627.             chk_ShowConnectors.Enabled = false;
  1628.             chk_ShowRecoilPattern.Enabled = false;
  1629.             chk_ShowTolerance.Enabled = false;
  1630.             chk_ShowCoF.Enabled = false;
  1631.             chk_AngledGrid.Enabled = false;
  1632.             ConfigPanel_Label10.Hide();
  1633.             group_thresholds.Hide();
  1634.             ConfigPanel_Label3.Hide();
  1635.             burst_stats.Hide();
  1636.             tb_thresholds.Hide();
  1637.             ConfigPanel_Label7.Hide();
  1638.             group_Still_Moving.Hide();
  1639.             group_ADSing.Hide();
  1640.             group_Stand_Crouch.Hide();
  1641.             btn_Fire_Burst.Enabled = false;
  1642.             btn_Reset.Enabled = false;
  1643.             btn_Record.Enabled = false;
  1644.             tb_Burst_Length.Enabled = false;
  1645.         }
  1646.         Invalidate();
  1647.     }
  1648.  
  1649.     private void Rb_Moving_CheckedChanged(object sender, EventArgs e)
  1650.     {
  1651.         UpdateBurstStats();
  1652.     }
  1653.  
  1654.     CheckBox CreateCheckBox(string title, int X, int Y)
  1655.     {
  1656.         CheckBox chk = new CheckBox();
  1657.         chk.Text = title;
  1658.         chk.Location = new Point(X, Y);
  1659.         chk.CheckedChanged += CheckAttachments;
  1660.         chk.CheckedChanged += btn_Reset_Click;
  1661.         Controls.Add(chk);
  1662.         return chk;
  1663.     }
  1664.     Label AddLabel(int X, int Y, int W, int H, string text, Font font)
  1665.     {
  1666.         Label label = new Label();
  1667.         label.Location = new Point(X, Y);
  1668.         label.Size = new Size(W, H);
  1669.         label.Text = text;
  1670.         label.Font = font;
  1671.         Controls.Add(label);
  1672.         return label;
  1673.     }
  1674.     Label AddLabel(int X, int Y, int W, int H, string text, Font font, GroupBox groupbox)
  1675.     {
  1676.         Label label = new Label();
  1677.         label.Location = new Point(X, Y);
  1678.         label.Size = new Size(W, H);
  1679.         label.Text = text;
  1680.         label.Font = font;
  1681.         groupbox.Controls.Add(label);
  1682.         return label;
  1683.     }
  1684.  
  1685.  
  1686.     RadioButton CreateRadioButton(string title, int X, int Y)
  1687.     {
  1688.         RadioButton rb = new RadioButton();
  1689.         rb.Text = title;
  1690.         rb.Location = new Point(X, Y);
  1691.         rb.Width = 40;
  1692.         rb.CheckedChanged += Rb_CheckedChanged;
  1693.         Controls.Add(rb);
  1694.         return rb;
  1695.     }
  1696.     RadioButton CreateRadioButtonW(string title, int X, int Y)
  1697.     {
  1698.         RadioButton rb = new RadioButton();
  1699.         rb.Text = title;
  1700.         rb.Location = new Point(X, Y);
  1701.         rb.Width = 45;
  1702.         rb.CheckedChanged += Rb_CheckedChanged;
  1703.         Controls.Add(rb);
  1704.         return rb;
  1705.     }
  1706.  
  1707.     private void Rb_CheckedChanged(object sender, EventArgs e)
  1708.     {
  1709.         ADS_Magnification = 1.35 * Convert.ToInt32(Optic_1x.Checked) + 2 * Convert.ToInt32(Optic_2x.Checked) + 3.4 * Convert.ToInt32(Optic_3_4x.Checked) + 4 * Convert.ToInt32(Optic_4x.Checked) +
  1710.             6 * Convert.ToInt32(Optic_6x.Checked) + 7 * Convert.ToInt32(Optic_7x.Checked) + 8 * Convert.ToInt32(Optic_8x.Checked) + 10 * Convert.ToInt32(Optic_10x.Checked) + 12 * Convert.ToInt32(Optic_12x.Checked);
  1711.         CalculatePixels();
  1712.         Invalidate();
  1713.     }
  1714.  
  1715.     void UpdateBurstStats()
  1716.     {
  1717.         burst_stats.Text = null;
  1718.  
  1719.  
  1720.  
  1721.         if (rb_ADSing.Checked) burst_stats.AppendText("Aiming Down Sights");
  1722.         else burst_stats.AppendText("Hip firing");
  1723.  
  1724.         if (rb_Standing.Checked) burst_stats.AppendText(" while standing ");
  1725.         else burst_stats.AppendText(" while crouching ");
  1726.  
  1727.         if (rb_Moving.Checked) burst_stats.AppendText("moving.\n");
  1728.         else burst_stats.AppendText("still.\n");
  1729.         if (rb_ADSing.Checked) burst_stats.AppendText("ADS Magnification: " + ADS_Magnification + "x\n");
  1730.  
  1731.         burst_stats.AppendText("Screen Zoom: " + Zoom + "x\n");
  1732.         burst_stats.AppendText("Current Cone of Fire: " + weapons_comparison[0].GetCurrentCoF(rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked) + " degrees\n");
  1733.  
  1734.         burst_stats.AppendText("\n");
  1735.         burst_stats.AppendText("### CONTROLS ###\n");
  1736.         burst_stats.AppendText("Left Mouse Button to fire.\n");
  1737.         burst_stats.AppendText("Right Mouse Button to ADS.\n");
  1738.         burst_stats.AppendText("Middle Mouse Button - hold and drag to move recoil pattern.\n");
  1739.         burst_stats.AppendText("Mouse wheel to change zoom.");
  1740.         if (chk_ShowGrid.Checked)
  1741.         {
  1742.             burst_stats.AppendText("\n");
  1743.             burst_stats.AppendText("\n");
  1744.             burst_stats.AppendText("Grid enabled.\n");
  1745.             burst_stats.AppendText("1 notch = 1 degree");
  1746.         }
  1747.         if (Recording)
  1748.         {
  1749.             burst_stats.AppendText("\n");
  1750.             burst_stats.AppendText("\n");
  1751.             burst_stats.AppendText("RECORD PATTERN MODE ENABLED\n");
  1752.             burst_stats.AppendText("Press A to fire a shot left\n");
  1753.             burst_stats.AppendText("Press D to fire a shot right");
  1754.         }
  1755.         if(chk_Draw_Target.Checked)
  1756.         {
  1757.             //calculating pause time depending on weapon refire time and time necessary to reset CoF
  1758.             tb_pause.Text = Convert.ToString((float)weapons_comparison[0].Refire_Time / 1000 + (weapons_comparison[0].CurrentCoF - weapons_comparison[0].GetCurrentMinimumCoF(rb_ADSing.Checked, rb_Standing.Checked, rb_Still.Checked)) / 20);
  1759.  
  1760.             tb_target.Text = "";
  1761.             tb_target.AppendText("Distance: " + distance + "m\n");
  1762.             tb_target.AppendText("Damage at distance: " + CalculateDamage(weapons_comparison[0], distance) + "\n");
  1763.             tb_target.AppendText("Time elapsed: " + time_elapsed + "s\n");
  1764.             tb_target.AppendText("Shots fired: " + weapons_comparison[0].ShotNumber * weapons_comparison[0].Pellets + "\n");
  1765.             tb_target.AppendText("Shots to assign: " + (weapons_comparison[0].ShotNumber * weapons_comparison[0].Pellets - assign_damage) +"\n");
  1766.             tb_target.AppendText("Remaining health: " + target_health + "\n");
  1767.             if (target_health <= 0) tb_target.AppendText("TARGET DEAD");
  1768.             btn_bodyshot.Text = "Body (" + bodyshots + ")";
  1769.             btn_headshot.Text = "Head (" + headshots + ")";
  1770.             btn_legshot.Text = "Leg (" + legshots + ")";
  1771.            
  1772.           // end here start last time  tb_target.AppendText("Time elapsed: " + weapons_comparison[0].ShotNumber * );
  1773.         }
  1774.  
  1775.     }
  1776.     float CalculateDamage(Weapon weapon, int distance)
  1777.     {
  1778.         if (distance < weapon.Maximum_Damage_Range) return weapon.Maximum_Damage;
  1779.         if (distance > weapon.Minimum_Damage_Range) return weapon.Minimum_Damage;
  1780.         return (float)Math.Sqrt(Math.Sqrt((weapon.Maximum_Damage - weapon.Minimum_Damage) * (weapon.Maximum_Damage - weapon.Minimum_Damage) + (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range) * (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range)) * (weapon.Minimum_Damage_Range - distance) / (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range) * Math.Sqrt((weapon.Maximum_Damage - weapon.Minimum_Damage) * (weapon.Maximum_Damage - weapon.Minimum_Damage) + (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range) * (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range)) * (weapon.Minimum_Damage_Range - distance) / (weapon.Minimum_Damage_Range - weapon.Maximum_Damage_Range) - (weapon.Minimum_Damage_Range - distance) * (weapon.Minimum_Damage_Range - distance)) + weapon.Minimum_Damage;
  1781.     }
  1782.     void CheckAttachments(object sender, System.EventArgs arg) //обработчик события нажатия на кнопку "Влево"
  1783.     {
  1784.  
  1785.         if (!chk_FG.Checked) { chk_AFG.Checked = false; chk_AFG.Enabled = false; }
  1786.         else chk_AFG.Enabled = true;
  1787.         if (!chk_LS.Checked) { chk_ALS.Checked = false; chk_ALS.Enabled = false; }
  1788.         else chk_ALS.Enabled = true;
  1789.  
  1790.         // HVA and SPA
  1791.         weapons_comparison[0].Maximum_Damage_Range = weapon_orig.Maximum_Damage_Range + 5 * Convert.ToInt32(chk_SPA.Checked) - 2 * Convert.ToInt32(chk_HVA.Checked) - 5 * Convert.ToInt32(chk_Suppressor.Checked);
  1792.         weapons_comparison[0].Minimum_Damage_Range = weapon_orig.Minimum_Damage_Range + 20 * Convert.ToInt32(chk_HVA.Checked) - 20 * Convert.ToInt32(chk_Suppressor.Checked) * Convert.ToInt32(weapons_comparison[0].Type != "SMG") - 10 * Convert.ToInt32(chk_Suppressor.Checked) * Convert.ToInt32(weapons_comparison[0].Type == "SMG");
  1793.         weapons_comparison[0].Projectile_Velocity = Convert.ToInt32(weapon_orig.Projectile_Velocity * (1F - 0.05F * Convert.ToInt32(chk_SPA.Checked) + 0.05F * Convert.ToInt32(chk_HVA.Checked) - (float)SuppressorVelocityPenalty(weapons_comparison[0])));
  1794.  
  1795.         //compensator hip fire penalty
  1796.         weapons_comparison[0].CoF_Crouching_Moving_HIP = weapon_orig.CoF_Crouching_Moving_HIP * (1 + 0.2 * Convert.ToInt32(chk_Compensator.Checked) - 0.33 * Convert.ToInt32(chk_LS.Checked) - 0.07 * Convert.ToInt32(chk_ALS.Checked));
  1797.         weapons_comparison[0].CoF_Crouching_Still_Hip = weapon_orig.CoF_Crouching_Still_Hip * (1 + 0.2 * Convert.ToInt32(chk_Compensator.Checked) - 0.33 * Convert.ToInt32(chk_LS.Checked) - 0.07 * Convert.ToInt32(chk_ALS.Checked));
  1798.         weapons_comparison[0].CoF_Standing_Moving_Hip = weapon_orig.CoF_Standing_Moving_Hip * (1 + 0.2 * Convert.ToInt32(chk_Compensator.Checked) - 0.33 * Convert.ToInt32(chk_LS.Checked) - 0.07 * Convert.ToInt32(chk_ALS.Checked));
  1799.         weapons_comparison[0].CoF_Standing_Still_Hip = weapon_orig.CoF_Standing_Still_Hip * (1 + 0.2 * Convert.ToInt32(chk_Compensator.Checked) - 0.33 * Convert.ToInt32(chk_LS.Checked) - 0.07 * Convert.ToInt32(chk_ALS.Checked));
  1800.  
  1801.         //compensator vertical recoil bonus
  1802.         weapons_comparison[0].Vertical_Recoil = weapon_orig.Vertical_Recoil * (1 - 0.15 * Convert.ToInt32(chk_Compensator.Checked) - 0.15 * Convert.ToInt32(chk_FG.Checked) * Convert.ToInt32(weapons_comparison[0].Type == "Sniper Rifle")); // other weapons
  1803.         if (weapons_comparison[0].ID == 7170) weapons_comparison[0].Vertical_Recoil = weapon_orig.Vertical_Recoil * (1 - 0.2 * Convert.ToInt32(chk_Compensator.Checked));  // AC-X11
  1804.         if (weapons_comparison[0].ID == 7108 || weapons_comparison[0].ID == 7125) weapons_comparison[0].Vertical_Recoil = weapon_orig.Vertical_Recoil * (1 - 0.25 * Convert.ToInt32(chk_Compensator.Checked)); //Reaper DMR and SABR
  1805.         //if (weapons_comparison[0].ShotNumber > 0 && weapons_comparison[0].shot[weapons_comparison[0].ShotNumber - 1] != null) weapons_comparison[0].shot[weapons_comparison[0].ShotNumber - 1].Vertical_Recoil = 0; это вообще что должно делать-то?
  1806.         //Extended Mags
  1807.         if (chk_ExMags.Checked)
  1808.         {
  1809.             if (weapons_comparison[0].Type == "SMG" && weapons_comparison[0].ID != 27001 && weapons_comparison[0].ID != 28001 && weapons_comparison[0].ID != 29001) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 10;
  1810.             if (weapons_comparison[0].Type == "LMG" || weapons_comparison[0].ID == 803732 || weapons_comparison[0].ID == 803779 || weapons_comparison[0].ID == 7533 || weapons_comparison[0].ID == 7540) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size * 2; // Lasher and MCG + AE versions
  1811.             if (weapons_comparison[0].Type == "Shotgun" || weapons_comparison[0].ID == 7390)
  1812.             {
  1813.                 if (FireMode(weapons_comparison[0].Fire_Mode) >= 0) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 4; //semi auto and burst shotguns
  1814.                 if (FireMode(weapons_comparison[0].Fire_Mode) == -1) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 2; // pump action
  1815.                 if (weapons_comparison[0].ID == 75083) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 2; // Baron
  1816.  
  1817.             }
  1818.             if (weapons_comparison[0].ID == 7528 || weapons_comparison[0].ID == 803756) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 3; // Jackhammer
  1819.             if (weapons_comparison[0].Weapon_Name.Contains("Emissary")) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 5;
  1820.             if (weapons_comparison[0].ID == 7390) weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size + 1; // MagScatter
  1821.         }
  1822.         else weapons_comparison[0].Magazine_Size = weapon_orig.Magazine_Size;
  1823.         //Forward Grip
  1824.         weapons_comparison[0].Horizontal_Recoil_Minimum = weapon_orig.Horizontal_Recoil_Minimum * (1 - FG_Recoil_Bonus(weapons_comparison[0]));
  1825.         weapons_comparison[0].Horizontal_Recoil_Maximum = weapon_orig.Horizontal_Recoil_Maximum * (1 - FG_Recoil_Bonus(weapons_comparison[0]));
  1826.         weapons_comparison[0].Horizontal_Recoil_Tolerance = weapon_orig.Horizontal_Recoil_Tolerance - weapon_orig.Horizontal_Recoil_Tolerance * FG_Recoil_Bonus(weapons_comparison[0]);
  1827.         weapons_comparison[0].Recoil_Angle_Maximum = weapon_orig.Recoil_Angle_Maximum * (1 - FG_Angle_Bonus());
  1828.         weapons_comparison[0].Recoil_Angle_Minimum = weapon_orig.Recoil_Angle_Minimum * (1 - FG_Angle_Bonus());
  1829.  
  1830.         //slug ammunition
  1831.         //Full Auto and Semi-Auto slug damage: 500 @ 10m – 360 @ 40m
  1832.         //Pump Action slug damage: 800 @ 10m – 400 @ 40m
  1833.         if (chk_Slugs.Visible)
  1834.         {
  1835.             if (chk_Slugs.Checked)
  1836.             {
  1837.                 chk_SmartChoke.Enabled = false;
  1838.                 chk_SmartChoke.Checked = false;
  1839.                 weapons_comparison[0].Pellets = 1;
  1840.                 weapons_comparison[0].Pellet_Spread_ADS = 0;
  1841.                 weapons_comparison[0].Pellet_Spread_HIP = 0;
  1842.                 weapons_comparison[0].CoF_Crouching_Moving_HIP = weapon_orig.CoF_Crouching_Moving_HIP * 1.75;
  1843.                 weapons_comparison[0].CoF_Crouching_Still_Hip = weapon_orig.CoF_Crouching_Still_Hip * 1.75;
  1844.                 weapons_comparison[0].CoF_Standing_Moving_Hip = weapon_orig.CoF_Standing_Moving_Hip * 1.75;
  1845.                 weapons_comparison[0].CoF_Standing_Still_Hip = weapon_orig.CoF_Standing_Still_Hip * 1.75;
  1846.                 weapons_comparison[0].Projectile_Velocity = 300;
  1847.                 if (FireMode(weapons_comparison[0].Fire_Mode) >= 0)//semi auto and burst shotguns
  1848.                 {
  1849.                     weapons_comparison[0].Maximum_Damage = 500;
  1850.                     weapons_comparison[0].Maximum_Damage_Range = 10;
  1851.                     weapons_comparison[0].Minimum_Damage = 360;
  1852.                     weapons_comparison[0].Minimum_Damage_Range = 40;
  1853.                 }
  1854.                 if (FireMode(weapons_comparison[0].Fire_Mode) == -1) // pump action
  1855.                 {
  1856.                     weapons_comparison[0].Maximum_Damage = 800;
  1857.                     weapons_comparison[0].Maximum_Damage_Range = 10;
  1858.                     weapons_comparison[0].Minimum_Damage = 400;
  1859.                     weapons_comparison[0].Minimum_Damage_Range = 40;
  1860.                 }
  1861.             }
  1862.             else
  1863.             {
  1864.                 chk_SmartChoke.Enabled = true;
  1865.                 weapons_comparison[0].Pellets = weapon_orig.Pellets;
  1866.                 weapons_comparison[0].Maximum_Damage = weapon_orig.Maximum_Damage;
  1867.                 weapons_comparison[0].Maximum_Damage_Range = weapon_orig.Maximum_Damage_Range;
  1868.                 weapons_comparison[0].Minimum_Damage = weapon_orig.Minimum_Damage;
  1869.                 weapons_comparison[0].Minimum_Damage_Range = weapon_orig.Minimum_Damage_Range;
  1870.                 weapons_comparison[0].Projectile_Velocity = weapon_orig.Projectile_Velocity;
  1871.             }
  1872.             if (chk_SmartChoke.Enabled)
  1873.             {
  1874.                 if (chk_SmartChoke.Checked)
  1875.                 {
  1876.                     weapons_comparison[0].Pellet_Spread_ADS = weapon_orig.Pellet_Spread_ADS - 0.5;
  1877.                     weapons_comparison[0].Pellet_Spread_HIP = weapon_orig.Pellet_Spread_HIP + 0.5;
  1878.                 }
  1879.                 else
  1880.                 {
  1881.                     weapons_comparison[0].Pellet_Spread_ADS = weapon_orig.Pellet_Spread_ADS;
  1882.                     weapons_comparison[0].Pellet_Spread_HIP = weapon_orig.Pellet_Spread_HIP;
  1883.                 }
  1884.             }
  1885.         }
  1886.  
  1887.         //ATTACHMENT STRING SETTING
  1888.         weapons_comparison[0].Attachments = "";
  1889.         if (chk_AFG.Checked) weapons_comparison[0].Attachments += "Advanced Forward Grip\n";
  1890.         else if (chk_FG.Checked) weapons_comparison[0].Attachments += "Forward Grip\n";
  1891.         if (chk_ALS.Checked) weapons_comparison[0].Attachments += "Advanced Laser Sight\n";
  1892.         else if (chk_LS.Checked) weapons_comparison[0].Attachments += "Laser Sight\n";
  1893.         if (chk_ExMags.Checked) weapons_comparison[0].Attachments += "Extended Magazine\n";
  1894.         if (chk_SPA.Checked) weapons_comparison[0].Attachments += "SPA\n";
  1895.         if (chk_HVA.Checked) weapons_comparison[0].Attachments += "HVA\n";
  1896.         if (chk_Slugs.Checked) weapons_comparison[0].Attachments += "Slug Ammunition\n";
  1897.         if (chk_SmartChoke.Checked) weapons_comparison[0].Attachments += "Smart Choke\n";
  1898.         if (chk_Suppressor.Checked) weapons_comparison[0].Attachments += "Suppressor\n";
  1899.         if (chk_Compensator.Checked) weapons_comparison[0].Attachments += "Compensator\n";
  1900.  
  1901.         WriteWeaponStats();
  1902.         Invalidate();
  1903.     }
  1904.     // WEAPON SELECTION
  1905.     private void Lb_Click(object sender, EventArgs e)
  1906.     {
  1907.         chk_Ignore_Vertical_Recoil.Checked = false;
  1908.         chk_FG.Checked = false;
  1909.         chk_LS.Checked = false;
  1910.         chk_SPA.Checked = false;
  1911.         chk_HVA.Checked = false;
  1912.         chk_Suppressor.Checked = false;
  1913.         chk_Compensator.Checked = false;
  1914.         Optic_1x.Checked = true;
  1915.         chk_ExMags.Checked = false;
  1916.  
  1917.         weapons_comparison[0] = new Weapon(weapons[lb.SelectedIndex]);
  1918.         weapons_comparison[0].Attachments = "";
  1919.         weapons_comparison[0].Starting_X = Width / 2;
  1920.         weapons_comparison[0].Starting_Y = Height / 2;
  1921.         weapon_orig = weapons[lb.SelectedIndex];
  1922.  
  1923.         if (weapons_comparison[0].Type == "Shotgun" || weapons_comparison[0].ID == 7390)
  1924.         {
  1925.             chk_Slugs.Show();
  1926.             chk_SmartChoke.Show();
  1927.             chk_SPA.Hide();
  1928.             chk_HVA.Hide();
  1929.         }
  1930.         else
  1931.         {
  1932.             chk_Slugs.Hide();
  1933.             chk_SmartChoke.Hide();
  1934.             chk_SPA.Show();
  1935.             chk_HVA.Show();
  1936.         }
  1937.  
  1938.         timer.Interval = weapons_comparison[0].Refire_Time;
  1939.         WriteWeaponStats();
  1940.  
  1941.         Reset();
  1942.         Invalidate();
  1943.     }
  1944.     double SuppressorVelocityPenalty(Weapon weapon)
  1945.     {
  1946.         if (chk_Suppressor.Checked)
  1947.         {
  1948.             if (weapon.Type == "SMG") return 0.2;
  1949.             if (weapon.Weapon_Name.Contains("Emissary")) return 0.12;
  1950.             if (weapon.Type == "Carbine") return 0.35;
  1951.             if (weapon.ID == 7301) return 0.505; //railjack
  1952.             return 0.4;
  1953.         }
  1954.         return 0;
  1955.     }
  1956.     double FG_Recoil_Bonus(Weapon weapon)
  1957.     {
  1958.         if (chk_FG.Checked)
  1959.         {
  1960.             if (chk_AFG.Checked) return 0.33;
  1961.             else return 0.25;
  1962.         }
  1963.         return 0;
  1964.     }
  1965.     double FG_Angle_Bonus()
  1966.     {
  1967.         if (chk_FG.Checked)
  1968.         {
  1969.             if (chk_AFG.Checked) return 0.33;
  1970.             else return 0.25;
  1971.         }
  1972.         return 0;
  1973.     }
  1974.     void WriteWeaponStats()
  1975.     {
  1976.         tb.Text = null;
  1977.         tb.AppendText("Weapon ID: " + weapons_comparison[0].ID + "\n");
  1978.         tb.AppendText("Name: " + weapons_comparison[0].Weapon_Name + "\n");
  1979.         tb.AppendText("Faction: " + weapons_comparison[0].Faction + "\n");
  1980.         tb.AppendText("Type: " + weapons_comparison[0].Type + "\n");
  1981.         tb.AppendText("Damage: " + weapons_comparison[0].Maximum_Damage + " @ " + weapons_comparison[0].Maximum_Damage_Range + "m - " + weapons_comparison[0].Minimum_Damage + " @ " + weapons_comparison[0].Minimum_Damage_Range + "m\n");
  1982.         if (weapons_comparison[0].Pellets > 1)
  1983.         {
  1984.             if (weapons_comparison[0].Pellet_Spread_ADS == weapons_comparison[0].Pellet_Spread_HIP)
  1985.                 tb.AppendText("Pellets: " + weapons_comparison[0].Pellets + " / " + "Pellet Spread: " + weapons_comparison[0].Pellet_Spread_ADS + "\n");
  1986.             else tb.AppendText("Pellets: " + weapons_comparison[0].Pellets + " / " + "Pellet Spread: " + weapons_comparison[0].Pellet_Spread_ADS + " / " + weapons_comparison[0].Pellet_Spread_HIP + "\n");
  1987.         }
  1988.         tb.AppendText("Headshot Damage Multiplier: " + (1 + weapons_comparison[0].Headshot_Damage_Multiplier) + "x\n");
  1989.         if (!weapons_comparison[0].Fire_Mode.Contains("Action")) tb.AppendText("Rate of Fire: " + weapons_comparison[0].Rate_of_Fire + "\n");
  1990.         tb.AppendText("Projectile Velocity: " + weapons_comparison[0].Projectile_Velocity + " m/s \n");
  1991.         tb.AppendText("Ammo: " + weapons_comparison[0].Magazine_Size + " / " + weapons_comparison[0].Ammo_Pool + " \n");
  1992.         if (weapons_comparison[0].Fire_Mode != "Pump-Action" && !weapons_comparison[0].Weapon_Name.Contains("Baron")) tb.AppendText("Reload Time: " + weapons_comparison[0].Short_Reload / 1000 + " s / " + weapons_comparison[0].Long_Reload / 1000 + " s \n");
  1993.         tb.AppendText("ADS Movement Speed Multiplier: " + weapons_comparison[0].ADS_Movement_Speed_Multiplier + "\n");
  1994.         tb.AppendText("Hip Fire CoFs: " + weapons_comparison[0].CoF_Crouching_Still_Hip + " / " + weapons_comparison[0].CoF_Crouching_Moving_HIP + " / " + weapons_comparison[0].CoF_Standing_Still_Hip + " / " + weapons_comparison[0].CoF_Standing_Moving_Hip + "\n");
  1995.         tb.AppendText("ADS Fire CoFs: " + weapons_comparison[0].CoF_Crouching_Still_ADS + " / " + weapons_comparison[0].CoF_Crouching_Moving_ADS + " / " + weapons_comparison[0].CoF_Standing_Still_ADS + " / " + weapons_comparison[0].CoF_Standing_Moving_ADS + "\n");
  1996.         tb.AppendText("CoF Bloom: " + weapons_comparison[0].CoF_Bloom_ADS + " / " + weapons_comparison[0].CoF_Bloom_Hip + " \n");
  1997.         tb.AppendText("Recoil Angle: " + weapons_comparison[0].Recoil_Angle_Minimum + " - " + weapons_comparison[0].Recoil_Angle_Maximum + "\n");
  1998.         tb.AppendText("Vertical Recoil: " + weapons_comparison[0].Vertical_Recoil + "\n");
  1999.         tb.AppendText("First Shot Recoil Multiplier: " + weapons_comparison[0].First_Shot_Recoil_Multiplier + "x\n");
  2000.         tb.AppendText("Horizontal Recoil: " + weapons_comparison[0].Horizontal_Recoil_Minimum + " - " + weapons_comparison[0].Horizontal_Recoil_Maximum + "\n");
  2001.         tb.AppendText("Horizontal Recoil Tolerance: " + weapons_comparison[0].Horizontal_Recoil_Tolerance + "\n");
  2002.         tb.AppendText("Recoil Recovery Rate: " + weapons_comparison[0].Recoil_Recovery_Rate + "\n");
  2003.         tb.AppendText("Fire Mode: " + weapons_comparison[0].Fire_Mode);
  2004.  
  2005.         //write BTK thresholds
  2006.         {
  2007.             if (tb_target_health.Focused)
  2008.             {
  2009.                 tb_target_health.Text = tb_target_health.Text.Replace('.', ',');
  2010.                 tb_target_health.SelectionStart = tb_target_health.Text.Length;
  2011.                 tb_target_health.SelectionLength = 0;
  2012.             }
  2013.             if (tb_damage_multiplier.Focused)
  2014.             {
  2015.                 tb_damage_multiplier.Text = tb_damage_multiplier.Text.Replace('.', ',');
  2016.                 tb_damage_multiplier.SelectionStart = tb_damage_multiplier.Text.Length;
  2017.                 tb_damage_multiplier.SelectionLength = 0;
  2018.             }
  2019.  
  2020.             int[][] arr;
  2021.             if (tb_target_health.Text != "" && tb_target_health.Text != "" && tb_damage_multiplier.Text != "")
  2022.                 if (Convert.ToDouble(tb_target_health.Text) >= 0 && Convert.ToDouble(tb_target_health.Text) >= 0 && Convert.ToDouble(tb_damage_multiplier.Text) > 0)
  2023.                 {
  2024.                     arr = Calculate_tb_thresholds(weapons_comparison[0], (float)Convert.ToDouble(tb_target_health.Text), (float)Convert.ToDouble(tb_damage_multiplier.Text), Convert.ToInt32(tb_bonus_headshots.Text));
  2025.                     tb_thresholds.Text = null;
  2026.                     tb_thresholds.AppendText("Target Effective Health: " + (float)(Convert.ToDouble(tb_target_health.Text) / Convert.ToDouble(tb_damage_multiplier.Text)) + "\n");
  2027.                     if (Convert.ToInt32(tb_bonus_headshots.Text) > 0)
  2028.                     {
  2029.                         if (Convert.ToInt32(tb_bonus_headshots.Text) == 1) tb_thresholds.AppendText("After 1 headshot\n");
  2030.                         else tb_thresholds.AppendText("After " + Convert.ToInt32(tb_bonus_headshots.Text) + " headshots\n");
  2031.                     }
  2032.                     for (int i = 0; i < arr.Length; i++)
  2033.                     {
  2034.                             if (i + 1 == arr.Length) tb_thresholds.AppendText("BTK of " + arr[i][0] + " at " + arr[i][1] + "m+ (" + (Math.Ceiling((double)arr[i][0] / weapons_comparison[0].Pellets) - 1) * ((float)weapons_comparison[0].Refire_Time / 1000) + "s)");
  2035.                             else tb_thresholds.AppendText("BTK of " + arr[i][0] + " from " + arr[i][1] + "m to " + arr[i][2] + "m (" + (Math.Ceiling((double)arr[i][0] / weapons_comparison[0].Pellets) -1) * ((float)weapons_comparison[0].Refire_Time / 1000) + "s)\n");
  2036.                     }
  2037.                 }
  2038.         }
  2039.     }
  2040.     void ParseFile()
  2041.     {
  2042.         StreamReader reader = null;
  2043.         if (File.Exists("Stats.csv")) reader = File.OpenText("Stats.csv");
  2044.         else
  2045.         {
  2046.             MessageBox.Show("Failed to open database file. Make sure that \"Stats.csv\" file is in application folder. Program will be closed.", "Database error");
  2047.             if (System.Windows.Forms.Application.MessageLoop) System.Windows.Forms.Application.Exit();
  2048.             else System.Environment.Exit(1);
  2049.         }
  2050.  
  2051.  
  2052.         string line = reader.ReadLine();
  2053.         string[] items = line.Split(',');
  2054.         Database_Date = items[0];
  2055.  
  2056.         int wpn = 0;
  2057.  
  2058.         while ((line = reader.ReadLine()) != null)
  2059.         {
  2060.  
  2061.             items = line.Split(',');
  2062.             switch (items[3])
  2063.             {
  2064.                 case "AA MAX (Left)": continue;
  2065.                 case "AA MAX (Right)": continue;
  2066.                 case "AI MAX (Left)": continue;
  2067.                 case "AI MAX (Right)": continue;
  2068.                 case "ANT Top Turret": continue;
  2069.                 case "AV MAX (Left)": continue;
  2070.                 case "AV MAX (Right)": continue;
  2071.                 case "Flash Primary Weapon": continue;
  2072.                 case "Galaxy Left Weapon": continue;
  2073.                 case "Galaxy Right Weapon": continue;
  2074.                 case "Galaxy Tail Weapon": continue;
  2075.                 case "Galaxy Top Weapon": continue;
  2076.                 case "Harasser Top Gunner": continue;
  2077.                 case "Liberator Belly Weapon": continue;
  2078.                 case "Liberator Nose Cannon": continue;
  2079.                 case "Liberator Tail Weapon": continue;
  2080.                 case "Lightning Primary Weapon ": continue;
  2081.                 case "Magrider Gunner Weapon": continue;
  2082.                 case "Magrider Primary Weapon": continue;
  2083.                 case "Mosquito Nose Cannon": continue;
  2084.                 case "Mosquito Wing Mount": continue;
  2085.                 case "Prowler Gunner Weapon": continue;
  2086.                 case "Prowler Primary Weapon": continue;
  2087.                 case "Reaver Nose Cannon": continue;
  2088.                 case "Reaver Wing Mount": continue;
  2089.                 case "Scythe Nose Cannon": continue;
  2090.                 case "Scythe Wing Mount": continue;
  2091.                 case "Sunderer Front Gunner": continue;
  2092.                 case "Sunderer Rear Gunner": continue;
  2093.                 case "Valkyrie Nose Gunner": continue;
  2094.                 case "Vanguard Gunner Weapon": continue;
  2095.                 case "Vanguard Primary Weapon": continue;
  2096.                 case "Vehicle Abilities": continue;
  2097.                 case "Heavy Gun": continue;
  2098.             }
  2099.  
  2100.  
  2101.             /*
  2102. 0   Item ID
  2103. 1   Name
  2104. 2   Faction
  2105. 3   Category
  2106. 4   Min Damage
  2107. 5   Min Range
  2108. 6   Max Damage
  2109. 7   Max Range
  2110. 8   H/S Multiplier
  2111. 9   RPM
  2112. 10  Pellets
  2113. 11  TTK
  2114. 12  Velocity
  2115. 13  Equip Time
  2116. 14  Clip Size
  2117. 15  Capacity
  2118. 16  Long Reload
  2119. 17  Short Reload
  2120. 18  Move Mod ADS
  2121. 19  COF Recoil Hip
  2122. 20  COF Recoil ADS
  2123. 21  Standing Hip
  2124. 22  Crouching Hip
  2125. 23  Walking Hip
  2126. 24  Running Hip
  2127. 25  CrouchWalking Hip
  2128. 26  Standing ADS
  2129. 27  Crouching ADS
  2130. 28  Walking ADS
  2131. 29  CrouchWalking ADS
  2132. 30  Recoil Angle Min
  2133. 31  Recoil Angle Max
  2134. 32  Vertical Recoil
  2135. 33  Horizontal Recoil Min
  2136. 34  Horizontal Recoil Max
  2137. 35  Horizontal Recoil Tolerance
  2138. 36  Recoil First Shot Mod
  2139. 37  Recoil Recovery
  2140. */
  2141.  
  2142.             weapons[wpn] = new Weapon();
  2143.  
  2144.             weapons[wpn].ID = Convert.ToInt32(items[0]);
  2145.             weapons[wpn].Weapon_Name = items[1];
  2146.             weapons[wpn].Faction = items[2];
  2147.             weapons[wpn].Type = items[3];
  2148.             weapons[wpn].Maximum_Damage = Convert.ToInt32(items[4]);
  2149.             weapons[wpn].Maximum_Damage_Range = Convert.ToInt32(items[5]);
  2150.             weapons[wpn].Minimum_Damage = Convert.ToInt32(items[6]);
  2151.             weapons[wpn].Minimum_Damage_Range = Convert.ToInt32(items[7]);
  2152.             weapons[wpn].Headshot_Damage_Multiplier = Convert.ToDouble(items[8].Replace('.', ','));
  2153.  
  2154.             if (items[9] != "") weapons[wpn].Refire_Time = Convert.ToInt32(items[9]);
  2155.             else weapons[wpn].Refire_Time = 1000;
  2156.  
  2157.             weapons[wpn].Rate_of_Fire = 60000 / weapons[wpn].Refire_Time;
  2158.  
  2159.             weapons[wpn].Pellets = Convert.ToInt32(items[10]);
  2160.  
  2161.             if (items[12] != "") weapons[wpn].Projectile_Velocity = Convert.ToInt32(items[12]);
  2162.             else
  2163.             {
  2164.                 if (items[1] == "Spiker") weapons[wpn].Projectile_Velocity = 325;
  2165.                 else weapons[wpn].Projectile_Velocity = 1;
  2166.             }
  2167.  
  2168.             if (items[13] != "-") weapons[wpn].Equip_Time = Convert.ToDouble(items[13].Replace('.', ','));
  2169.             else weapons[wpn].Equip_Time = 1;
  2170.  
  2171.             if (items[14] != "") weapons[wpn].Magazine_Size = Convert.ToInt32(items[14]);
  2172.             else weapons[wpn].Magazine_Size = 1;
  2173.  
  2174.             if (items[15] != "") weapons[wpn].Ammo_Pool = Convert.ToInt32(items[15]);
  2175.             else weapons[wpn].Ammo_Pool = 1;
  2176.  
  2177.             if (items[16] != "NaN") weapons[wpn].Long_Reload = Convert.ToInt32(items[16]);
  2178.             else weapons[wpn].Short_Reload = 1;
  2179.  
  2180.  
  2181.             if (items[17] != "") weapons[wpn].Short_Reload = Convert.ToInt32(items[17]);
  2182.             else weapons[wpn].Long_Reload = 1;
  2183.  
  2184.             weapons[wpn].ADS_Movement_Speed_Multiplier = Convert.ToDouble(items[18].Replace('.', ','));
  2185.             weapons[wpn].CoF_Bloom_Hip = Convert.ToDouble(items[19].Replace('.', ','));
  2186.             weapons[wpn].CoF_Bloom_ADS = Convert.ToDouble(items[20].Replace('.', ','));
  2187.  
  2188.             weapons[wpn].CoF_Standing_Still_Hip = Convert.ToDouble(items[21].Replace('.', ','));
  2189.             weapons[wpn].CoF_Crouching_Still_Hip = Convert.ToDouble(items[22].Replace('.', ','));
  2190.             weapons[wpn].CoF_Standing_Moving_Hip = Convert.ToDouble(items[23].Replace('.', ','));
  2191.             weapons[wpn].CoF_Sprint = Convert.ToDouble(items[24].Replace('.', ','));
  2192.             weapons[wpn].CoF_Crouching_Moving_HIP = Convert.ToDouble(items[25].Replace('.', ','));
  2193.  
  2194.             weapons[wpn].CoF_Standing_Still_ADS = Convert.ToDouble(items[26].Replace('.', ','));
  2195.             weapons[wpn].CoF_Crouching_Still_ADS = Convert.ToDouble(items[27].Replace('.', ','));
  2196.             weapons[wpn].CoF_Standing_Moving_ADS = Convert.ToDouble(items[28].Replace('.', ','));
  2197.             weapons[wpn].CoF_Crouching_Moving_ADS = Convert.ToDouble(items[29].Replace('.', ','));
  2198.  
  2199.             weapons[wpn].Recoil_Angle_Maximum = Convert.ToDouble(items[30].Replace('.', ','));
  2200.             weapons[wpn].Recoil_Angle_Minimum = Convert.ToDouble(items[31].Replace('.', ','));
  2201.  
  2202.             weapons[wpn].Vertical_Recoil = Convert.ToDouble(items[32].Replace('.', ','));
  2203.             weapons[wpn].Horizontal_Recoil_Maximum = Convert.ToDouble(items[33].Replace('.', ','));
  2204.             weapons[wpn].Horizontal_Recoil_Minimum = Convert.ToDouble(items[34].Replace('.', ','));
  2205.             weapons[wpn].Horizontal_Recoil_Tolerance = Convert.ToDouble(items[35].Replace('.', ','));
  2206.             weapons[wpn].First_Shot_Recoil_Multiplier = Convert.ToDouble(items[36].Replace('.', ','));
  2207.             weapons[wpn].Recoil_Recovery_Rate = Convert.ToInt32(items[37]);
  2208.  
  2209.             weapons[wpn].Fire_Mode = items[38];
  2210.  
  2211.             if (items[39].Length > 0) weapons[wpn].Pellet_Spread_ADS = weapons[wpn].Pellet_Spread_HIP = Convert.ToDouble(items[39].Replace('.', ','));
  2212.             else weapons[wpn].Pellet_Spread_ADS = weapons[wpn].Pellet_Spread_HIP = 0;
  2213.  
  2214.             wpn++;
  2215.         }
  2216.         number_of_weapons = wpn;
  2217.  
  2218.         //removing empty items from array
  2219.         weapons = weapons.Where(c => c != null).ToArray();
  2220.  
  2221.         //sorting array by weapon type
  2222.         Array.Sort(weapons, (x, y) => x.Type.CompareTo(y.Type));
  2223.     }
  2224.     int FireMode(string FM)
  2225.     {
  2226.         if (FM == "Semi-Auto" || FM == "Charge" || FM == "Single Shot") return 1;
  2227.         if (FM == "Auto / Semi-Auto" || FM == "Auto" || FM == "Auto / 3x Burst / Semi-Auto" || FM == "Auto / 2x Burst / Semi-Auto" || FM == "2x Burst / Auto / Semi-Auto" || FM == "Auto / Semi-Auto / 3x Burst") return 0;
  2228.         if (FM == "2x Burst / Semi-Auto" || FM == "Semi-Auto / 2x Burst" || FM == "Charge / 2x Burst") return 2;
  2229.         if (FM == "Semi-Auto / 3x Burst" || FM == "3x Burst / Semi-Auto" || FM == "Semi-Auto / 3x Burst / 2x Burst") return 3;
  2230.         if (FM == "Pump-Action") return -1;
  2231.         if (FM == "Bolt Action") return -2;
  2232.         return 0;
  2233.     }
  2234. }
  2235.  
  2236. static class Program
  2237. {
  2238.     [STAThread]
  2239.     static void Main()
  2240.     {
  2241.         Application.EnableVisualStyles();
  2242.         Application.SetCompatibleTextRenderingDefault(false);
  2243.         Application.Run(new MainWindow());
  2244.     }
  2245. }
Add Comment
Please, Sign In to add comment