Form1.cs


using FForumF;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MenuTOD
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                // Проверяем, существует ли форма
                Form2 form2 = new Form2();

                // Настройка формы перед открытием
                form2.StartPosition = FormStartPosition.CenterScreen;
                form2.ShowInTaskbar = false; // если нужно

                // Открываем форму модально
                form2.ShowDialog();

                // После закрытия формы
                form2.Dispose(); // Освобождаем ресурсы
            }
            catch (Exception ex)
            {
                // Выводим сообщение об ошибке
                MessageBox.Show($"Ошибка при открытии формы: {ex.Message}\n\n" +
                               $"Тип ошибки: {ex.GetType().Name}\n" +
                               $"StackTrace: {ex.StackTrace}",
                                "Ошибка",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                // Проверяем, существует ли форма
                Form3 form3 = new Form3();

                // Настройка формы перед открытием
                form3.StartPosition = FormStartPosition.CenterScreen;
                form3.ShowInTaskbar = false; // если нужно

                // Открываем форму модально
                form3.ShowDialog();

                // После закрытия формы
                form3.Dispose(); // Освобождаем ресурсы
            }
            catch (Exception ex)
            {
                // Выводим сообщение об ошибке
                MessageBox.Show($"Ошибка при открытии формы: {ex.Message}\n\n" +
                               $"Тип ошибки: {ex.GetType().Name}\n" +
                               $"StackTrace: {ex.StackTrace}",
                                "Ошибка",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                // Проверяем, существует ли форма
                MainForm MainForm = new MainForm();

                // Настройка формы перед открытием
                MainForm.StartPosition = FormStartPosition.CenterScreen;
                MainForm.ShowInTaskbar = false; // если нужно

                // Открываем форму модально
                MainForm.ShowDialog();

                // После закрытия формы
                MainForm.Dispose(); // Освобождаем ресурсы
            }
            catch (Exception ex)
            {
                // Выводим сообщение об ошибке
                MessageBox.Show($"Ошибка при открытии формы: {ex.Message}\n\n" +
                               $"Тип ошибки: {ex.GetType().Name}\n" +
                               $"StackTrace: {ex.StackTrace}",
                                "Ошибка",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                // Проверяем, существует ли форма
                Form5 form5 = new Form5();

                // Настройка формы перед открытием
                form5.StartPosition = FormStartPosition.CenterScreen;
                form5.ShowInTaskbar = false; // если нужно

                // Открываем форму модально
                form5.ShowDialog();

                // После закрытия формы
                form5.Dispose(); // Освобождаем ресурсы
            }
            catch (Exception ex)
            {
                // Выводим сообщение об ошибке
                MessageBox.Show($"Ошибка при открытии формы: {ex.Message}\n\n" +
                               $"Тип ошибки: {ex.GetType().Name}\n" +
                               $"StackTrace: {ex.StackTrace}",
                                "Ошибка",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }
    }
}

    

Form1.Designer.cs

namespace MenuTOD
{
    partial class Form1
    {
        /// 
        /// Обязательная переменная конструктора.
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// Освободить все используемые ресурсы.
        /// 
        /// истинно, если управляемый ресурс должен быть удален; иначе ложно.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Код, автоматически созданный конструктором форм Windows

        /// 
        /// Требуемый метод для поддержки конструктора — не изменяйте 
        /// содержимое этого метода с помощью редактора кода.
        /// 
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.button2 = new System.Windows.Forms.Button();
            this.button1 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.button5 = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox1
            // 
            this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage")));
            this.pictureBox1.Location = new System.Drawing.Point(-8, -3);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(835, 456);
            this.pictureBox1.TabIndex = 1;
            this.pictureBox1.TabStop = false;
            // 
            // button2
            // 
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.button2.Location = new System.Drawing.Point(12, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(66, 31);
            this.button2.TabIndex = 2;
            this.button2.Text = "N3D";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button1
            // 
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.button1.Location = new System.Drawing.Point(12, 49);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(124, 31);
            this.button1.TabIndex = 3;
            this.button1.Text = "NSSpace";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button3
            // 
            this.button3.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.button3.Location = new System.Drawing.Point(12, 86);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(115, 31);
            this.button3.TabIndex = 4;
            this.button3.Text = "FForumF";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // button4
            // 
            this.button4.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.button4.Location = new System.Drawing.Point(12, 123);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(132, 31);
            this.button4.TabIndex = 5;
            this.button4.Text = "SlizarioPC";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button4_Click);
            // 
            // button5
            // 
            this.button5.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.button5.Location = new System.Drawing.Point(12, 160);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(132, 31);
            this.button5.TabIndex = 6;
            this.button5.Text = "SlizarioPC";
            this.button5.UseVisualStyleBackColor = true;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.button5);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
    }
}



    

Form2.cs

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

namespace MenuTOD
{
    public partial class Form2 : Form
    {
        // Цвета
        private Color bgColor = Color.FromArgb(30, 30, 40);
        private Color[] originalCubeColors = new Color[]
        {
            Color.FromArgb(251, 236, 93),   // Желтый
            Color.FromArgb(123, 145, 123),  // Серо-зеленый
            Color.FromArgb(0, 165, 80)      // Зеленый
        };
        private Color[] cubeColors;
        private Color outlineColor = Color.FromArgb(32, 96, 61);

        // Цвета сторон сцены
        private Color[] originalSceneSideColors = new Color[]
        {
            Color.FromArgb(60, 60, 80, 100),   // Задняя стена
            Color.FromArgb(60, 80, 60, 100),   // Правая стена  
            Color.FromArgb(60, 100, 80, 60),   // Левая стена
            Color.FromArgb(60, 100, 60, 80),   // Пол
            Color.FromArgb(60, 60, 100, 80),   // Потолок
            Color.FromArgb(60, 100, 100, 60)   // Передняя
        };
        private Color[] sceneSideColors;

        // Цвета сеток
        private Color[] originalGridColors = new Color[]
        {
            Color.FromArgb(80, 100, 150, 200), // XY плоскость
            Color.FromArgb(80, 150, 100, 200), // XZ плоскость
            Color.FromArgb(80, 200, 150, 100)  // YZ плоскость
        };
        private Color[] gridColors;

        // Кубы
        private float cubeSize = 60;
        private List cubes = new List
        {
            new Vector3(0, 0, 0),
            new Vector3(150, 0, 150),
            new Vector3(-150, 0, 300)
        };

        // Камера
        private float camX = 35, camY = -35, camZ = 0, zoom = 1.2f;
        private Point lastMouse;
        private bool isRotating = false;
        private bool isPanning = false;
        private bool isOrbiting = false;
        private Vector3 cameraPosition = new Vector3(0, 0, 500);
        private Vector3 orbitCenter = new Vector3(0, 0, 0);
        private float orbitRadius = 500;
        private float orbitAngle = 0;

        // Управление
        private Timer gameTimer;
        private Dictionary pressedKeys = new Dictionary();
        private float moveSpeed = 8f;
        private float rotateSpeed = 0.5f;
        private float orbitSpeed = 2f;

        // Режимы WASD
        private enum WasdMode
        {
            MoveCubes,      // O - движение кубов
            MoveCamera      // I - движение камеры
        }
        private WasdMode currentWasdMode = WasdMode.MoveCubes;

        // Режим колёсика
        private enum WheelMode
        {
            Zoom,           // Обычный зум
            HeightControl   // Управление высотой (Z координатой)
        }
        private WheelMode currentWheelMode = WheelMode.Zoom;
        private Keys lastModifierKey = Keys.None;

        // Сетка
        private int gridSize = 600;
        private int originalGridStep = 50;
        private int gridStep;
        private int sceneSize = 800;

        // Режимы управления и рандомизация
        private ControlMode currentControlMode = ControlMode.Default;
        private Random random = new Random();
        private bool isRandomized = false;

        // История для отмены
        private List cubeColorsHistory = new List();
        private List sceneColorsHistory = new List();
        private List gridColorsHistory = new List();
        private List gridStepHistory = new List();
        private List> cubesHistory = new List>();

        private enum ControlMode
        {
            Default,
            RobloxStyle,
            HeightControl,
            Combined,
            OrbitMode
        }

        public Form2()
        {
            InitializeComponent();
            SetupForm();
        }

        private void SetupForm()
        {
            // Инициализируем цвета
            cubeColors = (Color[])originalCubeColors.Clone();
            sceneSideColors = (Color[])originalSceneSideColors.Clone();
            gridColors = (Color[])originalGridColors.Clone();
            gridStep = originalGridStep;

            this.DoubleBuffered = true;
            this.BackColor = bgColor;
            pictureBox1.BackColor = bgColor;
            this.KeyPreview = true;
            this.Text = "3D СЦЕНА - Колёсико: ZOOM (обычный) / ВЫСОТА (с Alt/Ctrl/Shift)";

            gameTimer = new Timer();
            gameTimer.Interval = 16;
            gameTimer.Tick += GameTimer_Tick;
            gameTimer.Start();

            InitializeKeys();
        }

        private void InitializeKeys()
        {
            pressedKeys[Keys.Left] = false;
            pressedKeys[Keys.Right] = false;
            pressedKeys[Keys.Up] = false;
            pressedKeys[Keys.Down] = false;
            pressedKeys[Keys.D2] = false;
            pressedKeys[Keys.D3] = false;
            pressedKeys[Keys.W] = false;
            pressedKeys[Keys.S] = false;
            pressedKeys[Keys.A] = false;
            pressedKeys[Keys.D] = false;
            pressedKeys[Keys.Q] = false;
            pressedKeys[Keys.E] = false;
            pressedKeys[Keys.R] = false;
            pressedKeys[Keys.T] = false;
            pressedKeys[Keys.N] = false;
            pressedKeys[Keys.M] = false;
            pressedKeys[Keys.O] = false;
            pressedKeys[Keys.I] = false;
            pressedKeys[Keys.ControlKey] = false;
            pressedKeys[Keys.ShiftKey] = false;
            pressedKeys[Keys.Alt] = false;
        }

        private void GameTimer_Tick(object sender, EventArgs e)
        {
            bool needRedraw = false;
            float speed = moveSpeed;

            if (currentControlMode == ControlMode.OrbitMode)
            {
                orbitAngle += orbitSpeed * 0.1f;
                if (orbitAngle > 360) orbitAngle -= 360;

                cameraPosition.X = orbitCenter.X + orbitRadius * (float)Math.Sin(orbitAngle * Math.PI / 180);
                cameraPosition.Z = orbitCenter.Z + orbitRadius * (float)Math.Cos(orbitAngle * Math.PI / 180);
                cameraPosition.Y = orbitCenter.Y + orbitRadius * 0.3f * (float)Math.Sin(orbitAngle * 0.5f * Math.PI / 180);

                needRedraw = true;
            }

            // Обработка WASD в зависимости от режима
            if (currentWasdMode == WasdMode.MoveCubes)
            {
                // Движение кубов
                if (pressedKeys[Keys.W]) { foreach (var cube in cubes) cube.Z -= speed; needRedraw = true; }
                if (pressedKeys[Keys.S]) { foreach (var cube in cubes) cube.Z += speed; needRedraw = true; }
                if (pressedKeys[Keys.A]) { foreach (var cube in cubes) cube.X -= speed; needRedraw = true; }
                if (pressedKeys[Keys.D]) { foreach (var cube in cubes) cube.X += speed; needRedraw = true; }
            }
            else if (currentWasdMode == WasdMode.MoveCamera)
            {
                // Движение камеры
                if (pressedKeys[Keys.W]) { cameraPosition.Z -= speed * 2; needRedraw = true; }
                if (pressedKeys[Keys.S]) { cameraPosition.Z += speed * 2; needRedraw = true; }
                if (pressedKeys[Keys.A]) { cameraPosition.X -= speed * 2; needRedraw = true; }
                if (pressedKeys[Keys.D]) { cameraPosition.X += speed * 2; needRedraw = true; }
            }

            // Управление в зависимости от режима
            switch (currentControlMode)
            {
                case ControlMode.Default:
                    needRedraw |= HandleDefaultControls(speed);
                    break;
                case ControlMode.RobloxStyle:
                    needRedraw |= HandleRobloxControls(speed);
                    break;
                case ControlMode.HeightControl:
                    needRedraw |= HandleHeightControls(speed);
                    break;
                case ControlMode.Combined:
                    needRedraw |= HandleDefaultControls(speed);
                    needRedraw |= HandleRobloxControls(speed);
                    needRedraw |= HandleHeightControls(speed);
                    break;
            }

            // Движение камеры вверх/вниз (Q/E)
            if (pressedKeys[Keys.Q])
            {
                cameraPosition.Y += speed * 2;
                needRedraw = true;
            }
            if (pressedKeys[Keys.E])
            {
                cameraPosition.Y -= speed * 2;
                needRedraw = true;
            }

            if (needRedraw) pictureBox1.Invalidate();
        }

        private bool HandleDefaultControls(float speed)
        {
            bool changed = false;
            if (pressedKeys[Keys.Left]) { foreach (var cube in cubes) cube.X -= speed; changed = true; }
            if (pressedKeys[Keys.Right]) { foreach (var cube in cubes) cube.X += speed; changed = true; }
            if (pressedKeys[Keys.Up]) { foreach (var cube in cubes) cube.Y -= speed; changed = true; }
            if (pressedKeys[Keys.Down]) { foreach (var cube in cubes) cube.Y += speed; changed = true; }
            return changed;
        }

        private bool HandleRobloxControls(float speed)
        {
            bool changed = false;
            if (pressedKeys[Keys.W]) { foreach (var cube in cubes) cube.Z -= speed; changed = true; }
            if (pressedKeys[Keys.S]) { foreach (var cube in cubes) cube.Z += speed; changed = true; }
            if (pressedKeys[Keys.A]) { foreach (var cube in cubes) cube.X -= speed; changed = true; }
            if (pressedKeys[Keys.D]) { foreach (var cube in cubes) cube.X += speed; changed = true; }
            return changed;
        }

        private bool HandleHeightControls(float speed)
        {
            bool changed = false;
            if (pressedKeys[Keys.D2]) { foreach (var cube in cubes) cube.Z += speed; changed = true; }
            if (pressedKeys[Keys.D3]) { foreach (var cube in cubes) cube.Z -= speed; changed = true; }
            return changed;
        }

        private void PictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.Clear(bgColor);

            Matrix originalTransform = g.Transform;
            g.TranslateTransform(pictureBox1.Width / 2, pictureBox1.Height / 2);
            g.ScaleTransform(zoom, zoom);

            // Применяем 3D вращение камеры
            Matrix rotation = new Matrix();
            rotation.Rotate(camZ, MatrixOrder.Append);
            rotation.Rotate(camX, MatrixOrder.Append);
            rotation.Rotate(camY, MatrixOrder.Append);
            g.MultiplyTransform(rotation);

            DrawSceneWalls(g);
            DrawFull3DGrid(g);

            List drawOrder = GetDrawOrder();
            foreach (int idx in drawOrder)
                DrawCube(g, cubes[idx], cubeColors[idx], (idx + 1).ToString());

            DrawCoordinateAxes(g);
            g.Transform = originalTransform;

            DrawHUD(g);
            DrawControls(g);
        }

        private void DrawSceneWalls(Graphics g)
        {
            DrawScenePlane(g, new Vector3(-sceneSize, -sceneSize, -sceneSize), new Vector3(sceneSize, -sceneSize, -sceneSize), new Vector3(sceneSize, -sceneSize, sceneSize), new Vector3(-sceneSize, -sceneSize, sceneSize), sceneSideColors[3]);
            DrawScenePlane(g, new Vector3(-sceneSize, sceneSize, -sceneSize), new Vector3(sceneSize, sceneSize, -sceneSize), new Vector3(sceneSize, sceneSize, sceneSize), new Vector3(-sceneSize, sceneSize, sceneSize), sceneSideColors[4]);
            DrawScenePlane(g, new Vector3(-sceneSize, -sceneSize, -sceneSize), new Vector3(sceneSize, -sceneSize, -sceneSize), new Vector3(sceneSize, sceneSize, -sceneSize), new Vector3(-sceneSize, sceneSize, -sceneSize), sceneSideColors[0]);
            DrawScenePlane(g, new Vector3(-sceneSize, -sceneSize, sceneSize), new Vector3(sceneSize, -sceneSize, sceneSize), new Vector3(sceneSize, sceneSize, sceneSize), new Vector3(-sceneSize, sceneSize, sceneSize), sceneSideColors[5]);
            DrawScenePlane(g, new Vector3(-sceneSize, -sceneSize, -sceneSize), new Vector3(-sceneSize, -sceneSize, sceneSize), new Vector3(-sceneSize, sceneSize, sceneSize), new Vector3(-sceneSize, sceneSize, -sceneSize), sceneSideColors[2]);
            DrawScenePlane(g, new Vector3(sceneSize, -sceneSize, -sceneSize), new Vector3(sceneSize, -sceneSize, sceneSize), new Vector3(sceneSize, sceneSize, sceneSize), new Vector3(sceneSize, sceneSize, -sceneSize), sceneSideColors[1]);
        }

        private void DrawScenePlane(Graphics g, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color color)
        {
            PointF[] points = new PointF[4];
            points[0] = ProjectToScreen(p1);
            points[1] = ProjectToScreen(p2);
            points[2] = ProjectToScreen(p3);
            points[3] = ProjectToScreen(p4);

            if (IsValidPolygon(points))
            {
                using (Brush brush = new SolidBrush(color))
                    g.FillPolygon(brush, points);
            }
        }

        private void DrawFull3DGrid(Graphics g)
        {
            using (Pen xyPen = new Pen(gridColors[0], 1))
            {
                for (int z = -gridSize; z <= gridSize; z += gridStep * 2)
                {
                    for (int x = -gridSize; x <= gridSize; x += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(x, -gridSize, z));
                        PointF end = ProjectToScreen(new Vector3(x, gridSize, z));
                        if (IsValidLine(start, end)) g.DrawLine(xyPen, start, end);
                    }
                    for (int y = -gridSize; y <= gridSize; y += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(-gridSize, y, z));
                        PointF end = ProjectToScreen(new Vector3(gridSize, y, z));
                        if (IsValidLine(start, end)) g.DrawLine(xyPen, start, end);
                    }
                }
            }

            using (Pen xzPen = new Pen(gridColors[1], 1))
            {
                for (int y = -gridSize; y <= gridSize; y += gridStep * 2)
                {
                    for (int x = -gridSize; x <= gridSize; x += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(x, y, -gridSize));
                        PointF end = ProjectToScreen(new Vector3(x, y, gridSize));
                        if (IsValidLine(start, end)) g.DrawLine(xzPen, start, end);
                    }
                    for (int z = -gridSize; z <= gridSize; z += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(-gridSize, y, z));
                        PointF end = ProjectToScreen(new Vector3(gridSize, y, z));
                        if (IsValidLine(start, end)) g.DrawLine(xzPen, start, end);
                    }
                }
            }

            using (Pen yzPen = new Pen(gridColors[2], 1))
            {
                for (int x = -gridSize; x <= gridSize; x += gridStep * 2)
                {
                    for (int y = -gridSize; y <= gridSize; y += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(x, y, -gridSize));
                        PointF end = ProjectToScreen(new Vector3(x, y, gridSize));
                        if (IsValidLine(start, end)) g.DrawLine(yzPen, start, end);
                    }
                    for (int z = -gridSize; z <= gridSize; z += gridStep)
                    {
                        PointF start = ProjectToScreen(new Vector3(x, -gridSize, z));
                        PointF end = ProjectToScreen(new Vector3(x, gridSize, z));
                        if (IsValidLine(start, end)) g.DrawLine(yzPen, start, end);
                    }
                }
            }
        }

        private void DrawCoordinateAxes(Graphics g)
        {
            DrawAxis(g, Color.Red, new Vector3(0, 0, 0), new Vector3(gridSize + 100, 0, 0), "X");
            DrawAxis(g, Color.Green, new Vector3(0, 0, 0), new Vector3(0, gridSize + 100, 0), "Y");
            DrawAxis(g, Color.Blue, new Vector3(0, 0, 0), new Vector3(0, 0, gridSize + 100), "Z");
        }

        private void DrawAxis(Graphics g, Color color, Vector3 start, Vector3 end, string label)
        {
            using (Pen pen = new Pen(color, 2))
            {
                PointF p1 = ProjectToScreen(start);
                PointF p2 = ProjectToScreen(end);
                if (IsValidLine(p1, p2))
                {
                    g.DrawLine(pen, p1, p2);
                    DrawArrow(g, pen, p1, p2);
                    DrawAxisLabel(g, color, p2, label);
                }
            }
        }

        private void DrawArrow(Graphics g, Pen pen, PointF start, PointF end)
        {
            float arrowSize = 8;
            float dx = end.X - start.X;
            float dy = end.Y - start.Y;
            float length = (float)Math.Sqrt(dx * dx + dy * dy);

            if (length > 0)
            {
                dx /= length; dy /= length;
                float perpX = -dy; float perpY = dx;

                PointF arrow1 = new PointF(end.X - dx * arrowSize + perpX * arrowSize * 0.5f, end.Y - dy * arrowSize + perpY * arrowSize * 0.5f);
                PointF arrow2 = new PointF(end.X - dx * arrowSize - perpX * arrowSize * 0.5f, end.Y - dy * arrowSize - perpY * arrowSize * 0.5f);

                g.DrawLine(pen, end, arrow1);
                g.DrawLine(pen, end, arrow2);
            }
        }

        private void DrawAxisLabel(Graphics g, Color color, PointF position, string label)
        {
            try
            {
                using (Font font = new Font("Arial", 10, FontStyle.Bold))
                using (Brush brush = new SolidBrush(color))
                {
                    SizeF size = g.MeasureString(label, font);
                    g.DrawString(label, font, brush, position.X + 5, position.Y - size.Height / 2);
                }
            }
            catch { }
        }

        private PointF ProjectToScreen(Vector3 point)
        {
            try
            {
                float x = point.X - cameraPosition.X;
                float y = point.Y - cameraPosition.Y;
                float z = point.Z - cameraPosition.Z;
                float scale = 800 / (800 + z);
                return new PointF(x * scale, y * scale);
            }
            catch { return PointF.Empty; }
        }

        private bool IsValidPoint(PointF point) => !float.IsNaN(point.X) && !float.IsNaN(point.Y) && !float.IsInfinity(point.X) && !float.IsInfinity(point.Y);
        private bool IsValidLine(PointF p1, PointF p2) => IsValidPoint(p1) && IsValidPoint(p2);

        private List GetDrawOrder()
        {
            List order = new List { 0, 1, 2 };
            order.Sort((a, b) => DistanceToCamera(cubes[a]).CompareTo(DistanceToCamera(cubes[b])));
            return order;
        }

        private float DistanceToCamera(Vector3 point)
        {
            float dx = point.X - cameraPosition.X;
            float dy = point.Y - cameraPosition.Y;
            float dz = point.Z - cameraPosition.Z;
            return dx * dx + dy * dy + dz * dz;
        }

        private void DrawCube(Graphics g, Vector3 position, Color color, string label)
        {
            float hs = cubeSize / 2;
            Vector3[] vertices = new Vector3[8];
            vertices[0] = new Vector3(position.X - hs, position.Y - hs, position.Z - hs);
            vertices[1] = new Vector3(position.X + hs, position.Y - hs, position.Z - hs);
            vertices[2] = new Vector3(position.X + hs, position.Y + hs, position.Z - hs);
            vertices[3] = new Vector3(position.X - hs, position.Y + hs, position.Z - hs);
            vertices[4] = new Vector3(position.X - hs, position.Y - hs, position.Z + hs);
            vertices[5] = new Vector3(position.X + hs, position.Y - hs, position.Z + hs);
            vertices[6] = new Vector3(position.X + hs, position.Y + hs, position.Z + hs);
            vertices[7] = new Vector3(position.X - hs, position.Y + hs, position.Z + hs);

            int[][] faces = new int[][]
            {
                new int[] {0,1,2,3}, new int[] {4,5,6,7}, new int[] {1,5,6,2},
                new int[] {0,4,7,3}, new int[] {3,2,6,7}, new int[] {0,1,5,4}
            };

            Color[] faceColors = new Color[]
            {
                AdjustColor(color, -60), AdjustColor(color, -40), AdjustColor(color, -20),
                AdjustColor(color, 20), AdjustColor(color, 40), AdjustColor(color, -80)
            };

            PointF[] projected = new PointF[8];
            for (int i = 0; i < 8; i++) projected[i] = ProjectToScreen(vertices[i]);

            List faceOrder = new List { 0, 1, 2, 3, 4, 5 };
            faceOrder.Sort((a, b) => GetFaceDepth(vertices, faces[b]).CompareTo(GetFaceDepth(vertices, faces[a])));

            foreach (int faceIndex in faceOrder)
            {
                PointF[] points = new PointF[4];
                for (int j = 0; j < 4; j++) points[j] = projected[faces[faceIndex][j]];

                if (IsValidPolygon(points))
                {
                    using (Brush brush = new SolidBrush(faceColors[faceIndex]))
                        g.FillPolygon(brush, points);
                    using (Pen pen = new Pen(outlineColor, 1))
                        g.DrawPolygon(pen, points);
                }
            }

            DrawCubeLabel(g, position, label);
        }

        private float GetFaceDepth(Vector3[] vertices, int[] faceIndices)
        {
            float totalZ = 0;
            foreach (int idx in faceIndices) totalZ += vertices[idx].Z;
            return totalZ / faceIndices.Length;
        }

        private void DrawCubeLabel(Graphics g, Vector3 position, string label)
        {
            try
            {
                PointF screenPos = ProjectToScreen(position);
                using (Font font = new Font("Arial", 14, FontStyle.Bold))
                {
                    SizeF size = g.MeasureString(label, font);
                    float x = screenPos.X - size.Width / 2;
                    float y = screenPos.Y - size.Height / 2;
                    if (x > -1000 && x < 2000 && y > -1000 && y < 2000)
                    {
                        g.DrawString(label, font, Brushes.Black, x + 1, y + 1);
                        g.DrawString(label, font, Brushes.White, x, y);
                    }
                }
            }
            catch { }
        }

        private bool IsValidPolygon(PointF[] points)
        {
            foreach (var point in points) if (!IsValidPoint(point)) return false;
            return true;
        }

        private string GetDirection(float angle)
        {
            float normalizedAngle = angle % 360;
            if (normalizedAngle < 0) normalizedAngle += 360;

            if (normalizedAngle >= 315 || normalizedAngle < 45)
                return "СЕВЕР ↑";
            else if (normalizedAngle >= 45 && normalizedAngle < 135)
                return "ВОСТОК →";
            else if (normalizedAngle >= 135 && normalizedAngle < 225)
                return "ЮГ ↓";
            else
                return "ЗАПАД ←";
        }

        private string GetWasdModeName(WasdMode mode)
        {
            return mode == WasdMode.MoveCubes ? "КУБЫ" : "КАМЕРА";
        }

        private string GetWheelModeName(WheelMode mode)
        {
            return mode == WheelMode.Zoom ? "ZOOM" : "ВЫСОТА (Z)";
        }

        private void DrawHUD(Graphics g)
        {
            try
            {
                int padding = 10;
                int boxWidth = 340;
                int boxHeight = 210;

                using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 20, 20, 30)))
                {
                    g.FillRectangle(bgBrush, padding, padding, boxWidth, boxHeight);
                    g.DrawRectangle(Pens.Gray, padding, padding, boxWidth, boxHeight);
                }

                using (Font font = new Font("Arial", 9, FontStyle.Bold))
                {
                    // Режим WASD
                    string wasdText = $"WASD: {GetWasdModeName(currentWasdMode)} (O/I)";
                    g.DrawString(wasdText, font, currentWasdMode == WasdMode.MoveCubes ? Brushes.Cyan : Brushes.Magenta,
                        padding + 10, padding + 10);

                    // Режим колёсика
                    string wheelText = $"КОЛЁСИКО: {GetWheelModeName(currentWheelMode)}";
                    Brush wheelColor = currentWheelMode == WheelMode.Zoom ? Brushes.White : Brushes.Yellow;
                    g.DrawString(wheelText, font, wheelColor, padding + 10, padding + 30);

                    // Режим управления
                    string modeText = $"РЕЖИМ: {GetModeName(currentControlMode)}";
                    g.DrawString(modeText, font, GetModeColor(currentControlMode), padding + 10, padding + 50);

                    string randomStatus = isRandomized ? "РАНДОМИЗАЦИЯ: ✅ ВКЛ" : "РАНДОМИЗАЦИЯ: ❌ ВЫКЛ";
                    g.DrawString(randomStatus, font, isRandomized ? Brushes.Lime : Brushes.Gray, padding + 10, padding + 70);

                    float camAngle = camY % 360;
                    if (camAngle < 0) camAngle += 360;
                    g.DrawString($"НАПРАВЛЕНИЕ: {GetDirection(camAngle)}", font, Brushes.Yellow, padding + 10, padding + 90);

                    g.DrawString($"КАМЕРА: X:{cameraPosition.X:F0} Y:{cameraPosition.Y:F0} Z:{cameraPosition.Z:F0}",
                        font, Brushes.Cyan, padding + 10, padding + 110);

                    g.DrawString($"УГЛЫ: X={camX:F0}° Y={camY:F0}° Z={camZ:F0}°",
                        font, Brushes.White, padding + 10, padding + 130);

                    g.DrawString($"ZOOM: {zoom:F1}x | СЕТКА: {gridStep}",
                        font, Brushes.Yellow, padding + 10, padding + 150);

                    g.DrawString($"ОРБИТА: {(currentControlMode == ControlMode.OrbitMode ? "🌀 ВКЛ" : "⭕ ВЫКЛ")}",
                        font, currentControlMode == ControlMode.OrbitMode ? Brushes.Magenta : Brushes.Gray,
                        padding + 10, padding + 170);

                    // Информация о модификаторах
                    string modifiers = GetModifiersText();
                    g.DrawString($"МОДИФИКАТОРЫ: {modifiers}", font, Brushes.Orange, padding + 10, padding + 190);
                }
            }
            catch { }
        }

        private string GetModifiersText()
        {
            List mods = new List();
            if (pressedKeys[Keys.ControlKey]) mods.Add("Ctrl");
            if (pressedKeys[Keys.ShiftKey]) mods.Add("Shift");
            if (pressedKeys[Keys.Alt]) mods.Add("Alt");
            return mods.Count > 0 ? string.Join("+", mods) : "нет";
        }

        private string GetModeName(ControlMode mode)
        {
            switch (mode)
            {
                case ControlMode.Default:
                    return "СТАНДАРТНЫЙ";
                case ControlMode.RobloxStyle:
                    return "ROBLOX WASD";
                case ControlMode.HeightControl:
                    return "ВЫСОТА 2/3";
                case ControlMode.Combined:
                    return "ВСЁ ВМЕСТЕ";
                case ControlMode.OrbitMode:
                    return "ВРАЩЕНИЕ";
                default:
                    return "НЕИЗВЕСТНО";
            }
        }

        private Brush GetModeColor(ControlMode mode)
        {
            switch (mode)
            {
                case ControlMode.Default:
                    return Brushes.White;
                case ControlMode.RobloxStyle:
                    return Brushes.Cyan;
                case ControlMode.HeightControl:
                    return Brushes.Lime;
                case ControlMode.Combined:
                    return Brushes.Yellow;
                case ControlMode.OrbitMode:
                    return Brushes.Magenta;
                default:
                    return Brushes.White;
            }
        }

        private string GetActiveKeysText()
        {
            List active = new List();
            if (pressedKeys.ContainsKey(Keys.W) && pressedKeys[Keys.W]) active.Add("W");
            if (pressedKeys.ContainsKey(Keys.A) && pressedKeys[Keys.A]) active.Add("A");
            if (pressedKeys.ContainsKey(Keys.S) && pressedKeys[Keys.S]) active.Add("S");
            if (pressedKeys.ContainsKey(Keys.D) && pressedKeys[Keys.D]) active.Add("D");
            if (pressedKeys.ContainsKey(Keys.Q) && pressedKeys[Keys.Q]) active.Add("Q");
            if (pressedKeys.ContainsKey(Keys.E) && pressedKeys[Keys.E]) active.Add("E");
            if (pressedKeys.ContainsKey(Keys.R) && pressedKeys[Keys.R]) active.Add("R");
            if (pressedKeys.ContainsKey(Keys.T) && pressedKeys[Keys.T]) active.Add("T");
            if (pressedKeys.ContainsKey(Keys.N) && pressedKeys[Keys.N]) active.Add("N");
            if (pressedKeys.ContainsKey(Keys.M) && pressedKeys[Keys.M]) active.Add("M");
            if (pressedKeys.ContainsKey(Keys.O) && pressedKeys[Keys.O]) active.Add("O");
            if (pressedKeys.ContainsKey(Keys.I) && pressedKeys[Keys.I]) active.Add("I");
            if (pressedKeys.ContainsKey(Keys.D2) && pressedKeys[Keys.D2]) active.Add("2");
            if (pressedKeys.ContainsKey(Keys.D3) && pressedKeys[Keys.D3]) active.Add("3");
            return active.Count > 0 ? string.Join(" ", active) : "---";
        }

        private void DrawControls(Graphics g)
        {
            try
            {
                string[] controls = {
                    "=== КОЛЁСИКО МЫШИ (ГЛАВНОЕ!) ===",
                    "Обычное колёсико - ZOOM",
                    "Alt/Ctrl/Shift + колёсико - ВЫСОТА (Z)",
                    "",
                    "=== РЕЖИМЫ WASD ===",
                    "O - WASD двигает КУБЫ",
                    "I - WASD двигает КАМЕРУ",
                    "",
                    "=== 3D ВРАЩЕНИЕ КАМЕРЫ ===",
                    "Зажатое колесо + движение - вращение в 3D",
                    "",
                    "=== РЕЖИМЫ УПРАВЛЕНИЯ ===",
                    "R - ROBLOX WASD",
                    "E - ВЫСОТА 2/3",
                    "T - ВСЁ ВМЕСТЕ",
                    "",
                    "=== СПЕЦИАЛЬНЫЕ КОМАНДЫ ===",
                    "N - РАНДОМНЫЕ цвета и сетка",
                    "M - ОТМЕНА рандомизации",
                    "Ctrl+R - полный сброс",
                    "",
                    "=== ОСНОВНОЕ УПРАВЛЕНИЕ ===",
                    "ЛКМ - вращение камеры",
                    "ПКМ - панорамирование",
                    "Q/E - камера вверх/вниз",
                    "Стрелки - движение кубов",
                    "ESC - выход"
                };

                using (Font font = new Font("Arial", 8, FontStyle.Bold))
                {
                    float maxWidth = 0;
                    foreach (string line in controls)
                    {
                        SizeF size = g.MeasureString(line, font);
                        if (size.Width > maxWidth) maxWidth = size.Width;
                    }

                    float boxWidth = maxWidth + 20;
                    float boxHeight = controls.Length * 16 + 10;
                    float boxX = pictureBox1.Width - boxWidth - 10;
                    float boxY = 10;

                    if (boxX < 0) boxX = 10;

                    using (Brush bgBrush = new SolidBrush(Color.FromArgb(220, 0, 0, 0)))
                    {
                        g.FillRectangle(bgBrush, boxX, boxY, boxWidth, boxHeight);
                        g.DrawRectangle(Pens.Gray, boxX, boxY, boxWidth, boxHeight);
                    }

                    for (int i = 0; i < controls.Length; i++)
                    {
                        Brush color = Brushes.White;
                        if (controls[i].Contains("КОЛЁСИКО")) color = Brushes.Yellow;
                        else if (controls[i].Contains("Alt/Ctrl/Shift")) color = Brushes.Lime;
                        else if (controls[i].Contains("WASD")) color = Brushes.Cyan;
                        else if (controls[i].Contains("3D")) color = Brushes.Magenta;
                        else if (controls[i].Contains("O -")) color = Brushes.Cyan;
                        else if (controls[i].Contains("I -")) color = Brushes.Magenta;
                        else if (controls[i].Contains("R -")) color = Brushes.Cyan;
                        else if (controls[i].Contains("E -")) color = Brushes.Lime;
                        else if (controls[i].Contains("T -")) color = Brushes.Yellow;
                        else if (controls[i].Contains("N -")) color = Brushes.Magenta;
                        else if (controls[i].Contains("M -")) color = Brushes.Orange;
                        else if (controls[i].Contains("Ctrl+R")) color = Brushes.Red;
                        else if (controls[i].Contains("===")) color = Brushes.Yellow;

                        float y = boxY + 5 + i * 16;
                        g.DrawString(controls[i], font, color, boxX + 10, y);
                    }
                }
            }
            catch { }
        }

        private Color AdjustColor(Color c, int adj)
        {
            int Clamp(int val) => Math.Max(0, Math.Min(255, val));
            return Color.FromArgb(Clamp(c.R + adj), Clamp(c.G + adj), Clamp(c.B + adj));
        }

        private void RandomizeEverything()
        {
            SaveCurrentState();

            for (int i = 0; i < cubeColors.Length; i++)
                cubeColors[i] = Color.FromArgb(random.Next(50, 255), random.Next(50, 255), random.Next(50, 255));

            for (int i = 0; i < sceneSideColors.Length; i++)
                sceneSideColors[i] = Color.FromArgb(60, random.Next(50, 200), random.Next(50, 200), random.Next(50, 200));

            for (int i = 0; i < gridColors.Length; i++)
                gridColors[i] = Color.FromArgb(80, random.Next(100, 255), random.Next(100, 255), random.Next(100, 255));

            gridStep = random.Next(20, 101);

            for (int i = 0; i < cubes.Count; i++)
            {
                cubes[i].X += random.Next(-100, 101);
                cubes[i].Y += random.Next(-50, 51);
                cubes[i].Z += random.Next(-100, 101);
            }

            isRandomized = true;
            pictureBox1.Invalidate();
        }

        private void UndoRandomization()
        {
            if (cubeColorsHistory.Count > 0)
            {
                cubeColors = cubeColorsHistory[cubeColorsHistory.Count - 1];
                sceneSideColors = sceneColorsHistory[sceneColorsHistory.Count - 1];
                gridColors = gridColorsHistory[gridColorsHistory.Count - 1];
                gridStep = gridStepHistory[gridStepHistory.Count - 1];
                cubes = cubesHistory[cubesHistory.Count - 1];

                cubeColorsHistory.RemoveAt(cubeColorsHistory.Count - 1);
                sceneColorsHistory.RemoveAt(sceneColorsHistory.Count - 1);
                gridColorsHistory.RemoveAt(gridColorsHistory.Count - 1);
                gridStepHistory.RemoveAt(gridStepHistory.Count - 1);
                cubesHistory.RemoveAt(cubesHistory.Count - 1);

                isRandomized = cubeColorsHistory.Count > 0;
                pictureBox1.Invalidate();
            }
            else
            {
                cubeColors = (Color[])originalCubeColors.Clone();
                sceneSideColors = (Color[])originalSceneSideColors.Clone();
                gridColors = (Color[])originalGridColors.Clone();
                gridStep = originalGridStep;
                cubes = new List { new Vector3(0, 0, 0), new Vector3(150, 0, 150), new Vector3(-150, 0, 300) };
                isRandomized = false;
                pictureBox1.Invalidate();
            }
        }

        private void SaveCurrentState()
        {
            cubeColorsHistory.Add((Color[])cubeColors.Clone());
            sceneColorsHistory.Add((Color[])sceneSideColors.Clone());
            gridColorsHistory.Add((Color[])gridColors.Clone());
            gridStepHistory.Add(gridStep);

            List cubeCopy = new List();
            foreach (var cube in cubes)
                cubeCopy.Add(new Vector3(cube.X, cube.Y, cube.Z));
            cubesHistory.Add(cubeCopy);

            if (cubeColorsHistory.Count > 5)
            {
                cubeColorsHistory.RemoveAt(0);
                sceneColorsHistory.RemoveAt(0);
                gridColorsHistory.RemoveAt(0);
                gridStepHistory.RemoveAt(0);
                cubesHistory.RemoveAt(0);
            }
        }

        // ===== МЫШКА =====
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isRotating = true;
                lastMouse = e.Location;
                pictureBox1.Cursor = Cursors.Hand;
            }
            else if (e.Button == MouseButtons.Right)
            {
                isPanning = true;
                lastMouse = e.Location;
                pictureBox1.Cursor = Cursors.SizeAll;
            }
            else if (e.Button == MouseButtons.Middle)
            {
                isOrbiting = true;
                pictureBox1.Cursor = Cursors.Cross;
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isRotating && e.Button == MouseButtons.Left)
            {
                int dx = e.X - lastMouse.X;
                int dy = e.Y - lastMouse.Y;
                camY += dx * rotateSpeed;
                camX += dy * rotateSpeed;
                camX = Math.Max(-90, Math.Min(90, camX));
                lastMouse = e.Location;
                pictureBox1.Invalidate();
            }
            else if (isPanning && e.Button == MouseButtons.Right)
            {
                int dx = e.X - lastMouse.X;
                int dy = e.Y - lastMouse.Y;
                cameraPosition.X -= dx * 2;
                cameraPosition.Y -= dy * 2;
                lastMouse = e.Location;
                pictureBox1.Invalidate();
            }
            else if (isOrbiting && e.Button == MouseButtons.Middle)
            {
                int dx = e.X - lastMouse.X;
                int dy = e.Y - lastMouse.Y;

                camY += dx * rotateSpeed * 0.5f;
                camX += dy * rotateSpeed * 0.3f;
                camZ += dx * rotateSpeed * 0.2f;

                camX = Math.Max(-180, Math.Min(180, camX));
                camZ = Math.Max(-45, Math.Min(45, camZ));

                lastMouse = e.Location;
                pictureBox1.Invalidate();
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isRotating = false;
                pictureBox1.Cursor = Cursors.Default;
            }
            else if (e.Button == MouseButtons.Right)
            {
                isPanning = false;
                pictureBox1.Cursor = Cursors.Default;
            }
            else if (e.Button == MouseButtons.Middle)
            {
                isOrbiting = false;
                pictureBox1.Cursor = Cursors.Default;
            }
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            // Определяем режим колёсика по нажатым модификаторам
            bool ctrlPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control;
            bool altPressed = (Control.ModifierKeys & Keys.Alt) == Keys.Alt;
            bool shiftPressed = (Control.ModifierKeys & Keys.Shift) == Keys.Shift;

            if (ctrlPressed || altPressed || shiftPressed)
            {
                // РЕЖИМ ВЫСОТЫ (Z координаты) с модификаторами
                currentWheelMode = WheelMode.HeightControl;
                float heightChange = e.Delta * 0.5f; // Меньшая чувствительность для высоты

                if (currentWasdMode == WasdMode.MoveCubes)
                {
                    // Изменяем Z координату кубов
                    foreach (var cube in cubes)
                        cube.Z += heightChange;
                }
                else
                {
                    // Изменяем Z координату камеры
                    cameraPosition.Z += heightChange;
                }
            }
            else
            {
                // РЕЖИМ ZOOM (обычный)
                currentWheelMode = WheelMode.Zoom;
                zoom += e.Delta * 0.001f;
                zoom = Math.Max(0.1f, Math.Min(5.0f, zoom));
            }

            pictureBox1.Invalidate();
        }

        // ===== КЛАВИАТУРА =====
        private void Form2_KeyDown(object sender, KeyEventArgs e)
        {
            // Обновляем состояние модификаторов
            if (e.KeyCode == Keys.ControlKey) pressedKeys[Keys.ControlKey] = true;
            if (e.KeyCode == Keys.ShiftKey) pressedKeys[Keys.ShiftKey] = true;
            if (e.KeyCode == Keys.Alt) pressedKeys[Keys.Alt] = true;

            if (!pressedKeys.ContainsKey(e.KeyCode))
                pressedKeys[e.KeyCode] = true;
            else
                pressedKeys[e.KeyCode] = true;

            // Переключение режимов WASD
            if (e.KeyCode == Keys.O && !e.Control && !e.Alt && !e.Shift)
            {
                currentWasdMode = WasdMode.MoveCubes;
            }
            else if (e.KeyCode == Keys.I && !e.Control && !e.Alt && !e.Shift)
            {
                currentWasdMode = WasdMode.MoveCamera;
            }
            // Переключение режимов управления
            else if (e.KeyCode == Keys.R && !e.Control && !e.Alt && !e.Shift)
            {
                currentControlMode = currentControlMode != ControlMode.RobloxStyle ? ControlMode.RobloxStyle : ControlMode.Default;
            }
            else if (e.KeyCode == Keys.E && !e.Control && !e.Alt && !e.Shift)
            {
                currentControlMode = currentControlMode != ControlMode.HeightControl ? ControlMode.HeightControl : ControlMode.Default;
            }
            else if (e.KeyCode == Keys.T && !e.Control && !e.Alt && !e.Shift)
            {
                currentControlMode = currentControlMode != ControlMode.Combined ? ControlMode.Combined : ControlMode.Default;
            }
            else if (e.KeyCode == Keys.R && e.Control)
            {
                ResetView();
            }
            else if (e.KeyCode == Keys.N && !e.Control && !e.Alt && !e.Shift)
            {
                RandomizeEverything();
            }
            else if (e.KeyCode == Keys.M && !e.Control && !e.Alt && !e.Shift)
            {
                UndoRandomization();
            }
            else if (e.KeyCode == Keys.Escape)
            {
                this.Close();
            }

            pictureBox1.Invalidate();
        }

        private void Form2_KeyUp(object sender, KeyEventArgs e)
        {
            // Обновляем состояние модификаторов
            if (e.KeyCode == Keys.ControlKey) pressedKeys[Keys.ControlKey] = false;
            if (e.KeyCode == Keys.ShiftKey) pressedKeys[Keys.ShiftKey] = false;
            if (e.KeyCode == Keys.Alt) pressedKeys[Keys.Alt] = false;

            if (pressedKeys.ContainsKey(e.KeyCode))
                pressedKeys[e.KeyCode] = false;
        }

        private void ResetView()
        {
            cubes = new List { new Vector3(0, 0, 0), new Vector3(150, 0, 150), new Vector3(-150, 0, 300) };
            camX = 35; camY = -35; camZ = 0; zoom = 1.2f;
            cameraPosition = new Vector3(0, 0, 500);
            currentControlMode = ControlMode.Default;
            currentWasdMode = WasdMode.MoveCubes;
            currentWheelMode = WheelMode.Zoom;
            orbitSpeed = 2f;
            UndoRandomization();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            pictureBox1.MouseDown += pictureBox1_MouseDown;
            pictureBox1.MouseMove += pictureBox1_MouseMove;
            pictureBox1.MouseUp += pictureBox1_MouseUp;
            pictureBox1.MouseWheel += pictureBox1_MouseWheel;
            pictureBox1.Paint += PictureBox1_Paint;
            this.KeyDown += Form2_KeyDown;
            this.KeyUp += Form2_KeyUp;
            this.Focus();
        }

        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            gameTimer?.Stop();
            gameTimer?.Dispose();
        }

        private class Vector3
        {
            public float X, Y, Z;
            public Vector3(float x, float y, float z) { X = x; Y = y; Z = z; }
        }
    }
}

    

Form2.Designer.cs

namespace MenuTOD
{
    partial class Form2
    {
        private System.ComponentModel.IContainer components = null;
        private System.Windows.Forms.PictureBox pictureBox1;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();

            // pictureBox1
            // 
            this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.pictureBox1.Location = new System.Drawing.Point(0, 0);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(800, 600);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;

            // Form2
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 600);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form2";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "3 Куба - 3D Вьюер";
            this.Load += new System.EventHandler(this.Form2_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);
        }
    }
}
    

Form3.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;

namespace MenuTOD
{
    public partial class Form3 : Form
    {
        private World world;
        private PlayerShip player;
        private bool[] keysPressed = new bool[256];
        private PointF cameraPos = PointF.Empty;
        private float scale = 1.0f;
        private Random rnd = new Random();

        private int worldSeed = 12345;
        private SolarSystem currentSystem = null;
        private bool editorMode = false;
        private SolarSystem editingSystem = null;
        private int selectedObjectType = 0;

        private Color spaceColor = Color.FromArgb(10, 10, 40);
        private bool cameraFollowsPlayer = true;
        private float cooldownTimer = 0f;
        private float timeScale = 1.0f;

        private List starParticles = new List();
        private List superShips = new List();

        // Шаблоны для редактора
        private List planetTemplates = new List();
        private List starTemplates = new List();

        public Form3()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
            this.KeyPreview = true;
            this.WindowState = FormWindowState.Maximized;
            this.Text = "Космический Симулятор - Редактор Spore-стиль";
            this.BackColor = Color.Black;

            InitializeTemplates();
            InitializeGame();

            SetupEditorMenu();

            Timer gameTimer = new Timer();
            gameTimer.Interval = 16;
            gameTimer.Tick += GameTimer_Tick;
            gameTimer.Start();

            GenerateWorld();
        }

        private void InitializeGame()
        {
            world = new World();
            player = new PlayerShip();
            GenerateWorld();
        }

        private void InitializeTemplates()
        {
            planetTemplates.Clear();
            starTemplates.Clear();

            // Создаем 18 типов планет по 10 вариантов каждый
            string[] planetTypes = {
                "Каменная", "Газовый гигант", "Ледяная", "Землеподобная", "Лава",
                "Кислотная", "Мясная", "Голограмма", "Молочная", "Построенная",
                "Стимпанк", "Водная", "Алмазная", "Урановая", "Город-планета",
                "Живая", "Мега-планета", "Цитадель"
            };

            foreach (string type in planetTypes)
            {
                for (int i = 1; i <= 10; i++)
                {
                    Color color = GetPlanetColor(type, i);
                    PlanetTemplate template = new PlanetTemplate
                    {
                        Name = type + "-" + i,
                        Type = type,
                        Color = color,
                        Radius = 8 + i + (type.Length % 5),
                        Composition = GetComposition(type),
                        CanBeColonized = CanBeColonized(type),
                        HasRings = i % 3 == 0,
                        HasAtmosphere = HasAtmosphere(type),
                        HasLife = type == "Землеподобная" && i > 5,
                        IsAcid = type == "Кислотная",
                        IsMeat = type == "Мясная",
                        IsHologram = type == "Голограмма",
                        IsMilk = type == "Молочная",
                        IsConstructed = type == "Построенная",
                        IsSteampunk = type == "Стимпанк",
                        IsWater = type == "Водная",
                        IsDiamond = type == "Алмазная",
                        IsUranium = type == "Урановая",
                        IsCity = type == "Город-планета",
                        IsAlive = type == "Живая",
                        IsMega = type == "Мега-планета",
                        IsCitadel = type == "Цитадель",
                        IsSystemCenter = type == "Мега-планета" && i % 3 == 0
                    };

                    // Устанавливаем дополнительные свойства в зависимости от типа
                    if (type == "Мясная")
                        template.BugCount = i * 2;
                    if (type == "Живая")
                        template.EyeCount = 4 + i % 8;
                    if (type == "Стимпанк")
                        template.GearCount = 3 + i % 5;
                    if (type == "Урановая")
                        template.RadiationLevel = 3 + i % 5;
                    if (type == "Алмазная")
                        template.SparkleIntensity = 5 + i;
                    if (type == "Город-планета")
                    {
                        template.BuildingCount = 50 + i * 10;
                        template.CityLights = true;
                    }

                    planetTemplates.Add(template);
                }
            }

            // Создаем звезды
            string[] starTypes = { "Желтый карлик", "Красный карлик", "Голубой гигант", "Красный гигант", "Двойная система", "Белый карлик", "Нейтронная звезда", "Черная дыра" };
            foreach (string type in starTypes)
            {
                for (int i = 1; i <= 10; i++)
                {
                    StarTemplate template = new StarTemplate
                    {
                        Name = type + "-" + i,
                        Type = type,
                        Color = GetStarColor(type),
                        Radius = GetStarRadius(type, i),
                        Temperature = GetStarTemperature(type),
                        IsBinary = type == "Двойная система",
                        IsNeutron = type == "Нейтронная звезда",
                        IsBlackHole = type == "Черная дыра"
                    };
                    starTemplates.Add(template);
                }
            }
        }

        private Color GetPlanetColor(string type, int variant)
        {
            switch (type)
            {
                case "Каменная":
                    return Color.FromArgb(80 + variant * 10, 80 + variant * 10, 80 + variant * 10);
                case "Газовый гигант":
                    return Color.FromArgb(255, 165 + variant * 3, 0);
                case "Ледяная":
                    return Color.FromArgb(150, 200 + variant * 2, 255);
                case "Землеподобная":
                    return Color.FromArgb(0, 100 + variant * 5, 0);
                case "Лава":
                    return Color.FromArgb(139 + variant * 5, 0, 0);
                case "Кислотная":
                    return Color.FromArgb(0, 255 - variant * 5, 0);
                case "Мясная":
                    return Color.FromArgb(139 + variant * 5, 69 + variant * 2, 19);
                case "Голограмма":
                    return Color.FromArgb(100, 150 + variant * 5, 255, 150 + variant * 5);
                case "Молочная":
                    return Color.FromArgb(255, 250 - variant * 5, 240 - variant * 5);
                case "Построенная":
                    return Color.FromArgb(100 + variant * 5, 100 + variant * 5, 100 + variant * 5);
                case "Стимпанк":
                    return Color.FromArgb(139 + variant * 2, 69 + variant, 19);
                case "Водная":
                    return Color.FromArgb(0, 0, 139 + variant * 5);
                case "Алмазная":
                    return Color.FromArgb(0, 255 - variant * 5, 255 - variant * 5);
                case "Урановая":
                    return Color.FromArgb(0, 255 - variant * 5, 0);
                case "Город-планета":
                    return Color.FromArgb(50 + variant * 5, 50 + variant * 5, 50 + variant * 5);
                case "Живая":
                    return Color.FromArgb(255, 100 + variant * 5, 150 + variant * 5);
                case "Мега-планета":
                    return Color.FromArgb(100 + variant * 5, 100 + variant * 5, 100);
                case "Цитадель":
                    return Color.FromArgb(192 - variant * 2, 192 - variant * 2, 192 - variant * 2);
                default:
                    return Color.Gray;
            }
        }

        private Color GetStarColor(string type)
        {
            switch (type)
            {
                case "Желтый карлик":
                    return Color.Yellow;
                case "Красный карлик":
                    return Color.OrangeRed;
                case "Голубой гигант":
                    return Color.LightBlue;
                case "Красный гигант":
                    return Color.Red;
                case "Двойная система":
                    return Color.Orange;
                case "Белый карлик":
                    return Color.White;
                case "Нейтронная звезда":
                    return Color.Cyan;
                case "Черная дыра":
                    return Color.FromArgb(30, 30, 30);
                default:
                    return Color.White;
            }
        }

        private float GetStarRadius(string type, int variant)
        {
            switch (type)
            {
                case "Желтый карлик":
                    return 30 + variant * 2;
                case "Красный карлик":
                    return 20 + variant;
                case "Голубой гигант":
                    return 50 + variant * 3;
                case "Красный гигант":
                    return 60 + variant * 4;
                case "Двойная система":
                    return 40 + variant * 2;
                case "Белый карлик":
                    return 15 + variant;
                case "Нейтронная звезда":
                    return 8 + variant;
                case "Черная дыра":
                    return 25 + variant * 2;
                default:
                    return 30 + variant;
            }
        }

        private int GetStarTemperature(string type)
        {
            switch (type)
            {
                case "Желтый карлик":
                    return 5700;
                case "Красный карлик":
                    return 3500;
                case "Голубой гигант":
                    return 30000;
                case "Красный гигант":
                    return 3500;
                case "Двойная система":
                    return 6000;
                case "Белый карлик":
                    return 10000;
                case "Нейтронная звезда":
                    return 1000000;
                case "Черная дыра":
                    return 0;
                default:
                    return 5000;
            }
        }

        private string GetComposition(string type)
        {
            switch (type)
            {
                case "Каменная":
                    return "Кремний, железо";
                case "Газовый гигант":
                    return "Водород, гелий";
                case "Ледяная":
                    return "Водяной лед";
                case "Землеподобная":
                    return "Кислород, вода";
                case "Лава":
                    return "Базальт, лава";
                case "Кислотная":
                    return "Серная кислота";
                case "Мясная":
                    return "Биомасса";
                case "Голограмма":
                    return "Свет, данные";
                case "Молочная":
                    return "Лактоза";
                case "Построенная":
                    return "Металл";
                case "Стимпанк":
                    return "Шестерни, пар";
                case "Водная":
                    return "Вода, океаны";
                case "Алмазная":
                    return "Углерод, алмазы";
                case "Урановая":
                    return "Уран, радиация";
                case "Город-планета":
                    return "Мегаполис";
                case "Живая":
                    return "Сознание, плоть";
                case "Мега-планета":
                    return "Колоссальная масса";
                case "Цитадель":
                    return "Искусственная структура";
                default:
                    return "Неизвестно";
            }
        }

        private bool CanBeColonized(string type)
        {
            switch (type)
            {
                case "Каменная":
                case "Газовый гигант":
                case "Ледяная":
                case "Лава":
                case "Кислотная":
                case "Урановая":
                    return false;
                default:
                    return true;
            }
        }

        private bool HasAtmosphere(string type)
        {
            switch (type)
            {
                case "Газовый гигант":
                case "Землеподобная":
                case "Кислотная":
                case "Мясная":
                case "Молочная":
                case "Построенная":
                case "Стимпанк":
                case "Водная":
                case "Город-планета":
                case "Живая":
                case "Мега-планета":
                    return true;
                default:
                    return false;
            }
        }

        private void SetupEditorMenu()
        {
            MenuStrip menu = new MenuStrip();
            menu.BackColor = Color.FromArgb(40, 40, 40);
            menu.ForeColor = Color.White;

            ToolStripMenuItem fileMenu = new ToolStripMenuItem("Файл");
            ToolStripMenuItem newWorld = new ToolStripMenuItem("Новый мир", null, (s, e) => NewWorld());
            ToolStripMenuItem toggleEditor = new ToolStripMenuItem("Режим редактора", null, (s, e) => ToggleEditor());
            ToolStripMenuItem createSystem = new ToolStripMenuItem("Создать систему", null, (s, e) => CreateSystem());

            fileMenu.DropDownItems.AddRange(new ToolStripItem[] { newWorld, toggleEditor, createSystem });
            menu.Items.Add(fileMenu);

            this.MainMenuStrip = menu;
            this.Controls.Add(menu);
        }

        private void NewWorld()
        {
            using (var dialog = new SeedInputDialog("Введите сид для мира:"))
            {
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    worldSeed = dialog.Seed;
                    GenerateWorld();
                }
            }
        }

        private void ToggleEditor()
        {
            editorMode = !editorMode;
            if (editorMode && currentSystem != null)
            {
                editingSystem = currentSystem;
            }
            else
            {
                editingSystem = null;
            }
            Invalidate();
        }

        private void CreateSystem()
        {
            using (var dialog = new SystemCreationDialog(starTemplates))
            {
                if (dialog.ShowDialog() == DialogResult.OK && dialog.CreatedSystem != null)
                {
                    SolarSystem newSystem = dialog.CreatedSystem;
                    newSystem.Position = player.Position;
                    world.Systems.Add(newSystem);

                    currentSystem = newSystem;
                    editingSystem = newSystem;
                    scale = 0.02f;
                    editorMode = true;

                    Invalidate();
                }
            }
        }

        private void GenerateWorld()
        {
            world = new World();
            starParticles.Clear();
            superShips.Clear();
            rnd = new Random(worldSeed);

            currentSystem = null;
            editingSystem = null;
            editorMode = false;
            cameraPos = PointF.Empty;
            scale = 0.0005f; // Очень маленький масштаб для всей галактики
            player.Position = new PointF(1000, 1000);
            player.Velocity = PointF.Empty;
            timeScale = 1.0f;

            // Создаем фоновые звезды
            for (int i = 0; i < 5000; i++)
            {
                starParticles.Add(new StarParticle(this.ClientSize, rnd));
            }

            // Создаем несколько супер-кораблей
            for (int i = 0; i < 10; i++)
            {
                superShips.Add(new SuperShip(rnd));
            }

            // Генерация галактики (250-500 систем)
            int systemCount = rnd.Next(250, 501);
            world.SystemCount = systemCount;

            GenerateGalaxy(systemCount);
            Invalidate();
        }

        private void GenerateGalaxy(int systemCount)
        {
            // Спиральная галактика
            float galaxyRadius = 40000;
            int arms = 4;

            for (int i = 0; i < systemCount; i++)
            {
                SolarSystem system = new SolarSystem();

                float angle = (float)(rnd.NextDouble() * Math.PI * 2);
                float distance = (float)Math.Sqrt(rnd.NextDouble()) * galaxyRadius;

                // Исправленный расчет смещения рукава
                double armAngle = angle * arms;
                float armOffset = (float)(armAngle - Math.Floor(armAngle / (Math.PI * 2)) * (Math.PI * 2));
                distance += (float)Math.Sin(armOffset) * 5000;

                system.Position = new PointF(
                    (float)Math.Cos(angle) * distance,
                    (float)Math.Sin(angle) * distance
                );

                system.ID = world.Systems.Count + 1;
                system.Name = "Система " + system.ID.ToString("0000");

                GenerateSolarSystem(system, i);
                world.Systems.Add(system);
            }
        }

        private void GenerateSolarSystem(SolarSystem system, int index)
        {
            // Создаем звезду с улучшенной логикой
            int starType = rnd.Next(100);
            Star star = new Star();
            star.Position = system.Position;

            if (starType < 40)
            {
                star.Radius = rnd.Next(40, 70);
                star.Color = GetStarColor("Желтый карлик");
                star.Type = "Желтый карлик";
                star.Temperature = 5700;
            }
            else if (starType < 65)
            {
                star.Radius = rnd.Next(30, 50);
                star.Color = GetStarColor("Красный карлик");
                star.Type = "Красный карлик";
                star.Temperature = 3500;
            }
            else if (starType < 80)
            {
                star.Radius = rnd.Next(80, 120);
                star.Color = GetStarColor("Голубой гигант");
                star.Type = "Голубой гигант";
                star.Temperature = 30000;
                star.IsGiant = true;
            }
            else if (starType < 92)
            {
                star.Radius = rnd.Next(100, 160);
                star.Color = GetStarColor("Красный гигант");
                star.Type = "Красный гигант";
                star.Temperature = 3500;
                star.IsGiant = true;
            }
            else if (starType < 98)
            {
                star.Radius = rnd.Next(15, 25);
                star.Color = GetStarColor("Белый карлик");
                star.Type = "Белый карлик";
                star.Temperature = 10000;
            }
            else if (starType < 99)
            {
                star.Radius = rnd.Next(8, 12);
                star.Color = GetStarColor("Нейтронная звезда");
                star.Type = "Нейтронная звезда";
                star.Temperature = 1000000;
                star.IsNeutron = true;
            }
            else
            {
                star.Radius = rnd.Next(25, 35);
                star.Color = GetStarColor("Черная дыра");
                star.Type = "Черная дыра";
                star.Temperature = 0;
                star.IsBlackHole = true;
            }

            // Двойная система (10% шанс)
            if (rnd.Next(100) < 10)
            {
                star.IsBinary = true;
                star.BinaryRadius = star.Radius * 0.6f;
                star.BinaryColor = star.Type == "Красный гигант" ? GetStarColor("Белый карлик") :
                                  star.Type == "Желтый карлик" ? GetStarColor("Красный карлик") :
                                  GetStarColor("Желтый карлик");
            }

            system.Stars.Add(star);

            // Создаем планеты с разнообразием типов
            int planetCount = rnd.Next(2, 15);
            for (int p = 0; p < planetCount; p++)
            {
                int planetIndex = rnd.Next(planetTemplates.Count);
                PlanetTemplate planetTemplate = planetTemplates[planetIndex];

                Planet planet = CreatePlanetFromTemplate(system, p, planetTemplate, rnd);
                system.Planets.Add(planet);
            }
        }

        private Planet CreatePlanetFromTemplate(SolarSystem system, int index, PlanetTemplate template, Random random)
        {
            Planet planet = new Planet();
            float orbitRadius = 80 + index * 60 + random.Next(-15, 15);
            float angle = (float)(random.NextDouble() * 2 * Math.PI);

            planet.Position = new PointF(
                system.Position.X + (float)Math.Cos(angle) * orbitRadius,
                system.Position.Y + (float)Math.Sin(angle) * orbitRadius
            );

            planet.Name = template.Name;
            planet.Radius = template.Radius;
            planet.Color = template.Color;
            planet.Type = template.Type;
            planet.Composition = template.Composition;
            planet.CanBeColonized = template.CanBeColonized;
            planet.OrbitCenter = system.Position;
            planet.OrbitRadius = orbitRadius;
            planet.OrbitSpeed = (float)(0.01 + random.NextDouble() * 0.08) / (index + 1);
            planet.SpinSpeed = (float)(random.NextDouble() * 0.03);
            planet.SpinAngle = (float)(random.NextDouble() * 2 * Math.PI);
            planet.HasRings = template.HasRings;
            planet.HasAtmosphere = template.HasAtmosphere;
            planet.IsMega = template.IsMega;
            planet.IsCitadel = template.IsCitadel;
            planet.IsAcid = template.IsAcid;
            planet.IsMeat = template.IsMeat;
            planet.IsHologram = template.IsHologram;
            planet.IsMilk = template.IsMilk;
            planet.IsConstructed = template.IsConstructed;
            planet.IsSteampunk = template.IsSteampunk;
            planet.IsWater = template.IsWater;
            planet.IsDiamond = template.IsDiamond;
            planet.IsUranium = template.IsUranium;
            planet.IsCity = template.IsCity;
            planet.IsAlive = template.IsAlive;
            planet.HasLife = template.HasLife;
            planet.HasBugs = template.HasBugs;
            planet.BugCount = template.BugCount;
            planet.EyeCount = template.EyeCount;
            planet.CannotScan = template.CannotScan;
            planet.GearCount = template.GearCount;
            planet.RadiationLevel = template.RadiationLevel;
            planet.SparkleIntensity = template.SparkleIntensity;
            planet.BuildingCount = template.BuildingCount;
            planet.CityLights = template.CityLights;
            planet.IsSystemCenter = template.IsSystemCenter;

            if (planet.HasRings)
            {
                planet.RingInner = planet.Radius + 4;
                planet.RingOuter = planet.Radius + 20;
                planet.RingColor = Color.Goldenrod;
            }

            return planet;
        }

        private void GameTimer_Tick(object sender, EventArgs e)
        {
            UpdatePlayerMovement();
            player.Update(timeScale);
            UpdateWorld();
            UpdateCamera();
            CheckSystemEntry();
            Invalidate();
        }

        private void UpdatePlayerMovement()
        {
            float thrust = 0.15f * timeScale;
            float rotationSpeed = 0.08f * timeScale;

            if (keysPressed[(int)Keys.W] || keysPressed[(int)Keys.Up])
                player.ThrustForward(thrust);
            if (keysPressed[(int)Keys.S] || keysPressed[(int)Keys.Down])
                player.ThrustForward(-thrust * 0.5f);
            if (keysPressed[(int)Keys.A] || keysPressed[(int)Keys.Left])
                player.Rotation -= rotationSpeed;
            if (keysPressed[(int)Keys.D] || keysPressed[(int)Keys.Right])
                player.Rotation += rotationSpeed;

            if (keysPressed[(int)Keys.Space])
            {
                player.Velocity = new PointF(
                    player.Velocity.X * 0.9f,
                    player.Velocity.Y * 0.9f
                );
            }

            // Управление временем Z/X
            if (keysPressed[(int)Keys.Z] && timeScale > 0.1f)
                timeScale *= 0.99f;
            if (keysPressed[(int)Keys.X] && timeScale < 10.0f)
                timeScale *= 1.01f;

            if (cooldownTimer > 0) cooldownTimer -= 0.016f * timeScale;
        }

        private void UpdateWorld()
        {
            world.Update(timeScale);
            foreach (var star in starParticles) star.Update();
            foreach (var ship in superShips) ship.Update();
        }

        private void UpdateCamera()
        {
            if (cameraFollowsPlayer)
            {
                cameraPos = new PointF(
                    cameraPos.X + (player.Position.X - cameraPos.X) * 0.05f,
                    cameraPos.Y + (player.Position.Y - cameraPos.Y) * 0.05f
                );
            }
        }

        private void CheckSystemEntry()
        {
            if (currentSystem == null && cooldownTimer <= 0)
            {
                SolarSystem nearest = world.GetNearestSystem(player.Position);
                if (nearest != null)
                {
                    float dx = nearest.Position.X - player.Position.X;
                    float dy = nearest.Position.Y - player.Position.Y;
                    float distance = (float)Math.Sqrt(dx * dx + dy * dy);

                    float entryDistance = 500 / scale;

                    if (distance < entryDistance)
                    {
                        EnterSystem(nearest);
                    }
                }
            }
        }

        private void EnterSystem(SolarSystem system)
        {
            if (cooldownTimer > 0) return;

            currentSystem = system;
            scale = 0.02f;

            if (editorMode)
            {
                editingSystem = system;
            }

            MessageBox.Show($"Вход в систему: {system.Name}\nЗвезда: {system.Stars[0].Type}",
                          "Обнаружена система");
        }

        private void ExitSystem()
        {
            if (currentSystem != null)
            {
                currentSystem = null;
                editingSystem = null;
                scale = 0.0005f;
                cooldownTimer = 1.0f;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.Clear(Color.Black);

            // Рисуем фоновые звезды
            foreach (var star in starParticles)
            {
                star.Draw(g, cameraPos, scale);
            }

            // Рисуем галактический фон
            DrawGalaxyBackground(g);

            g.TranslateTransform(ClientSize.Width / 2, ClientSize.Height / 2);
            g.ScaleTransform(scale, scale);
            g.TranslateTransform(-cameraPos.X, -cameraPos.Y);

            // Рисуем игровой мир
            world.Draw(g, player.Position, currentSystem, scale);

            // Рисуем супер-корабли
            foreach (var ship in superShips) ship.Draw(g, scale);

            // Игрок
            player.Draw(g);

            g.ResetTransform();

            // Рисуем интерфейс
            DrawHUD(g);

            if (editorMode && editingSystem != null)
            {
                DrawEditorUI(g);
            }
        }

        private void DrawGalaxyBackground(Graphics g)
        {
            // Туманности и газовые облака
            Random bgRnd = new Random(worldSeed);
            for (int i = 0; i < 20; i++)
            {
                float x = bgRnd.Next(ClientSize.Width);
                float y = bgRnd.Next(ClientSize.Height);
                float size = bgRnd.Next(100, 400);

                Color[] nebulaColors = {
                    Color.FromArgb(30, 100, 0, 200),   // Фиолетовая
                    Color.FromArgb(30, 200, 100, 0),   // Оранжевая
                    Color.FromArgb(30, 0, 150, 200),   // Голубая
                    Color.FromArgb(30, 200, 0, 100)    // Розовая
                };

                using (Brush nebulaBrush = new SolidBrush(nebulaColors[bgRnd.Next(nebulaColors.Length)]))
                {
                    g.FillEllipse(nebulaBrush, x - size / 2, y - size / 2, size, size);
                }
            }
        }

        private void DrawHUD(Graphics g)
        {
            string info = $"Координаты: {player.Position.X:F0}, {player.Position.Y:F0}\n" +
                         $"Скорость: {Math.Sqrt(player.Velocity.X * player.Velocity.X + player.Velocity.Y * player.Velocity.Y):F1}\n" +
                         $"Масштаб: {scale:F6}x\n" +
                         $"Время: x{timeScale:F1}\n" +
                         $"Систем: {world.Systems.Count}";

            using (Font hudFont = new Font("Arial", 10))
            {
                g.DrawString(info, hudFont, Brushes.White, 10, 10);
            }

            if (currentSystem != null)
            {
                using (Font modeFont = new Font("Arial", 12, FontStyle.Bold))
                {
                    g.DrawString($"Система: {currentSystem.Name}", modeFont, Brushes.Yellow,
                                ClientSize.Width / 2 - 100, 10);
                }
            }

            string controls = "WASD - движение\nПробел - торможение\nZ/X - время\nT - камера\nESC - выход из системы\nE - редактор";

            if (editorMode)
            {
                controls += "\n\nРЕДАКТОР ВКЛЮЧЕН:\nЛКМ - выбрать объект\nПКМ - добавить планету\nDel - удалить объект";
            }

            using (Font controlFont = new Font("Arial", 9))
            {
                g.DrawString(controls, controlFont, Brushes.LightGray, 10, ClientSize.Height - 200);
            }
        }

        private void DrawEditorUI(Graphics g)
        {
            using (Brush editorPanel = new SolidBrush(Color.FromArgb(200, 30, 30, 40)))
            {
                g.FillRectangle(editorPanel, ClientSize.Width - 350, 50, 340, 350);
            }

            string editorInfo = "РЕДАКТОР СИСТЕМЫ\n" + editingSystem.Name + "\n\n";
            editorInfo += "Звезд: " + editingSystem.Stars.Count + "\n";
            editorInfo += "Планет: " + editingSystem.Planets.Count + "\n\n";
            editorInfo += "Выбрано: " + (selectedObjectType == 0 ? "Звезда" : "Планета") + "\n";
            editorInfo += "ЛКМ - выбрать объект\nПКМ - добавить объект\nDel - удалить выбранный";

            using (Font editorFont = new Font("Arial", 10))
            {
                g.DrawString(editorInfo, editorFont, Brushes.White, ClientSize.Width - 340, 60);
            }

            // Кнопки выбора типа
            using (Brush buttonBrush = new SolidBrush(Color.FromArgb(100, 50, 100, 200)))
            {
                g.FillRectangle(buttonBrush, ClientSize.Width - 340, 200, 150, 30);
                g.FillRectangle(buttonBrush, ClientSize.Width - 180, 200, 150, 30);
            }

            using (Font buttonFont = new Font("Arial", 10, FontStyle.Bold))
            {
                g.DrawString("Выбрать звезду", buttonFont, Brushes.White, ClientSize.Width - 335, 205);
                g.DrawString("Выбрать планету", buttonFont, Brushes.White, ClientSize.Width - 175, 205);
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyValue < 256) keysPressed[e.KeyValue] = true;

            if (e.KeyCode == Keys.Add || e.KeyCode == Keys.Oemplus) scale *= 1.2f;
            if (e.KeyCode == Keys.Subtract || e.KeyCode == Keys.OemMinus) scale *= 0.8f;
            if (e.KeyCode == Keys.Escape && currentSystem != null) ExitSystem();
            if (e.KeyCode == Keys.T) cameraFollowsPlayer = !cameraFollowsPlayer;
            if (e.KeyCode == Keys.E) ToggleEditor();

            if (scale < 0.0001f) scale = 0.0001f;
            if (scale > 2f) scale = 2f;

            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyValue < 256) keysPressed[e.KeyValue] = false;
            base.OnKeyUp(e);
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            float zoomFactor = 1.1f;
            if (e.Delta > 0) scale *= zoomFactor;
            else scale /= zoomFactor;

            if (scale < 0.0001f) scale = 0.0001f;
            if (scale > 2f) scale = 2f;

            base.OnMouseWheel(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (editorMode && editingSystem != null)
                {
                    HandleEditorLeftClick(e.Location);
                }
                else if (currentSystem != null)
                {
                    PointF worldPos = ScreenToWorld(e.Location);
                    ShowPlanetInfo(worldPos);
                }
            }
            else if (e.Button == MouseButtons.Right && editorMode && editingSystem != null)
            {
                ShowAddObjectDialog();
            }

            base.OnMouseDown(e);
        }

        private void HandleEditorLeftClick(Point location)
        {
            // Проверяем клик по кнопкам редактора
            if (location.X > ClientSize.Width - 340 && location.X < ClientSize.Width - 190 &&
                location.Y > 200 && location.Y < 230)
            {
                selectedObjectType = 0; // Выбрать звезду
                return;
            }
            else if (location.X > ClientSize.Width - 180 && location.X < ClientSize.Width - 30 &&
                     location.Y > 200 && location.Y < 230)
            {
                selectedObjectType = 1; // Выбрать планету
                return;
            }

            // Выбор объекта в системе
            PointF worldPos = ScreenToWorld(location);
            ShowObjectInfo(worldPos);
        }

        private PointF ScreenToWorld(Point screenPoint)
        {
            return new PointF(
                (screenPoint.X - ClientSize.Width / 2) / scale + cameraPos.X,
                (screenPoint.Y - ClientSize.Height / 2) / scale + cameraPos.Y
            );
        }

        private void ShowObjectInfo(PointF worldPos)
        {
            if (editingSystem == null) return;

            foreach (var star in editingSystem.Stars)
            {
                if (IsPointNearObject(worldPos, star.Position, star.Radius * 2))
                {
                    ShowStarInfo(star);
                    return;
                }
            }

            foreach (var planet in editingSystem.Planets)
            {
                if (IsPointNearObject(worldPos, planet.Position, planet.Radius * 2))
                {
                    ShowPlanetInfo(planet);
                    return;
                }
            }
        }

        private bool IsPointNearObject(PointF point, PointF objectPos, float radius)
        {
            float dx = objectPos.X - point.X;
            float dy = objectPos.Y - point.Y;
            float distance = (float)Math.Sqrt(dx * dx + dy * dy);
            return distance < radius;
        }

        private void ShowStarInfo(Star star)
        {
            string info = "🌟 " + star.Type + "\n\n" +
                         "Радиус: " + star.Radius.ToString("F0") + "\n" +
                         "Температура: " + star.Temperature + "K\n" +
                         "Цвет: " + star.Color.Name;

            MessageBox.Show(info, "Информация о звезде", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void ShowPlanetInfo(PointF worldPos)
        {
            if (currentSystem == null) return;

            Planet closestPlanet = null;
            float closestDistance = float.MaxValue;

            foreach (var planet in currentSystem.Planets)
            {
                if (IsPointNearObject(worldPos, planet.Position, planet.Radius * 2))
                {
                    float dx = planet.Position.X - worldPos.X;
                    float dy = planet.Position.Y - worldPos.Y;
                    float distance = (float)Math.Sqrt(dx * dx + dy * dy);

                    if (distance < closestDistance)
                    {
                        closestDistance = distance;
                        closestPlanet = planet;
                    }
                }
            }

            if (closestPlanet != null)
            {
                ShowPlanetInfo(closestPlanet);
            }
        }

        private void ShowPlanetInfo(Planet planet)
        {
            if (planet.CannotScan)
            {
                MessageBox.Show("👁️ ЖИВАЯ ПЛАНЕТА\n\nСканирование невозможно!\nПланета активно сопротивляется.",
                              "Сканирование заблокировано", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            string specialTraits = BuildSpecialTraits(planet);
            string message = "🪐 " + planet.Name + "\n\n" +
                           "Тип: " + planet.Type + "\n" +
                           "Диаметр: " + (planet.Radius * 2).ToString("F0") + " ед.\n" +
                           "Состав: " + planet.Composition + "\n" +
                           "Орбита: " + planet.OrbitRadius.ToString("F0") + " ед.\n" +
                           "Колонизация: " + (planet.CanBeColonized ? "Возможна" : "Невозможна") + "\n\n" +
                           (string.IsNullOrEmpty(specialTraits) ? "🚫 Особых признаков" : "✨ ОСОБЫЕ ПРИЗНАКИ:\n" + specialTraits);

            MessageBox.Show(message, "Сканирование планеты", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private string BuildSpecialTraits(Planet planet)
        {
            List traits = new List();

            if (planet.IsAcid) traits.Add("🧪 КИСЛОТНЫЙ МИР");
            if (planet.IsMeat) traits.Add("🥩 МЯСНАЯ ПЛАНЕТА");
            if (planet.IsHologram) traits.Add("👁️ ГОЛОГРАФИЧЕСКАЯ");
            if (planet.IsMilk) traits.Add("🥛 МОЛОЧНАЯ");
            if (planet.IsConstructed) traits.Add("🏗️ ПОСТРОЕННАЯ");
            if (planet.IsSteampunk) traits.Add("⚙️ СТИМПАНК (" + planet.GearCount + " шестерен)");
            if (planet.IsWater) traits.Add("💧 ВОДНЫЙ МИР");
            if (planet.IsDiamond) traits.Add("💎 АЛМАЗНАЯ");
            if (planet.IsUranium) traits.Add("☢️ УРАНОВАЯ (ур. " + planet.RadiationLevel + ")");
            if (planet.IsCity) traits.Add("🏙️ ГОРОД-ПЛАНЕТА");
            if (planet.IsAlive) traits.Add("👁️ ЖИВАЯ (" + planet.EyeCount + " глаз)");
            if (planet.HasLife) traits.Add("🌿 ОБИТАЕМАЯ");
            if (planet.HasBugs) traits.Add("🐜 " + planet.BugCount + " жуков");
            if (planet.HasRings) traits.Add("💍 ИМЕЕТ КОЛЬЦА");
            if (planet.IsMega) traits.Add("🌟 МЕГА-ПЛАНЕТА");
            if (planet.IsCitadel) traits.Add("🏰 ЦИТАДЕЛЬ");
            if (planet.IsSystemCenter) traits.Add("☀️ ЗАМЕНЯЕТ ЗВЕЗДУ");

            return string.Join("\n", traits);
        }

        private void ShowAddObjectDialog()
        {
            if (selectedObjectType == 0)
            {
                // Добавить звезду
                using (var dialog = new ObjectSelectionDialog("Выберите звезду", starTemplates.ConvertAll(x => (object)x)))
                {
                    if (dialog.ShowDialog() == DialogResult.OK && dialog.SelectedTemplate != null)
                    {
                        AddStarToSystem((StarTemplate)dialog.SelectedTemplate);
                    }
                }
            }
            else
            {
                // Добавить планету
                using (var dialog = new ObjectSelectionDialog("Выберите планету", planetTemplates.ConvertAll(x => (object)x)))
                {
                    if (dialog.ShowDialog() == DialogResult.OK && dialog.SelectedTemplate != null)
                    {
                        AddPlanetToSystem((PlanetTemplate)dialog.SelectedTemplate);
                    }
                }
            }
        }

        private void AddStarToSystem(StarTemplate template)
        {
            Star newStar = new Star();
            newStar.Position = editingSystem.Position;
            newStar.Radius = template.Radius;
            newStar.Color = template.Color;
            newStar.Type = template.Type;
            newStar.Temperature = template.Temperature;
            newStar.IsBinary = template.IsBinary;
            newStar.IsNeutron = template.IsNeutron;
            newStar.IsBlackHole = template.IsBlackHole;

            editingSystem.Stars.Add(newStar);
            Invalidate();
        }

        private void AddPlanetToSystem(PlanetTemplate template)
        {
            Random random = new Random();
            Planet newPlanet = CreatePlanetFromTemplate(editingSystem, editingSystem.Planets.Count, template, random);
            editingSystem.Planets.Add(newPlanet);
            Invalidate();
        }

        // Классы шаблонов
        public class PlanetTemplate
        {
            public string Name { get; set; }
            public string Type { get; set; }
            public Color Color { get; set; }
            public float Radius { get; set; }
            public string Composition { get; set; }
            public bool CanBeColonized { get; set; }
            public bool HasRings { get; set; }
            public bool HasAtmosphere { get; set; }
            public bool HasLife { get; set; }
            public bool HasBugs { get; set; }
            public int BugCount { get; set; }
            public int EyeCount { get; set; }
            public bool CannotScan { get; set; }
            public bool IsAcid { get; set; }
            public bool IsMeat { get; set; }
            public bool IsHologram { get; set; }
            public bool IsMilk { get; set; }
            public bool IsConstructed { get; set; }
            public bool IsSteampunk { get; set; }
            public bool IsWater { get; set; }
            public bool IsDiamond { get; set; }
            public bool IsUranium { get; set; }
            public bool IsCity { get; set; }
            public bool IsAlive { get; set; }
            public bool IsMega { get; set; }
            public bool IsCitadel { get; set; }
            public bool IsSystemCenter { get; set; }
            public int GearCount { get; set; }
            public int RadiationLevel { get; set; }
            public int SparkleIntensity { get; set; }
            public int BuildingCount { get; set; }
            public bool CityLights { get; set; }
        }

        public class StarTemplate
        {
            public string Name { get; set; }
            public string Type { get; set; }
            public Color Color { get; set; }
            public float Radius { get; set; }
            public int Temperature { get; set; }
            public bool IsBinary { get; set; }
            public bool IsNeutron { get; set; }
            public bool IsBlackHole { get; set; }
        }

        // Диалоговые окна
        private class SeedInputDialog : Form
        {
            public int Seed { get; private set; }
            private TextBox seedBox;

            public SeedInputDialog(string title)
            {
                Text = title;
                Size = new Size(300, 150);
                FormBorderStyle = FormBorderStyle.FixedDialog;
                StartPosition = FormStartPosition.CenterParent;

                Label label = new Label
                {
                    Text = title,
                    Location = new Point(10, 10),
                    Size = new Size(280, 20)
                };

                seedBox = new TextBox
                {
                    Location = new Point(10, 40),
                    Size = new Size(260, 20),
                    Text = new Random().Next().ToString()
                };

                Button okBtn = new Button
                {
                    Text = "Создать",
                    Location = new Point(10, 80),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.OK
                };

                Button cancelBtn = new Button
                {
                    Text = "Отмена",
                    Location = new Point(150, 80),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.Cancel
                };

                Controls.AddRange(new Control[] { label, seedBox, okBtn, cancelBtn });
                AcceptButton = okBtn;
                CancelButton = cancelBtn;
            }

            protected override void OnFormClosing(FormClosingEventArgs e)
            {
                if (DialogResult == DialogResult.OK && int.TryParse(seedBox.Text, out int seed))
                {
                    Seed = seed;
                }
                base.OnFormClosing(e);
            }
        }

        private class ObjectSelectionDialog : Form
        {
            public object SelectedTemplate { get; private set; }
            private ListBox listBox;
            private PictureBox previewBox;
            private List templates;

            public ObjectSelectionDialog(string title, List templateList)
            {
                templates = templateList;
                Text = title;
                Size = new Size(600, 500);
                FormBorderStyle = FormBorderStyle.FixedDialog;
                StartPosition = FormStartPosition.CenterParent;

                listBox = new ListBox
                {
                    Location = new Point(10, 10),
                    Size = new Size(250, 400)
                };

                foreach (var template in templates)
                {
                    if (template is PlanetTemplate planet)
                        listBox.Items.Add(planet.Name);
                    else if (template is StarTemplate star)
                        listBox.Items.Add(star.Name);
                }
                listBox.SelectedIndexChanged += (s, e) => UpdatePreview();

                previewBox = new PictureBox
                {
                    Location = new Point(270, 10),
                    Size = new Size(300, 300),
                    BackColor = Color.Black,
                    BorderStyle = BorderStyle.FixedSingle
                };

                Button okBtn = new Button
                {
                    Text = "Выбрать",
                    Location = new Point(10, 420),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.OK
                };

                Button cancelBtn = new Button
                {
                    Text = "Отмена",
                    Location = new Point(150, 420),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.Cancel
                };

                Controls.AddRange(new Control[] { listBox, previewBox, okBtn, cancelBtn });
                AcceptButton = okBtn;
                CancelButton = cancelBtn;

                if (listBox.Items.Count > 0) listBox.SelectedIndex = 0;
            }

            private void UpdatePreview()
            {
                if (listBox.SelectedIndex >= 0 && listBox.SelectedIndex < templates.Count)
                {
                    SelectedTemplate = templates[listBox.SelectedIndex];

                    Bitmap bmp = new Bitmap(300, 300);
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        g.Clear(Color.Black);
                        g.SmoothingMode = SmoothingMode.AntiAlias;

                        if (SelectedTemplate is PlanetTemplate planet)
                        {
                            float radius = Math.Min(100, planet.Radius * 4);
                            using (Brush planetBrush = new SolidBrush(planet.Color))
                            {
                                g.FillEllipse(planetBrush, 150 - radius, 150 - radius, radius * 2, radius * 2);
                            }

                            using (Font infoFont = new Font("Arial", 10))
                            using (Brush infoBrush = new SolidBrush(Color.White))
                            {
                                g.DrawString("Тип: " + planet.Type + "\nРадиус: " + planet.Radius + "\nСостав: " + planet.Composition,
                                           infoFont, infoBrush, 10, 10);
                            }
                        }
                        else if (SelectedTemplate is StarTemplate star)
                        {
                            float radius = Math.Min(80, star.Radius);
                            using (Brush starBrush = new SolidBrush(star.Color))
                            {
                                g.FillEllipse(starBrush, 150 - radius, 150 - radius, radius * 2, radius * 2);
                            }

                            using (Font infoFont = new Font("Arial", 10))
                            using (Brush infoBrush = new SolidBrush(Color.White))
                            {
                                g.DrawString("Тип: " + star.Type + "\nРадиус: " + star.Radius + "\nТемпература: " + star.Temperature + "K",
                                           infoFont, infoBrush, 10, 10);
                            }
                        }
                    }

                    previewBox.Image = bmp;
                }
            }

            protected override void OnFormClosing(FormClosingEventArgs e)
            {
                if (DialogResult == DialogResult.OK && listBox.SelectedIndex >= 0)
                {
                    SelectedTemplate = templates[listBox.SelectedIndex];
                }
                base.OnFormClosing(e);
            }
        }

        private class SystemCreationDialog : Form
        {
            public SolarSystem CreatedSystem { get; private set; }
            private TextBox systemNameBox;
            private ComboBox starTypeCombo;
            private List starTemplates;

            public SystemCreationDialog(List templates)
            {
                starTemplates = templates;
                Text = "Создать систему";
                Size = new Size(400, 200);
                FormBorderStyle = FormBorderStyle.FixedDialog;
                StartPosition = FormStartPosition.CenterParent;

                Label nameLabel = new Label
                {
                    Text = "Название системы:",
                    Location = new Point(10, 10),
                    Size = new Size(150, 20)
                };

                systemNameBox = new TextBox
                {
                    Location = new Point(170, 10),
                    Size = new Size(200, 20),
                    Text = "Моя система"
                };

                Label starLabel = new Label
                {
                    Text = "Тип звезды:",
                    Location = new Point(10, 40),
                    Size = new Size(150, 20)
                };

                starTypeCombo = new ComboBox
                {
                    Location = new Point(170, 40),
                    Size = new Size(200, 20),
                    DropDownStyle = ComboBoxStyle.DropDownList
                };

                foreach (var template in templates)
                {
                    starTypeCombo.Items.Add(template.Name);
                }

                if (starTypeCombo.Items.Count > 0) starTypeCombo.SelectedIndex = 0;

                Button createBtn = new Button
                {
                    Text = "Создать",
                    Location = new Point(10, 80),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.OK
                };

                Button cancelBtn = new Button
                {
                    Text = "Отмена",
                    Location = new Point(150, 80),
                    Size = new Size(120, 30),
                    DialogResult = DialogResult.Cancel
                };

                Controls.AddRange(new Control[] { nameLabel, systemNameBox, starLabel, starTypeCombo, createBtn, cancelBtn });
                AcceptButton = createBtn;
                CancelButton = cancelBtn;
            }

            protected override void OnFormClosing(FormClosingEventArgs e)
            {
                if (DialogResult == DialogResult.OK)
                {
                    CreatedSystem = new SolarSystem();
                    CreatedSystem.Name = systemNameBox.Text;

                    if (starTypeCombo.SelectedIndex >= 0 && starTypeCombo.SelectedIndex < starTemplates.Count)
                    {
                        StarTemplate template = starTemplates[starTypeCombo.SelectedIndex];
                        Star star = new Star();
                        star.Position = PointF.Empty;
                        star.Radius = template.Radius;
                        star.Color = template.Color;
                        star.Type = template.Type;
                        star.Temperature = template.Temperature;
                        star.IsBinary = template.IsBinary;
                        star.IsNeutron = template.IsNeutron;
                        star.IsBlackHole = template.IsBlackHole;
                        CreatedSystem.Stars.Add(star);
                    }
                }
                base.OnFormClosing(e);
            }
        }

        // Основные классы игры
        public class World
        {
            public List Systems { get; set; } = new List();
            public int SystemCount { get; set; } = 0;

            public void Update(float timeScale)
            {
                foreach (var system in Systems)
                {
                    system.Update(timeScale);
                }
            }

            public void Draw(Graphics g, PointF playerPos, SolarSystem currentSystem, float scale)
            {
                if (currentSystem != null)
                {
                    currentSystem.DrawDetailed(g, scale);
                }
                else
                {
                    foreach (var system in Systems)
                    {
                        system.DrawAsPoint(g, playerPos, scale);
                    }
                }
            }

            public SolarSystem GetNearestSystem(PointF pos)
            {
                SolarSystem nearest = null;
                float minDist = float.MaxValue;

                foreach (var system in Systems)
                {
                    float dx = system.Position.X - pos.X;
                    float dy = system.Position.Y - pos.Y;
                    float dist = dx * dx + dy * dy;

                    if (dist < minDist)
                    {
                        minDist = dist;
                        nearest = system;
                    }
                }

                return nearest;
            }
        }

        public class SolarSystem
        {
            public PointF Position { get; set; }
            public string Name { get; set; } = "Неизвестная система";
            public List Stars { get; set; } = new List();
            public List Planets { get; set; } = new List();
            public int ID { get; set; } = 0;

            public void Update(float timeScale)
            {
                foreach (var planet in Planets)
                {
                    planet.Update(timeScale);
                }
            }

            public void DrawAsPoint(Graphics g, PointF playerPos, float scale)
            {
                if (Stars.Count > 0)
                {
                    Star star = Stars[0];
                    float size = 3f / scale;
                    if (size < 1f) size = 1f;
                    if (size > 20f) size = 20f;

                    using (Brush brush = new SolidBrush(star.Color))
                    {
                        g.FillEllipse(brush, Position.X - size / 2, Position.Y - size / 2, size, size);
                    }
                }
            }

            public void DrawDetailed(Graphics g, float scale)
            {
                foreach (var star in Stars) star.DrawDetailed(g);
                foreach (var planet in Planets) planet.DrawDetailed(g);
            }
        }

        public class Star
        {
            public PointF Position { get; set; }
            public float Radius { get; set; }
            public Color Color { get; set; }
            public string Type { get; set; }
            public int Temperature { get; set; }
            public bool IsBinary { get; set; }
            public float BinaryRadius { get; set; }
            public Color BinaryColor { get; set; }
            public bool IsGiant { get; set; }
            public bool IsNeutron { get; set; }
            public bool IsBlackHole { get; set; }
            private float pulsePhase = 0;

            public void DrawDetailed(Graphics g)
            {
                if (IsBlackHole)
                {
                    DrawBlackHole(g);
                    return;
                }

                pulsePhase += 0.02f;
                float pulse = (float)Math.Sin(pulsePhase) * 0.1f + 1f;

                // Солнечная корона
                for (int i = 5; i > 0; i--)
                {
                    float coronaRadius = Radius * (1.2f + i * 0.1f) * pulse;
                    using (Pen coronaPen = new Pen(Color.FromArgb(30 - i * 5, Color), 1))
                    {
                        g.DrawEllipse(coronaPen,
                            Position.X - coronaRadius, Position.Y - coronaRadius,
                            coronaRadius * 2, coronaRadius * 2);
                    }
                }

                // Основная звезда
                using (PathGradientBrush starBrush = new PathGradientBrush(new PointF[]
                {
                    new PointF(Position.X - Radius, Position.Y),
                    new PointF(Position.X, Position.Y - Radius),
                    new PointF(Position.X + Radius, Position.Y),
                    new PointF(Position.X, Position.Y + Radius)
                }))
                {
                    starBrush.CenterPoint = Position;
                    starBrush.CenterColor = IsNeutron ? Color.White : Color.White;
                    starBrush.SurroundColors = new Color[] { Color, Color, Color, Color };

                    g.FillEllipse(starBrush,
                        Position.X - Radius, Position.Y - Radius,
                        Radius * 2, Radius * 2);
                }

                // Нейтронная звезда - пульсар
                if (IsNeutron)
                {
                    DrawPulsarBeam(g, pulsePhase);
                }

                // Двойная система
                if (IsBinary)
                {
                    using (Brush binaryBrush = new SolidBrush(BinaryColor))
                    {
                        g.FillEllipse(binaryBrush,
                            Position.X + Radius * 1.5f - BinaryRadius,
                            Position.Y + Radius * 1.5f - BinaryRadius,
                            BinaryRadius * 2, BinaryRadius * 2);
                    }
                }

                // Солнечные протуберанцы для гигантов
                if (IsGiant)
                {
                    Random rnd = new Random((int)Position.X + (int)Position.Y);
                    for (int i = 0; i < 12; i++)
                    {
                        float angle = (float)(rnd.NextDouble() * Math.PI * 2);
                        float length = Radius * (0.8f + (float)rnd.NextDouble() * 0.8f);
                        float width = Radius * 0.15f;

                        PointF start = new PointF(
                            Position.X + (float)Math.Cos(angle) * Radius,
                            Position.Y + (float)Math.Sin(angle) * Radius
                        );

                        PointF end = new PointF(
                            start.X + (float)Math.Cos(angle) * length,
                            start.Y + (float)Math.Sin(angle) * length
                        );

                        using (Pen prominencePen = new Pen(Color.FromArgb(150, Color.Red), width))
                        {
                            prominencePen.StartCap = LineCap.Round;
                            prominencePen.EndCap = LineCap.Round;
                            g.DrawLine(prominencePen, start, end);
                        }
                    }
                }
            }

            private void DrawBlackHole(Graphics g)
            {
                // Горизонт событий
                using (Brush blackHoleBrush = new SolidBrush(Color.Black))
                {
                    g.FillEllipse(blackHoleBrush,
                        Position.X - Radius, Position.Y - Radius,
                        Radius * 2, Radius * 2);
                }

                // Аккреционный диск
                for (int i = 0; i < 3; i++)
                {
                    float discRadius = Radius * (1.5f + i * 0.3f);
                    using (Pen discPen = new Pen(Color.FromArgb(100 - i * 20, 255, 100, 0), 2))
                    {
                        g.DrawEllipse(discPen,
                            Position.X - discRadius, Position.Y - discRadius,
                            discRadius * 2, discRadius * 2);
                    }
                }

                // Гравитационное линзирование
                using (Pen lensingPen = new Pen(Color.FromArgb(50, 200, 200, 255), 1))
                {
                    for (int i = 0; i < 8; i++)
                    {
                        float angle = i * (float)Math.PI / 4;
                        float length = Radius * 2;

                        PointF start = new PointF(
                            Position.X + (float)Math.Cos(angle) * Radius * 0.8f,
                            Position.Y + (float)Math.Sin(angle) * Radius * 0.8f
                        );

                        PointF end = new PointF(
                            start.X + (float)Math.Cos(angle) * length,
                            start.Y + (float)Math.Sin(angle) * length
                        );

                        g.DrawLine(lensingPen, start, end);
                    }
                }
            }

            private void DrawPulsarBeam(Graphics g, float phase)
            {
                for (int i = 0; i < 4; i++)
                {
                    float angle = phase * 2 + i * (float)Math.PI / 2;
                    float length = Radius * 8;
                    float width = Radius * 0.3f;

                    PointF start = new PointF(Position.X, Position.Y);
                    PointF end = new PointF(
                        start.X + (float)Math.Cos(angle) * length,
                        start.Y + (float)Math.Sin(angle) * length
                    );

                    using (Pen beamPen = new Pen(Color.FromArgb(100, 0, 200, 255), width))
                    {
                        g.DrawLine(beamPen, start, end);
                    }
                }
            }
        }

        public class Planet
        {
            public string Name { get; set; } = "Планета";
            public PointF Position { get; set; }
            public float Radius { get; set; }
            public Color Color { get; set; }
            public string Type { get; set; }
            public string Composition { get; set; }
            public bool CanBeColonized { get; set; }
            public PointF OrbitCenter { get; set; }
            public float OrbitRadius { get; set; }
            public float OrbitSpeed { get; set; }
            public float SpinAngle { get; set; }
            public float SpinSpeed { get; set; }
            public bool HasRings { get; set; }
            public float RingInner { get; set; }
            public float RingOuter { get; set; }
            public Color RingColor { get; set; }
            public bool HasAtmosphere { get; set; }
            public bool HasLife { get; set; }
            public bool HasBugs { get; set; }
            public int BugCount { get; set; }
            public int EyeCount { get; set; }
            public bool CannotScan { get; set; }
            public bool IsAcid { get; set; }
            public bool IsMeat { get; set; }
            public bool IsHologram { get; set; }
            public bool IsMilk { get; set; }
            public bool IsConstructed { get; set; }
            public bool IsSteampunk { get; set; }
            public bool IsWater { get; set; }
            public bool IsDiamond { get; set; }
            public bool IsUranium { get; set; }
            public bool IsCity { get; set; }
            public bool IsAlive { get; set; }
            public bool IsMega { get; set; }
            public bool IsCitadel { get; set; }
            public bool IsSystemCenter { get; set; }
            public int GearCount { get; set; }
            public int RadiationLevel { get; set; }
            public int SparkleIntensity { get; set; }
            public int BuildingCount { get; set; }
            public bool CityLights { get; set; }

            private float orbitAngle = 0;
            private float cloudOffset = 0;
            private float effectPhase = 0;
            private Random localRnd = new Random();

            public void Update(float timeScale)
            {
                orbitAngle += OrbitSpeed * timeScale;
                SpinAngle += SpinSpeed * timeScale;
                cloudOffset += 0.01f * timeScale;
                effectPhase += 0.02f * timeScale;

                Position = new PointF(
                    OrbitCenter.X + (float)Math.Cos(orbitAngle) * OrbitRadius,
                    OrbitCenter.Y + (float)Math.Sin(orbitAngle) * OrbitRadius
                );
            }

            public void DrawDetailed(Graphics g)
            {
                // Орбита
                using (Pen orbitPen = new Pen(Color.FromArgb(30, 100, 100, 100), 1))
                {
                    g.DrawEllipse(orbitPen,
                        OrbitCenter.X - OrbitRadius, OrbitCenter.Y - OrbitRadius,
                        OrbitRadius * 2, OrbitRadius * 2);
                }

                // Кольца
                if (HasRings)
                {
                    using (Pen ringPen = new Pen(Color.FromArgb(150, RingColor), 1))
                    {
                        g.DrawEllipse(ringPen,
                            Position.X - RingOuter, Position.Y - RingOuter,
                            RingOuter * 2, RingOuter * 2);
                    }
                }

                // Планета с вращением
                GraphicsState state = g.Save();
                g.TranslateTransform(Position.X, Position.Y);
                g.RotateTransform(SpinAngle * 180f / (float)Math.PI);

                // Основная планета
                using (Brush planetBrush = new SolidBrush(Color))
                {
                    g.FillEllipse(planetBrush, -Radius, -Radius, Radius * 2, Radius * 2);
                }

                // Специальные эффекты в зависимости от типа
                if (IsAcid) DrawAcidEffects(g);
                if (IsMeat) DrawMeatEffects(g);
                if (IsHologram) DrawHologramEffects(g);
                if (IsMilk) DrawMilkEffects(g);
                if (IsConstructed) DrawConstructedEffects(g);
                if (IsSteampunk) DrawSteampunkEffects(g);
                if (IsWater) DrawWaterEffects(g);
                if (IsDiamond) DrawDiamondEffects(g);
                if (IsUranium) DrawUraniumEffects(g);
                if (IsCity) DrawCityEffects(g);
                if (IsAlive) DrawAliveEffects(g);
                if (IsMega) DrawMegaEffects(g);
                if (IsCitadel) DrawCitadelEffects(g);
                if (Type == "Землеподобная" || Type == "Газовый гигант" || HasAtmosphere)
                {
                    DrawAtmosphere(g);
                }

                g.Restore(state);
            }

            private void DrawAtmosphere(Graphics g)
            {
                using (Brush atmosphereBrush = new SolidBrush(Color.FromArgb(50, 200, 220, 255)))
                {
                    g.FillEllipse(atmosphereBrush,
                        -Radius * 1.1f, -Radius * 1.1f,
                        Radius * 2.2f, Radius * 2.2f);
                }

                // Облака
                Random rnd = new Random((int)(Position.X + Position.Y));
                for (int i = 0; i < 5; i++)
                {
                    float cloudAngle = cloudOffset + i * (float)Math.PI * 0.4f;
                    float cloudRadius = Radius * 0.9f;
                    float cloudSize = Radius * 0.2f;

                    using (Brush cloudBrush = new SolidBrush(Color.FromArgb(100, 255, 255, 255)))
                    {
                        g.FillEllipse(cloudBrush,
                            (float)Math.Cos(cloudAngle) * cloudRadius - cloudSize / 2,
                            (float)Math.Sin(cloudAngle) * cloudRadius - cloudSize / 2,
                            cloudSize, cloudSize * 0.7f);
                    }
                }
            }

            private void DrawAcidEffects(Graphics g)
            {
                using (Pen acidPen = new Pen(Color.Lime, 2))
                {
                    g.DrawEllipse(acidPen, -Radius * 1.2f, -Radius * 1.2f, Radius * 2.4f, Radius * 2.4f);
                }

                // Кислотные озера
                for (int i = 0; i < 3; i++)
                {
                    float lakeAngle = i * (float)Math.PI * 1.5f;
                    float lakeRadius = Radius * 0.3f;
                    using (Brush lakeBrush = new SolidBrush(Color.FromArgb(200, 0, 255, 0)))
                    {
                        g.FillEllipse(lakeBrush,
                            (float)Math.Cos(lakeAngle) * Radius * 0.5f - lakeRadius / 2,
                            (float)Math.Sin(lakeAngle) * Radius * 0.5f - lakeRadius / 2,
                            lakeRadius, lakeRadius);
                    }
                }
            }

            private void DrawMeatEffects(Graphics g)
            {
                // Мясные прожилки
                for (int i = 0; i < 8; i++)
                {
                    float angle = i * (float)Math.PI / 4;
                    using (Pen veinPen = new Pen(Color.DarkRed, Radius * 0.05f))
                    {
                        float x1 = (float)Math.Cos(angle) * Radius * 0.3f;
                        float y1 = (float)Math.Sin(angle) * Radius * 0.3f;
                        float x2 = (float)Math.Cos(angle + 0.5f) * Radius * 0.7f;
                        float y2 = (float)Math.Sin(angle + 0.5f) * Radius * 0.7f;

                        g.DrawLine(veinPen, x1, y1, x2, y2);
                    }
                }

                // Жуки
                for (int i = 0; i < Math.Min(BugCount, 20); i++)
                {
                    float angle = (float)(localRnd.NextDouble() * Math.PI * 2);
                    float distance = Radius * 0.8f * (float)localRnd.NextDouble();
                    float bugSize = Radius * 0.05f;

                    float x = (float)Math.Cos(angle) * distance;
                    float y = (float)Math.Sin(angle) * distance;

                    using (Brush bugBrush = new SolidBrush(Color.Black))
                    {
                        g.FillEllipse(bugBrush, x - bugSize / 2, y - bugSize / 2, bugSize, bugSize);
                    }
                }
            }

            private void DrawHologramEffects(Graphics g)
            {
                using (Brush hologramBrush = new SolidBrush(Color.FromArgb(100, 0, 255, 255)))
                {
                    g.FillEllipse(hologramBrush, -Radius, -Radius, Radius * 2, Radius * 2);
                }

                // Голографические линии
                for (int i = 0; i < 12; i++)
                {
                    float angle = i * (float)Math.PI / 6;
                    using (Pen holoPen = new Pen(Color.FromArgb(150, 0, 255, 255), 1))
                    {
                        g.DrawLine(holoPen,
                            (float)Math.Cos(angle) * Radius * 0.2f,
                            (float)Math.Sin(angle) * Radius * 0.2f,
                            (float)Math.Cos(angle) * Radius * 0.9f,
                            (float)Math.Sin(angle) * Radius * 0.9f);
                    }
                }
            }

            private void DrawMilkEffects(Graphics g)
            {
                // Молочные реки
                for (int i = 0; i < 4; i++)
                {
                    float angle = i * (float)Math.PI / 2;
                    using (Pen milkRiverPen = new Pen(Color.White, Radius * 0.1f))
                    {
                        g.DrawLine(milkRiverPen,
                            (float)Math.Cos(angle) * Radius * 0.4f,
                            (float)Math.Sin(angle) * Radius * 0.4f,
                            (float)Math.Cos(angle + 0.5f) * Radius * 0.8f,
                            (float)Math.Sin(angle + 0.5f) * Radius * 0.8f);
                    }
                }
            }

            private void DrawConstructedEffects(Graphics g)
            {
                // Металлические панели
                for (int i = 0; i < 8; i++)
                {
                    float angle = i * (float)Math.PI / 4;
                    using (Pen panelPen = new Pen(Color.DarkGray, 2))
                    {
                        g.DrawLine(panelPen,
                            (float)Math.Cos(angle) * Radius * 0.3f,
                            (float)Math.Sin(angle) * Radius * 0.3f,
                            (float)Math.Cos(angle) * Radius * 0.9f,
                            (float)Math.Sin(angle) * Radius * 0.9f);
                    }
                }
            }

            private void DrawSteampunkEffects(Graphics g)
            {
                // Шестерёнки
                for (int i = 0; i < GearCount; i++)
                {
                    float angle = i * (float)Math.PI * 2 / GearCount;
                    float gearRadius = Radius * 0.15f;
                    float x = (float)Math.Cos(angle) * Radius * 0.6f;
                    float y = (float)Math.Sin(angle) * Radius * 0.6f;

                    using (Pen gearPen = new Pen(Color.Brown, 1))
                    {
                        g.DrawEllipse(gearPen, x - gearRadius, y - gearRadius, gearRadius * 2, gearRadius * 2);
                    }
                }

                // Трубы и пар
                for (int i = 0; i < 4; i++)
                {
                    float angle = i * (float)Math.PI / 2;
                    using (Pen pipePen = new Pen(Color.Gray, Radius * 0.05f))
                    {
                        g.DrawLine(pipePen,
                            (float)Math.Cos(angle) * Radius * 0.5f,
                            (float)Math.Sin(angle) * Radius * 0.5f,
                            (float)Math.Cos(angle + 0.3f) * Radius * 0.8f,
                            (float)Math.Sin(angle + 0.3f) * Radius * 0.8f);
                    }
                }
            }

            private void DrawWaterEffects(Graphics g)
            {
                // Волны
                using (Pen wavePen = new Pen(Color.FromArgb(150, 0, 100, 255), 1))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        float waveRadius = Radius * (0.7f + i * 0.1f);
                        g.DrawEllipse(wavePen, -waveRadius, -waveRadius, waveRadius * 2, waveRadius * 2);
                    }
                }

                // Острова
                for (int i = 0; i < 5; i++)
                {
                    float angle = i * (float)Math.PI * 0.4f;
                    float islandSize = Radius * 0.1f;
                    using (Brush islandBrush = new SolidBrush(Color.DarkGreen))
                    {
                        g.FillEllipse(islandBrush,
                            (float)Math.Cos(angle) * Radius * 0.7f - islandSize / 2,
                            (float)Math.Sin(angle) * Radius * 0.7f - islandSize / 2,
                            islandSize, islandSize);
                    }
                }
            }

            private void DrawDiamondEffects(Graphics g)
            {
                // Блики
                for (int i = 0; i < SparkleIntensity; i++)
                {
                    float angle = (float)(localRnd.NextDouble() * Math.PI * 2);
                    float distance = Radius * 0.7f * (float)localRnd.NextDouble();
                    float sparkleSize = Radius * 0.05f;

                    float x = (float)Math.Cos(angle) * distance;
                    float y = (float)Math.Sin(angle) * distance;

                    using (Brush sparkleBrush = new SolidBrush(Color.White))
                    {
                        g.FillEllipse(sparkleBrush, x - sparkleSize / 2, y - sparkleSize / 2, sparkleSize, sparkleSize);
                    }
                }
            }

            private void DrawUraniumEffects(Graphics g)
            {
                // Радиационное свечение
                for (int i = 0; i < RadiationLevel; i++)
                {
                    using (Pen radiationPen = new Pen(Color.FromArgb(50 - i * 5, Color.Lime), 1))
                    {
                        float radRadius = Radius * (1.1f + i * 0.05f);
                        g.DrawEllipse(radiationPen, -radRadius, -radRadius, radRadius * 2, radRadius * 2);
                    }
                }

                // Радиоактивные руды
                for (int i = 0; i < 6; i++)
                {
                    float angle = i * (float)Math.PI / 3;
                    float oreSize = Radius * 0.08f;
                    using (Brush oreBrush = new SolidBrush(Color.GreenYellow))
                    {
                        g.FillEllipse(oreBrush,
                            (float)Math.Cos(angle) * Radius * 0.6f - oreSize / 2,
                            (float)Math.Sin(angle) * Radius * 0.6f - oreSize / 2,
                            oreSize, oreSize);
                    }
                }
            }

            private void DrawCityEffects(Graphics g)
            {
                if (CityLights)
                {
                    for (int i = 0; i < Math.Min(BuildingCount, 30); i++)
                    {
                        float angle = (float)(localRnd.NextDouble() * Math.PI * 2);
                        float distance = Radius * 0.8f * (float)localRnd.NextDouble();
                        float lightSize = Radius * 0.03f;

                        float x = (float)Math.Cos(angle) * distance;
                        float y = (float)Math.Sin(angle) * distance;

                        Color lightColor = localRnd.Next(3) == 0 ? Color.White :
                                         localRnd.Next(2) == 0 ? Color.Yellow : Color.Orange;

                        using (Brush lightBrush = new SolidBrush(lightColor))
                        {
                            g.FillEllipse(lightBrush, x - lightSize / 2, y - lightSize / 2, lightSize, lightSize);
                        }
                    }
                }
            }

            private void DrawAliveEffects(Graphics g)
            {
                // Глаза
                for (int i = 0; i < EyeCount; i++)
                {
                    float angle = i * (float)Math.PI * 2 / EyeCount;
                    float eyeSize = Radius * 0.1f;
                    float x = (float)Math.Cos(angle) * Radius * 0.7f;
                    float y = (float)Math.Sin(angle) * Radius * 0.7f;

                    using (Brush eyeBrush = new SolidBrush(Color.White))
                    {
                        g.FillEllipse(eyeBrush, x - eyeSize, y - eyeSize, eyeSize * 2, eyeSize * 2);
                    }
                    using (Brush pupilBrush = new SolidBrush(Color.Black))
                    {
                        g.FillEllipse(pupilBrush, x - eyeSize * 0.3f, y - eyeSize * 0.3f, eyeSize * 0.6f, eyeSize * 0.6f);
                    }
                }

                // Пульсация живой планеты
                float pulse = (float)Math.Sin(effectPhase) * 0.05f + 1f;
                using (Pen pulsePen = new Pen(Color.FromArgb(100, 255, 100, 100), 1))
                {
                    g.DrawEllipse(pulsePen, -Radius * pulse, -Radius * pulse, Radius * 2 * pulse, Radius * 2 * pulse);
                }
            }

            private void DrawMegaEffects(Graphics g)
            {
                // Большой размер уже установлен
                // Добавляем дополнительные детали
                using (Pen megaRingPen = new Pen(Color.FromArgb(150, 255, 255, 100), 2))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        float megaRadius = Radius * (1.2f + i * 0.1f);
                        g.DrawEllipse(megaRingPen, -megaRadius, -megaRadius, megaRadius * 2, megaRadius * 2);
                    }
                }
            }

            private void DrawCitadelEffects(Graphics g)
            {
                // Башни цитадели
                for (int i = 0; i < 6; i++)
                {
                    float angle = i * (float)Math.PI / 3;
                    float towerHeight = Radius * 0.4f;
                    float towerWidth = Radius * 0.08f;

                    using (Brush towerBrush = new SolidBrush(Color.Silver))
                    {
                        g.FillRectangle(towerBrush,
                            (float)Math.Cos(angle) * Radius * 0.9f - towerWidth / 2,
                            (float)Math.Sin(angle) * Radius * 0.9f - towerHeight / 2,
                            towerWidth, towerHeight);
                    }
                }
            }
        }

        public class PlayerShip
        {
            public PointF Position { get; set; }
            public PointF Velocity { get; set; }
            public float Rotation { get; set; }

            public PlayerShip()
            {
                Position = new PointF(0, 0);
                Velocity = new PointF(0, 0);
                Rotation = 0;
            }

            public void ThrustForward(float power)
            {
                Velocity = new PointF(
                    Velocity.X + (float)Math.Cos(Rotation) * power,
                    Velocity.Y + (float)Math.Sin(Rotation) * power
                );
            }

            public void Update(float timeScale)
            {
                Position = new PointF(Position.X + Velocity.X * timeScale, Position.Y + Velocity.Y * timeScale);
                Velocity = new PointF(Velocity.X * 0.99f, Velocity.Y * 0.99f);
            }

            public void Draw(Graphics g)
            {
                float shipSize = 15f;
                PointF[] ship = new PointF[]
                {
                    new PointF(Position.X + shipSize, Position.Y),
                    new PointF(Position.X - shipSize/2, Position.Y + shipSize/2),
                    new PointF(Position.X - shipSize/2, Position.Y - shipSize/2)
                };

                GraphicsState state = g.Save();
                g.TranslateTransform(Position.X, Position.Y);
                g.RotateTransform(Rotation * 180f / (float)Math.PI);
                g.TranslateTransform(-Position.X, -Position.Y);

                using (Brush shipBrush = new SolidBrush(Color.White))
                using (Pen shipPen = new Pen(Color.Red, 2))
                {
                    g.FillPolygon(shipBrush, ship);
                    g.DrawPolygon(shipPen, ship);
                }

                // Огонь двигателя
                if (Velocity.X != 0 || Velocity.Y != 0)
                {
                    PointF engine = new PointF(Position.X - 10, Position.Y);
                    PointF[] flame = new PointF[]
                    {
                        new PointF(engine.X - 8, engine.Y),
                        new PointF(engine.X - 4, engine.Y + 3),
                        new PointF(engine.X - 12, engine.Y),
                        new PointF(engine.X - 4, engine.Y - 3)
                    };

                    using (Brush flameBrush = new SolidBrush(Color.Orange))
                    {
                        g.FillPolygon(flameBrush, flame);
                    }
                }

                g.Restore(state);
            }
        }

        public class SuperShip
        {
            public PointF Position { get; set; }
            public PointF Velocity { get; set; }
            public float Rotation { get; set; }
            public Color Color { get; set; }
            public float Size { get; set; }
            private Random rnd;
            private float moveTimer = 0;

            public SuperShip(Random random)
            {
                rnd = random;
                Position = new PointF(
                    rnd.Next(-20000, 20000),
                    rnd.Next(-20000, 20000)
                );
                Velocity = new PointF(
                    (float)(rnd.NextDouble() * 2 - 1),
                    (float)(rnd.NextDouble() * 2 - 1)
                );
                Rotation = (float)(rnd.NextDouble() * Math.PI * 2);
                Size = rnd.Next(20, 50);
                Color = Color.FromArgb(
                    rnd.Next(200, 256),
                    rnd.Next(200, 256),
                    rnd.Next(200, 256)
                );
            }

            public void Update()
            {
                Position = new PointF(Position.X + Velocity.X, Position.Y + Velocity.Y);
                Rotation += 0.01f;

                moveTimer += 0.016f;
                if (moveTimer > 5)
                {
                    moveTimer = 0;
                    Velocity = new PointF(
                        (float)(rnd.NextDouble() * 2 - 1),
                        (float)(rnd.NextDouble() * 2 - 1)
                    );
                }
            }

            public void Draw(Graphics g, float scale)
            {
                // Рисуем только если достаточно близко
                if (scale > 0.0002f)
                {
                    float drawSize = Size / scale;
                    if (drawSize < 1) drawSize = 1;
                    if (drawSize > 100) drawSize = 100;

                    GraphicsState state = g.Save();
                    g.TranslateTransform(Position.X, Position.Y);
                    g.RotateTransform(Rotation * 180f / (float)Math.PI);

                    using (Brush shipBrush = new SolidBrush(Color))
                    using (Pen shipPen = new Pen(Color.White, 1))
                    {
                        g.FillEllipse(shipBrush, -drawSize / 2, -drawSize / 2, drawSize, drawSize);
                        g.DrawEllipse(shipPen, -drawSize / 2, -drawSize / 2, drawSize, drawSize);
                    }

                    g.Restore(state);
                }
            }
        }

        public class StarParticle
        {
            public PointF Position { get; set; }
            public float Size { get; set; }
            public float Brightness { get; set; }

            public StarParticle(Size screenSize, Random rnd)
            {
                Position = new PointF(
                    rnd.Next(-screenSize.Width * 20, screenSize.Width * 20),
                    rnd.Next(-screenSize.Height * 20, screenSize.Height * 20)
                );
                Size = rnd.Next(1, 3);
                Brightness = rnd.Next(100, 200);
            }

            public void Update()
            {
                Brightness = 100 + (float)(Math.Sin(Environment.TickCount * 0.001 + Position.X) * 50);
            }

            public void Draw(Graphics g, PointF cameraPos, float scale)
            {
                float drawX = Position.X - cameraPos.X;
                float drawY = Position.Y - cameraPos.Y;

                float drawSize = Size / scale;
                if (drawSize < 0.3f) drawSize = 0.3f;
                if (drawSize > 5f) drawSize = 5f;

                using (Brush starBrush = new SolidBrush(Color.FromArgb((int)Brightness, 255, 255, 255)))
                {
                    g.FillEllipse(starBrush, drawX - drawSize / 2, drawY - drawSize / 2, drawSize, drawSize);
                }
            }
        }
    }
}

    
    
    

Form3.Designer.cs

namespace MenuTOD
{
    partial class Form3
    {
        /// 
        /// Required designer variable.
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// Clean up any resources being used.
        /// 
        /// true if managed resources should be disposed; otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// 
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// 
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Text = "Form3";
        }

        #endregion
    }
}

    

Form4.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static FForumF.MainForm;

namespace FForumF
{
    public partial class MainForm : Form
    {
        // Лого
        private Label logoLabel;
        private System.Windows.Forms.Timer logoTimer;
        private int logoCounter = 0;
        private Random rnd = new Random();

        // Сервер
        private TcpListener server;
        private Thread serverThread;
        private bool isRunning = false;
        private int port = 8888;
        private List clients = new List();
        private string encryptionKey = "FFORUMF-SECURE-KEY-2024";

        // Данные
        private List topics = new List();
        private ListBox topicsList;
        private TextBox topicTitleBox;
        private TextBox topicAuthorBox;
        private RichTextBox topicContentBox;
        private ListBox logListBox;
        private Label ipLabel;
        private bool showIP = true;

        // Добавленные форматы файлов
        private List supportedFormats = new List
        {
            ".mp3", ".mp4", ".wav", ".avi", ".mov",
            ".png", ".jpg", ".jpeg", ".bmp", ".gif", ".svg", ".webp",
            ".txt", ".pdf", ".doc", ".docx", ".zip", ".rar"
        };

        public class ForumTopic
        {
            public string Id { get; set; }
            public string Title { get; set; }
            public string Author { get; set; }
            public string Content { get; set; }
            public DateTime Created { get; set; }
            public List Messages { get; set; } = new List();
        }

        public class ForumMessage
        {
            public string Id { get; set; }
            public string Author { get; set; }
            public string Text { get; set; }
            public DateTime Time { get; set; }
        }

        public MainForm()
        {
            InitializeForm();
            StartLogoAnimation();
            CreateSampleTopics();
        }

        private void InitializeForm()
        {
            this.Text = "FForumF - Secure P2P Forum";
            this.Size = new Size(1200, 800);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.BackColor = Color.FromArgb(10, 10, 10);
            this.FormClosing += MainForm_FormClosing;

            // Логотип
            Panel logoPanel = new Panel();
            logoPanel.Dock = DockStyle.Top;
            logoPanel.Height = 70;
            logoPanel.BackColor = Color.Black;

            logoLabel = new Label();
            logoLabel.Dock = DockStyle.Fill;
            logoLabel.Font = new Font("Consolas", 24, FontStyle.Bold);
            logoLabel.ForeColor = Color.Lime;
            logoLabel.TextAlign = ContentAlignment.MiddleCenter;
            logoLabel.Text = "FFORUMF ENCRYPTED";

            logoPanel.Controls.Add(logoLabel);

            // Основные вкладки
            TabControl mainTabs = new TabControl();
            mainTabs.Dock = DockStyle.Fill;
            mainTabs.Font = new Font("Consolas", 9);

            mainTabs.TabPages.Add(CreateHostTab());
            mainTabs.TabPages.Add(CreateTopicsTab());
            mainTabs.TabPages.Add(CreateCreateTab());
            mainTabs.TabPages.Add(CreateLogsTab());

            this.Controls.Add(mainTabs);
            this.Controls.Add(logoPanel);
        }

        private TabPage CreateHostTab()
        {
            TabPage tab = new TabPage("Хостинг");
            tab.BackColor = Color.FromArgb(20, 20, 20);

            // Статус
            Panel statusPanel = new Panel();
            statusPanel.Size = new Size(1150, 150);
            statusPanel.Location = new Point(20, 20);
            statusPanel.BackColor = Color.FromArgb(30, 30, 30);
            statusPanel.BorderStyle = BorderStyle.FixedSingle;

            Label statusLabel = new Label();
            statusLabel.Text = "СЕРВЕР ОФФЛАЙН";
            statusLabel.Font = new Font("Consolas", 16, FontStyle.Bold);
            statusLabel.ForeColor = Color.Red;
            statusLabel.Location = new Point(20, 20);

            ipLabel = new Label();
            ipLabel.Text = "IP: Нажмите 'Показать IP'";
            ipLabel.Font = new Font("Consolas", 12);
            ipLabel.ForeColor = Color.Cyan;
            ipLabel.Location = new Point(20, 60);
            ipLabel.Size = new Size(800, 25);

            Label clientsLabel = new Label();
            clientsLabel.Text = "Клиентов: 0";
            clientsLabel.Font = new Font("Consolas", 12);
            clientsLabel.ForeColor = Color.Yellow;
            clientsLabel.Location = new Point(20, 100);

            // Кнопка показа/скрытия IP
            Button toggleIPBtn = new Button();
            toggleIPBtn.Text = "Показать IP";
            toggleIPBtn.Font = new Font("Consolas", 10);
            toggleIPBtn.Size = new Size(150, 30);
            toggleIPBtn.Location = new Point(850, 55);
            toggleIPBtn.BackColor = Color.FromArgb(60, 60, 120);
            toggleIPBtn.ForeColor = Color.White;
            toggleIPBtn.Click += (s, e) => ToggleIPVisibility(toggleIPBtn);

            Button copyIPBtn = new Button();
            copyIPBtn.Text = "Копировать IP";
            copyIPBtn.Font = new Font("Consolas", 10);
            copyIPBtn.Size = new Size(150, 30);
            copyIPBtn.Location = new Point(850, 95);
            copyIPBtn.BackColor = Color.FromArgb(0, 80, 120);
            copyIPBtn.ForeColor = Color.White;
            copyIPBtn.Click += CopyIPToClipboard;

            statusPanel.Controls.Add(statusLabel);
            statusPanel.Controls.Add(ipLabel);
            statusPanel.Controls.Add(clientsLabel);
            statusPanel.Controls.Add(toggleIPBtn);
            statusPanel.Controls.Add(copyIPBtn);

            // Кнопки управления
            Button startBtn = new Button();
            startBtn.Text = "ЗАПУСТИТЬ ХОСТ";
            startBtn.Font = new Font("Consolas", 12, FontStyle.Bold);
            startBtn.Size = new Size(300, 50);
            startBtn.Location = new Point(20, 190);
            startBtn.BackColor = Color.FromArgb(0, 100, 0);
            startBtn.ForeColor = Color.White;
            startBtn.Click += (s, e) => StartServer(statusLabel, ipLabel, clientsLabel, startBtn);

            Button stopBtn = new Button();
            stopBtn.Text = "ОСТАНОВИТЬ";
            stopBtn.Font = new Font("Consolas", 12, FontStyle.Bold);
            stopBtn.Size = new Size(300, 50);
            stopBtn.Location = new Point(350, 190);
            stopBtn.BackColor = Color.FromArgb(100, 0, 0);
            stopBtn.ForeColor = Color.White;
            stopBtn.Click += (s, e) => StopServer(statusLabel, ipLabel, clientsLabel, startBtn);

            Button backupBtn = new Button();
            backupBtn.Text = "СОХРАНИТЬ БЭКАП";
            backupBtn.Font = new Font("Consolas", 12, FontStyle.Bold);
            backupBtn.Size = new Size(300, 50);
            backupBtn.Location = new Point(680, 190);
            backupBtn.BackColor = Color.FromArgb(0, 60, 120);
            backupBtn.ForeColor = Color.White;
            backupBtn.Click += CreateBackup;

            // Информация о порте
            Panel portPanel = new Panel();
            portPanel.Size = new Size(1150, 100);
            portPanel.Location = new Point(20, 260);
            portPanel.BackColor = Color.FromArgb(40, 40, 40);
            portPanel.BorderStyle = BorderStyle.FixedSingle;

            Label portLabel = new Label();
            portLabel.Text = $"Порт: {port}";
            portLabel.Font = new Font("Consolas", 14, FontStyle.Bold);
            portLabel.ForeColor = Color.White;
            portLabel.Location = new Point(20, 20);

            Button changePortBtn = new Button();
            changePortBtn.Text = "Изменить порт";
            changePortBtn.Size = new Size(200, 30);
            changePortBtn.Location = new Point(20, 60);
            changePortBtn.Click += ChangePort;

            portPanel.Controls.Add(portLabel);
            portPanel.Controls.Add(changePortBtn);

            // Инструкция
            RichTextBox infoBox = new RichTextBox();
            infoBox.Size = new Size(1150, 200);
            infoBox.Location = new Point(20, 380);
            infoBox.BackColor = Color.Black;
            infoBox.ForeColor = Color.Lime;
            infoBox.Font = new Font("Consolas", 9);
            infoBox.Text = "ЗАЩИЩЕННЫЙ P2P ФОРУМ\n";
            infoBox.Text += "=================================\n";
            infoBox.Text += "• Сообщения шифруются только в файлах\n";
            infoBox.Text += "• Поддержка многих форматов файлов\n";
            infoBox.Text += "• Бэкап в .ffor формате\n";
            infoBox.Text += "• Защита от взлома\n";
            infoBox.Text += "• Приватность: скрытие IP\n";
            infoBox.Text += "=================================\n";
            infoBox.Text += "Форматы: MP3, MP4, PNG, JPG, GIF, SVG, WEBP,\n";
            infoBox.Text += "TXT, PDF, DOC, ZIP, RAR и другие\n";

            tab.Controls.Add(statusPanel);
            tab.Controls.Add(startBtn);
            tab.Controls.Add(stopBtn);
            tab.Controls.Add(backupBtn);
            tab.Controls.Add(portPanel);
            tab.Controls.Add(infoBox);

            return tab;
        }

        private TabPage CreateTopicsTab()
        {
            TabPage tab = new TabPage("Темы");
            tab.BackColor = Color.FromArgb(20, 20, 20);

            topicsList = new ListBox();
            topicsList.Size = new Size(800, 500);
            topicsList.Location = new Point(20, 20);
            topicsList.BackColor = Color.Black;
            topicsList.ForeColor = Color.Lime;
            topicsList.Font = new Font("Consolas", 10);
            topicsList.DisplayMember = "Title";

            // Статистика
            Label statsLabel = new Label();
            statsLabel.Text = "Тем: 0 | Сообщений: 0";
            statsLabel.ForeColor = Color.Cyan;
            statsLabel.Location = new Point(20, 530);
            statsLabel.Size = new Size(300, 25);

            // Кнопки управления темами
            Panel buttonPanel = new Panel();
            buttonPanel.Size = new Size(300, 500);
            buttonPanel.Location = new Point(840, 20);
            buttonPanel.BackColor = Color.FromArgb(30, 30, 30);

            Button viewBtn = CreateTopicButton("ПРОСМОТРЕТЬ", 20, ViewTopic);
            Button replyBtn = CreateTopicButton("ОТВЕТИТЬ", 80, ReplyToTopic);
            Button deleteBtn = CreateTopicButton("УДАЛИТЬ", 140, DeleteTopic);
            Button exportBtn = CreateTopicButton("ЭКСПОРТ В .ffor", 200, ExportTopic);
            Button refreshBtn = CreateTopicButton("ОБНОВИТЬ", 260, (s, e) => UpdateTopicsList(statsLabel));

            buttonPanel.Controls.AddRange(new Control[] { viewBtn, replyBtn, deleteBtn, exportBtn, refreshBtn });

            tab.Controls.Add(topicsList);
            tab.Controls.Add(statsLabel);
            tab.Controls.Add(buttonPanel);

            this.Load += (s, e) => UpdateTopicsList(statsLabel);

            return tab;
        }

        private TabPage CreateCreateTab()
        {
            TabPage tab = new TabPage("Новая тема");
            tab.BackColor = Color.FromArgb(20, 20, 20);

            // Поля ввода
            Label titleLabel = new Label();
            titleLabel.Text = "Заголовок:";
            titleLabel.ForeColor = Color.White;
            titleLabel.Location = new Point(20, 20);

            topicTitleBox = new TextBox();
            topicTitleBox.Size = new Size(600, 30);
            topicTitleBox.Location = new Point(120, 17);
            topicTitleBox.BackColor = Color.Black;
            topicTitleBox.ForeColor = Color.Lime;
            topicTitleBox.Font = new Font("Consolas", 11);

            Label authorLabel = new Label();
            authorLabel.Text = "Автор:";
            authorLabel.ForeColor = Color.White;
            authorLabel.Location = new Point(20, 70);

            topicAuthorBox = new TextBox();
            topicAuthorBox.Size = new Size(300, 30);
            topicAuthorBox.Location = new Point(120, 67);
            topicAuthorBox.BackColor = Color.Black;
            topicAuthorBox.ForeColor = Color.Lime;
            topicAuthorBox.Font = new Font("Consolas", 11);

            Label contentLabel = new Label();
            contentLabel.Text = "Сообщение:";
            contentLabel.ForeColor = Color.White;
            contentLabel.Location = new Point(20, 120);

            topicContentBox = new RichTextBox();
            topicContentBox.Size = new Size(800, 250);
            topicContentBox.Location = new Point(20, 150);
            topicContentBox.BackColor = Color.Black;
            topicContentBox.ForeColor = Color.Lime;
            topicContentBox.Font = new Font("Consolas", 10);

            // Кнопка создания
            Button createBtn = new Button();
            createBtn.Text = "СОЗДАТЬ ТЕМУ";
            createBtn.Size = new Size(300, 50);
            createBtn.Location = new Point(20, 420);
            createBtn.BackColor = Color.FromArgb(0, 80, 0);
            createBtn.ForeColor = Color.White;
            createBtn.Font = new Font("Consolas", 14, FontStyle.Bold);
            createBtn.Click += CreateNewTopic;

            tab.Controls.AddRange(new Control[] {
                titleLabel, topicTitleBox,
                authorLabel, topicAuthorBox,
                contentLabel, topicContentBox,
                createBtn
            });

            return tab;
        }

        private TabPage CreateLogsTab()
        {
            TabPage tab = new TabPage("Логи");
            tab.BackColor = Color.Black;

            logListBox = new ListBox();
            logListBox.Dock = DockStyle.Fill;
            logListBox.BackColor = Color.Black;
            logListBox.ForeColor = Color.Lime;
            logListBox.Font = new Font("Consolas", 9);

            logListBox.Items.Add($"[{DateTime.Now:HH:mm:ss}] FFORUMF LOG");
            logListBox.Items.Add($"[{DateTime.Now:HH:mm:ss}] Система запущена");

            Panel logPanel = new Panel();
            logPanel.Dock = DockStyle.Bottom;
            logPanel.Height = 50;
            logPanel.BackColor = Color.FromArgb(30, 30, 30);

            Button clearLogsBtn = new Button();
            clearLogsBtn.Text = "Очистить логи";
            clearLogsBtn.Size = new Size(150, 30);
            clearLogsBtn.Location = new Point(20, 10);
            clearLogsBtn.Click += (s, e) => logListBox.Items.Clear();

            Button saveLogsBtn = new Button();
            saveLogsBtn.Text = "Сохранить логи";
            saveLogsBtn.Size = new Size(150, 30);
            saveLogsBtn.Location = new Point(180, 10);
            saveLogsBtn.Click += SaveLogs;

            logPanel.Controls.Add(clearLogsBtn);
            logPanel.Controls.Add(saveLogsBtn);

            tab.Controls.Add(logListBox);
            tab.Controls.Add(logPanel);

            return tab;
        }

        private Button CreateTopicButton(string text, int y, EventHandler handler)
        {
            Button btn = new Button();
            btn.Text = text;
            btn.Size = new Size(280, 40);
            btn.Location = new Point(10, y);
            btn.BackColor = Color.FromArgb(50, 50, 50);
            btn.ForeColor = Color.White;
            btn.Font = new Font("Consolas", 9);
            btn.Click += handler;
            return btn;
        }

        private void StartLogoAnimation()
        {
            logoTimer = new System.Windows.Forms.Timer();
            logoTimer.Interval = 50;
            logoTimer.Tick += (s, e) =>
            {
                logoCounter++;
                string[] oriyaChars = {
                    "ଅ", "ଆ", "ଇ", "ଈ", "ଉ", "ଊ", "ଋ", "ୠ", "ଌ", "ୡ",
                    "ଏ", "ଐ", "ଓ", "ଔ", "କ", "ଖ", "ଗ", "ଘ", "ଙ", "ଚ",
                    "ଛ", "ଜ", "ଝ", "ଞ", "ଟ", "ଠ", "ଡ", "ଢ", "ଣ", "ତ",
                    "ଥ", "ଦ", "ଧ", "ନ", "ପ", "ଫ", "ବ", "ଭ", "ମ", "ଯ",
                    "ର", "ଲ", "ଳ", "ୱ", "ଶ", "ଷ", "ସ", "ହ", "ଡୱ", "ଢୱ"
                };

                StringBuilder logoText = new StringBuilder("FFORUMF ");
                for (int i = 0; i < 12; i++)
                {
                    logoText.Append(oriyaChars[rnd.Next(oriyaChars.Length)]);
                }

                if (logoCounter % 8 == 0)
                {
                    Color[] colors = {
                        Color.Lime, Color.Cyan, Color.Magenta,
                        Color.Yellow, Color.Orange, Color.Pink,
                        Color.SpringGreen, Color.Aqua, Color.Fuchsia
                    };
                    logoLabel.ForeColor = colors[rnd.Next(colors.Length)];
                }

                logoLabel.Text = logoText.ToString();
            };

            logoTimer.Start();
        }

        // ===================== ШИФРОВАНИЕ (ТОЛЬКО ДЛЯ ФАЙЛОВ) =====================

        private string EncryptForFile(string text)
        {
            if (string.IsNullOrEmpty(text)) return text;

            try
            {
                // 1. Шифр Цезаря (сдвиг на 5)
                string step1 = CaesarCipher(text, 5);

                // 2. Отражаем строку
                string step2 = ReverseString(step1);

                // 3. Преобразуем в бинарный вид
                string step3 = StringToBinary(step2);

                // 4. Заменяем 1 на H, 0 на A
                string step4 = step3.Replace('1', 'H').Replace('0', 'A');

                return step4;
            }
            catch
            {
                return text;
            }
        }

        private string DecryptFromFile(string encrypted)
        {
            if (string.IsNullOrEmpty(encrypted)) return encrypted;

            try
            {
                // 4. Возвращаем 1 и 0
                string step4 = encrypted.Replace('H', '1').Replace('A', '0');

                // 3. Бинарный в текст
                string step3 = BinaryToString(step4);

                // 2. Возвращаем отражение
                string step2 = ReverseString(step3);

                // 1. Дешифруем Цезаря
                string step1 = CaesarCipher(step2, -5);

                return step1;
            }
            catch
            {
                return "DECRYPT_ERROR";
            }
        }

        private string CaesarCipher(string text, int shift)
        {
            if (string.IsNullOrEmpty(text)) return text;

            shift %= 26;
            char[] buffer = text.ToCharArray();

            for (int i = 0; i < buffer.Length; i++)
            {
                char letter = buffer[i];
                if (char.IsLetter(letter))
                {
                    char offset = char.IsUpper(letter) ? 'A' : 'a';
                    buffer[i] = (char)(((letter + shift - offset + 26) % 26) + offset);
                }
            }
            return new string(buffer);
        }

        private string ReverseString(string s)
        {
            if (string.IsNullOrEmpty(s)) return s;
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }

        private string StringToBinary(string data)
        {
            if (string.IsNullOrEmpty(data)) return "";

            StringBuilder binary = new StringBuilder();
            foreach (char c in data)
            {
                binary.Append(Convert.ToString(c, 2).PadLeft(8, '0'));
            }
            return binary.ToString();
        }

        private string BinaryToString(string binary)
        {
            if (string.IsNullOrEmpty(binary) || binary.Length % 8 != 0)
                return binary;

            try
            {
                List bytes = new List();
                for (int i = 0; i < binary.Length; i += 8)
                {
                    if (i + 8 <= binary.Length)
                    {
                        string byteString = binary.Substring(i, 8);
                        bytes.Add(Convert.ToByte(byteString, 2));
                    }
                }
                return Encoding.UTF8.GetString(bytes.ToArray());
            }
            catch
            {
                return binary;
            }
        }

        // ===================== УПРАВЛЕНИЕ IP =====================

        private void ToggleIPVisibility(Button toggleBtn)
        {
            showIP = !showIP;

            if (showIP)
            {
                toggleBtn.Text = "Скрыть IP";
                if (isRunning)
                {
                    string localIP = GetLocalIPAddress();
                    ipLabel.Text = $"IP: {localIP}:{port}";
                }
                else
                {
                    ipLabel.Text = "IP: Сервер не запущен";
                }
            }
            else
            {
                toggleBtn.Text = "Показать IP";
                ipLabel.Text = "IP: ***********";
            }
        }

        private void CopyIPToClipboard(object sender, EventArgs e)
        {
            if (isRunning && showIP)
            {
                string localIP = GetLocalIPAddress();
                Clipboard.SetText($"{localIP}:{port}");
                AddLog("IP скопирован в буфер обмена");
                MessageBox.Show($"IP скопирован: {localIP}:{port}", "Успех",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Сначала запустите сервер и покажите IP", "Ошибка",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void ChangePort(object sender, EventArgs e)
        {
            // Создаем свою форму для ввода порта
            Form portForm = new Form();
            portForm.Text = "Изменение порта";
            portForm.Size = new Size(300, 150);
            portForm.StartPosition = FormStartPosition.CenterScreen;
            portForm.BackColor = Color.FromArgb(30, 30, 30);

            Label label = new Label();
            label.Text = "Введите новый порт (1024-65535):";
            label.ForeColor = Color.White;
            label.Location = new Point(20, 20);
            label.Size = new Size(250, 20);

            TextBox portBox = new TextBox();
            portBox.Text = port.ToString();
            portBox.Location = new Point(20, 50);
            portBox.Size = new Size(240, 25);
            portBox.BackColor = Color.Black;
            portBox.ForeColor = Color.Lime;

            Button okBtn = new Button();
            okBtn.Text = "OK";
            okBtn.Location = new Point(20, 85);
            okBtn.Size = new Size(100, 30);
            okBtn.BackColor = Color.FromArgb(0, 100, 0);
            okBtn.ForeColor = Color.White;
            okBtn.DialogResult = DialogResult.OK;

            Button cancelBtn = new Button();
            cancelBtn.Text = "Отмена";
            cancelBtn.Location = new Point(130, 85);
            cancelBtn.Size = new Size(100, 30);
            cancelBtn.BackColor = Color.FromArgb(100, 0, 0);
            cancelBtn.ForeColor = Color.White;
            cancelBtn.DialogResult = DialogResult.Cancel;

            portForm.Controls.Add(label);
            portForm.Controls.Add(portBox);
            portForm.Controls.Add(okBtn);
            portForm.Controls.Add(cancelBtn);

            portForm.AcceptButton = okBtn;
            portForm.CancelButton = cancelBtn;

            if (portForm.ShowDialog() == DialogResult.OK)
            {
                string newPort = portBox.Text;
                if (int.TryParse(newPort, out int portNum) && portNum >= 1024 && portNum <= 65535)
                {
                    if (!isRunning)
                    {
                        port = portNum;
                        AddLog($"Порт изменен на: {port}");
                        MessageBox.Show($"Порт изменен на: {port}", "Успех",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        MessageBox.Show("Остановите сервер перед изменением порта", "Ошибка",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Неверный номер порта!", "Ошибка",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // ===================== ОСНОВНЫЕ МЕТОДЫ =====================

        private void CreateSampleTopics()
        {
            topics.Add(new ForumTopic
            {
                Id = Guid.NewGuid().ToString(),
                Title = "Добро пожаловать в FForumF!",
                Author = "Система",
                Content = "Это защищенный P2P форум. Сообщения шифруются только в файлах .ffor!",
                Created = DateTime.Now
            });

            AddLog("Созданы примерные темы");
        }

        private void UpdateTopicsList(Label statsLabel = null)
        {
            if (topicsList != null && !topicsList.IsDisposed)
            {
                topicsList.Items.Clear();
                foreach (var topic in topics.OrderByDescending(t => t.Created))
                {
                    topicsList.Items.Add(topic);
                }

                if (statsLabel != null && !statsLabel.IsDisposed)
                {
                    int totalMessages = topics.Sum(t => t.Messages.Count);
                    statsLabel.Text = $"Тем: {topics.Count} | Сообщений: {totalMessages}";
                }
            }
        }

        private void ViewTopic(object sender, EventArgs e)
        {
            if (topicsList.SelectedItem is ForumTopic selectedTopic)
            {
                TopicViewForm viewForm = new TopicViewForm(selectedTopic, this);
                viewForm.ShowDialog();
                UpdateTopicsList();
            }
        }

        private void ReplyToTopic(object sender, EventArgs e)
        {
            if (topicsList.SelectedItem is ForumTopic selectedTopic)
            {
                ReplyForm replyForm = new ReplyForm(selectedTopic, this);
                if (replyForm.ShowDialog() == DialogResult.OK)
                {
                    UpdateTopicsList();
                    AddLog($"Добавлен ответ в тему: {selectedTopic.Title}");
                }
            }
        }

        private void DeleteTopic(object sender, EventArgs e)
        {
            if (topicsList.SelectedItem is ForumTopic selectedTopic)
            {
                if (MessageBox.Show($"Удалить тему '{selectedTopic.Title}' со всеми сообщениями?",
                    "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    topics.Remove(selectedTopic);
                    UpdateTopicsList();
                    AddLog($"Удалена тема: {selectedTopic.Title}");
                }
            }
        }

        private void ExportTopic(object sender, EventArgs e)
        {
            if (topicsList.SelectedItem is ForumTopic selectedTopic)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "FFOR файлы|*.ffor";
                sfd.FileName = $"topic_{selectedTopic.Title.Replace(" ", "_")}_{DateTime.Now:yyyyMMdd}.ffor";

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        // Собираем данные для экспорта
                        string exportData = "FFORUMF TOPIC EXPORT\n";
                        exportData += $"ID:{selectedTopic.Id}\n";
                        exportData += $"TITLE:{selectedTopic.Title}\n";
                        exportData += $"AUTHOR:{selectedTopic.Author}\n";
                        exportData += $"CREATED:{selectedTopic.Created}\n";
                        exportData += "CONTENT_BEGIN\n";

                        // В файл пишем зашифрованный контент
                        string encryptedContent = EncryptForFile(selectedTopic.Content);
                        exportData += encryptedContent + "\n";
                        exportData += "CONTENT_END\n";

                        // Сообщения (также зашифрованные)
                        foreach (var msg in selectedTopic.Messages)
                        {
                            string encryptedMessage = EncryptForFile(msg.Text);
                            exportData += $"MESSAGE:{msg.Id}|{msg.Author}|{msg.Time}|{encryptedMessage}\n";
                        }

                        // Сохраняем файл
                        File.WriteAllText(sfd.FileName, exportData);

                        AddLog($"Тема экспортирована в: {Path.GetFileName(sfd.FileName)}");
                        MessageBox.Show("Тема успешно экспортирована в .ffor файл!", "Успех",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        AddLog($"Ошибка экспорта: {ex.Message}");
                        MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void CreateNewTopic(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(topicTitleBox.Text) ||
                string.IsNullOrWhiteSpace(topicAuthorBox.Text) ||
                string.IsNullOrWhiteSpace(topicContentBox.Text))
            {
                MessageBox.Show("Заполните все поля!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ForumTopic newTopic = new ForumTopic
            {
                Id = Guid.NewGuid().ToString(),
                Title = topicTitleBox.Text,
                Author = topicAuthorBox.Text,
                Content = topicContentBox.Text, // В интерфейсе - обычный текст
                Created = DateTime.Now
            };

            topics.Add(newTopic);

            // Очищаем форму
            topicTitleBox.Clear();
            topicAuthorBox.Clear();
            topicContentBox.Clear();

            UpdateTopicsList();
            AddLog($"Создана новая тема: {newTopic.Title}");

            MessageBox.Show("Тема создана!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void CreateBackup(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "FFOR Backup|*.ffor";
            sfd.FileName = $"forum_backup_{DateTime.Now:yyyyMMdd_HHmmss}.ffor";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    string backupData = "FFORUMF BACKUP v2.0\n";
                    backupData += $"DATE:{DateTime.Now}\n";
                    backupData += $"TOPICS:{topics.Count}\n";
                    backupData += "ENCRYPTED:YES\n";

                    foreach (var topic in topics)
                    {
                        backupData += $"TOPIC_BEGIN\n";
                        backupData += $"TITLE:{topic.Title}\n";
                        backupData += $"AUTHOR:{topic.Author}\n";
                        backupData += $"CREATED:{topic.Created}\n";

                        // Контент шифруем только для файла
                        string encryptedContent = EncryptForFile(topic.Content);
                        backupData += $"CONTENT:{encryptedContent}\n";

                        foreach (var msg in topic.Messages)
                        {
                            string encryptedMessage = EncryptForFile(msg.Text);
                            backupData += $"MSG:{msg.Author}|{msg.Time}|{encryptedMessage}\n";
                        }

                        backupData += $"TOPIC_END\n";
                    }

                    File.WriteAllText(sfd.FileName, backupData);

                    AddLog($"Создан бэкап: {Path.GetFileName(sfd.FileName)}");
                    MessageBox.Show("Бэкап создан успешно! Данные зашифрованы.", "Резервная копия",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    AddLog($"Ошибка создания бэкапа: {ex.Message}");
                    MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void SaveLogs(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Текстовые файлы|*.txt|Все файлы|*.*";
            sfd.FileName = $"forum_logs_{DateTime.Now:yyyyMMdd_HHmmss}.txt";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    using (StreamWriter sw = new StreamWriter(sfd.FileName))
                    {
                        foreach (var item in logListBox.Items)
                        {
                            sw.WriteLine(item.ToString());
                        }
                    }

                    AddLog($"Логи сохранены в: {Path.GetFileName(sfd.FileName)}");
                    MessageBox.Show("Логи успешно сохранены!", "Успех",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Ошибка сохранения: {ex.Message}", "Ошибка",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        public void AddLog(string message)
        {
            try
            {
                if (logListBox != null && !logListBox.IsDisposed)
                {
                    if (logListBox.InvokeRequired)
                    {
                        logListBox.Invoke(new Action(AddLog), message);
                    }
                    else
                    {
                        string logEntry = $"[{DateTime.Now:HH:mm:ss}] {message}";
                        logListBox.Items.Add(logEntry);
                        logListBox.TopIndex = logListBox.Items.Count - 1;
                    }
                }
            }
            catch { }
        }

        private void StartServer(Label statusLabel, Label ipLabel, Label clientsLabel, Button startBtn)
        {
            if (isRunning) return;

            try
            {
                server = new TcpListener(IPAddress.Any, port);
                server.Start();
                isRunning = true;

                serverThread = new Thread(() =>
                {
                    while (isRunning)
                    {
                        try
                        {
                            TcpClient client = server.AcceptTcpClient();
                            string clientIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();

                            ClientHandler handler = new ClientHandler(client, this);
                            clients.Add(handler);
                            Thread clientThread = new Thread(new ThreadStart(handler.Process));
                            clientThread.Start();

                            this.Invoke(new Action(() => {
                                clientsLabel.Text = $"Клиентов: {clients.Count}";
                            }));

                            AddLog($"Новое подключение: {clientIP}");
                        }
                        catch { }
                    }
                });

                serverThread.Start();

                statusLabel.Text = "СЕРВЕР ОНЛАЙН";
                statusLabel.ForeColor = Color.Lime;

                string localIP = GetLocalIPAddress();
                if (showIP)
                {
                    ipLabel.Text = $"IP: {localIP}:{port}";
                }

                startBtn.Enabled = false;

                AddLog($"Хост запущен на {localIP}:{port}");
                MessageBox.Show($"Хост запущен!\n\nIP для подключения: {localIP}:{port}",
                    "FForumF Хост", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                AddLog($"Ошибка запуска сервера: {ex.Message}");
                MessageBox.Show($"Ошибка запуска: {ex.Message}", "Ошибка",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void StopServer(Label statusLabel, Label ipLabel, Label clientsLabel, Button startBtn)
        {
            if (!isRunning) return;

            try
            {
                isRunning = false;
                server.Stop();

                foreach (var client in clients)
                {
                    client.Close();
                }
                clients.Clear();

                statusLabel.Text = "СЕРВЕР ОФФЛАЙН";
                statusLabel.ForeColor = Color.Red;
                ipLabel.Text = "IP: Сервер не запущен";
                clientsLabel.Text = "Клиентов: 0";
                startBtn.Enabled = true;

                AddLog("Хост остановлен");

                // Предлагаем скачать бэкап
                if (topics.Count > 0)
                {
                    var result = MessageBox.Show("Хотите сохранить резервную копию всех тем перед выходом?",
                        "Бэкап", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (result == DialogResult.Yes)
                    {
                        CreateBackupOnStop();
                    }
                }
            }
            catch (Exception ex)
            {
                AddLog($"Ошибка остановки сервера: {ex.Message}");
            }
        }

        private void CreateBackupOnStop()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "FFOR Backup|*.ffor";
            sfd.FileName = $"forum_stop_backup_{DateTime.Now:yyyyMMdd_HHmmss}.ffor";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    string backupData = "FFORUMF STOP BACKUP\n";
                    backupData += $"DATE:{DateTime.Now}\n";
                    backupData += $"TOPICS:{topics.Count}\n";

                    foreach (var topic in topics)
                    {
                        string encryptedTitle = EncryptForFile(topic.Title);
                        backupData += $"TOPIC:{encryptedTitle}|{topic.Author}|{topic.Created}\n";
                    }

                    File.WriteAllText(sfd.FileName, backupData);

                    AddLog($"Бэкап при остановке создан: {Path.GetFileName(sfd.FileName)}");
                    MessageBox.Show("Бэкап создан успешно!", "Резервная копия",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    AddLog($"Ошибка создания бэкапа: {ex.Message}");
                }
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isRunning)
            {
                var result = MessageBox.Show("Хост все еще работает. Остановить и выйти?",
                    "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    if (topics.Count > 0)
                    {
                        try
                        {
                            string autoBackup = $"auto_backup_{DateTime.Now:yyyyMMdd_HHmmss}.ffor";
                            string backupData = "AUTO BACKUP\n";
                            foreach (var topic in topics)
                            {
                                backupData += $"TOPIC:{topic.Title}\n";
                            }
                            File.WriteAllText(autoBackup, backupData);
                            AddLog($"Авто-бэкап создан: {autoBackup}");
                        }
                        catch { }
                    }

                    logoTimer?.Stop();
                    isRunning = false;
                    server?.Stop();
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        private string GetLocalIPAddress()
        {
            try
            {
                var host = Dns.GetHostEntry(Dns.GetHostName());
                foreach (var ip in host.AddressList)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                    {
                        return ip.ToString();
                    }
                }
            }
            catch { }
            return "127.0.0.1";
        }

        public string EncryptData(string data) => EncryptForFile(data);
        public string DecryptData(string data) => DecryptFromFile(data);

        // Класс обработки клиентов
        private class ClientHandler
        {
            private TcpClient client;
            private NetworkStream stream;
            private MainForm mainForm;

            public ClientHandler(TcpClient tcpClient, MainForm form)
            {
                client = tcpClient;
                stream = client.GetStream();
                mainForm = form;
            }

            public void Process()
            {
                try
                {
                    byte[] buffer = new byte[1024];
                    int bytesRead = stream.Read(buffer, 0, buffer.Length);

                    if (bytesRead > 0)
                    {
                        string request = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        mainForm.AddLog($"Запрос от клиента: {request.Substring(0, Math.Min(50, request.Length))}");

                        string response = "OK";
                        byte[] responseData = Encoding.UTF8.GetBytes(response);
                        stream.Write(responseData, 0, responseData.Length);
                    }
                }
                catch
                {
                    // Клиент отключился
                }
                finally
                {
                    Close();
                }
            }

            public void Close()
            {
                try
                {
                    stream?.Close();
                    client?.Close();
                }
                catch { }
            }
        }
    }

    // Форма для ответов на темы
    public class ReplyForm : Form
    {
        private ForumTopic topic;
        private MainForm mainForm;
        private TextBox authorBox;
        private RichTextBox messageBox;

        public ReplyForm(ForumTopic topic, MainForm mainForm)
        {
            this.topic = topic;
            this.mainForm = mainForm;
            InitializeForm();
        }

        private void InitializeForm()
        {
            this.Text = $"Ответ в тему: {topic.Title}";
            this.Size = new Size(700, 500);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.BackColor = Color.FromArgb(15, 15, 15);

            // Заголовок
            Label titleLabel = new Label();
            titleLabel.Text = $"Ответ в: {topic.Title}";
            titleLabel.Font = new Font("Consolas", 14, FontStyle.Bold);
            titleLabel.ForeColor = Color.Cyan;
            titleLabel.Location = new Point(20, 20);
            titleLabel.Size = new Size(650, 30);

            // Автор
            Label authorLabel = new Label();
            authorLabel.Text = "Ваше имя:";
            authorLabel.ForeColor = Color.White;
            authorLabel.Location = new Point(20, 70);

            authorBox = new TextBox();
            authorBox.Size = new Size(300, 25);
            authorBox.Location = new Point(120, 67);
            authorBox.BackColor = Color.Black;
            authorBox.ForeColor = Color.Lime;
            authorBox.Font = new Font("Consolas", 10);

            // Сообщение
            Label messageLabel = new Label();
            messageLabel.Text = "Сообщение:";
            messageLabel.ForeColor = Color.White;
            messageLabel.Location = new Point(20, 120);

            messageBox = new RichTextBox();
            messageBox.Size = new Size(650, 250);
            messageBox.Location = new Point(20, 150);
            messageBox.BackColor = Color.Black;
            messageBox.ForeColor = Color.Lime;
            messageBox.Font = new Font("Consolas", 10);

            // Кнопки
            Button sendBtn = new Button();
            sendBtn.Text = "ОТПРАВИТЬ ОТВЕТ";
            sendBtn.Size = new Size(200, 40);
            sendBtn.Location = new Point(150, 420);
            sendBtn.BackColor = Color.FromArgb(0, 80, 0);
            sendBtn.ForeColor = Color.White;
            sendBtn.Click += SendReply;

            Button cancelBtn = new Button();
            cancelBtn.Text = "ОТМЕНА";
            cancelBtn.Size = new Size(200, 40);
            cancelBtn.Location = new Point(370, 420);
            cancelBtn.Click += (s, e) => this.DialogResult = DialogResult.Cancel;

            this.Controls.AddRange(new Control[] {
                titleLabel,
                authorLabel, authorBox,
                messageLabel, messageBox,
                sendBtn, cancelBtn
            });
        }

        private void SendReply(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(authorBox.Text) ||
                string.IsNullOrWhiteSpace(messageBox.Text))
            {
                MessageBox.Show("Заполните имя и сообщение!", "Ошибка",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ForumMessage newMessage = new ForumMessage
            {
                Id = Guid.NewGuid().ToString(),
                Author = authorBox.Text,
                Text = messageBox.Text, // Обычный текст в интерфейсе
                Time = DateTime.Now
            };

            topic.Messages.Add(newMessage);

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    }

    // Форма просмотра темы (БЕЗ ШИФРОВАНИЯ в интерфейсе)
    public class TopicViewForm : Form
    {
        private ForumTopic topic;
        private MainForm mainForm;
        private ListBox messagesList;

        public TopicViewForm(ForumTopic topic, MainForm mainForm)
        {
            this.topic = topic;
            this.mainForm = mainForm;
            InitializeForm();
        }

        private void InitializeForm()
        {
            this.Text = $"Тема: {topic.Title}";
            this.Size = new Size(900, 700);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.BackColor = Color.FromArgb(15, 15, 15);

            // Заголовок
            Label titleLabel = new Label();
            titleLabel.Text = topic.Title;
            titleLabel.Font = new Font("Consolas", 16, FontStyle.Bold);
            titleLabel.ForeColor = Color.Cyan;
            titleLabel.Location = new Point(20, 20);
            titleLabel.Size = new Size(850, 40);

            // Информация
            Label infoLabel = new Label();
            infoLabel.Text = $"Автор: {topic.Author} | Создано: {topic.Created:dd.MM.yyyy HH:mm} | Ответов: {topic.Messages.Count}";
            infoLabel.Font = new Font("Consolas", 10);
            infoLabel.ForeColor = Color.LightGray;
            infoLabel.Location = new Point(20, 70);

            // Содержание (ОБЫЧНЫЙ ТЕКСТ - не шифрованный!)
            RichTextBox contentBox = new RichTextBox();
            contentBox.Text = topic.Content; // Прямой текст
            contentBox.Size = new Size(850, 150);
            contentBox.Location = new Point(20, 100);
            contentBox.BackColor = Color.Black;
            contentBox.ForeColor = Color.White;
            contentBox.Font = new Font("Consolas", 10);
            contentBox.ReadOnly = true;

            // Ответы
            Label repliesLabel = new Label();
            repliesLabel.Text = "Ответы:";
            repliesLabel.Font = new Font("Consolas", 12, FontStyle.Bold);
            repliesLabel.ForeColor = Color.White;
            repliesLabel.Location = new Point(20, 270);

            messagesList = new ListBox();
            messagesList.Size = new Size(850, 300);
            messagesList.Location = new Point(20, 300);
            messagesList.BackColor = Color.Black;
            messagesList.ForeColor = Color.Lime;
            messagesList.Font = new Font("Consolas", 9);

            UpdateMessagesList();

            // Кнопки
            Button replyBtn = new Button();
            replyBtn.Text = "ОТВЕТИТЬ";
            replyBtn.Size = new Size(200, 40);
            replyBtn.Location = new Point(20, 620);
            replyBtn.Click += (s, e) =>
            {
                ReplyForm replyForm = new ReplyForm(topic, mainForm);
                if (replyForm.ShowDialog() == DialogResult.OK)
                {
                    UpdateMessagesList();
                }
            };

            Button closeBtn = new Button();
            closeBtn.Text = "ЗАКРЫТЬ";
            closeBtn.Size = new Size(200, 40);
            closeBtn.Location = new Point(670, 620);
            closeBtn.Click += (s, e) => this.Close();

            this.Controls.AddRange(new Control[] {
                titleLabel, infoLabel, contentBox,
                repliesLabel, messagesList,
                replyBtn, closeBtn
            });
        }

        private void UpdateMessagesList()
        {
            messagesList.Items.Clear();
            foreach (var msg in topic.Messages.OrderBy(m => m.Time))
            {
                // Прямой текст - не дешифрованный!
                messagesList.Items.Add($"[{msg.Time:HH:mm}] {msg.Author}: {msg.Text}");
            }
        }
    }
}
    

Form4.Designer.cs

namespace FForumF
{
    partial class MainForm
    {
        /// 
        /// Required designer variable.
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// Clean up any resources being used.
        /// 
        /// true if managed resources should be disposed; otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// 
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// 
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Text = "Form4";
        }

        #endregion
    }
}
    

Form5.cs



    

Form5.Designer.cs