Subversion Repositories BlockadePP

Rev

Rev 7 | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace blockade
{
    public partial class Form1 : Form
    {
       
        public class smoke
        {
            public Color colour;
            public Point loc;
            public int time;

            public smoke(Color colourN, Point locN, int timeN)
            {
                colour = colourN;
                loc = locN;
                time = timeN;
            }
        }

        public class enemyType
        {
            public float health, speed, spawnChance;
            public int child, value, spawn;
            public animg img;

            public Image getImg()
            {
                return img.curImg();
            }

            public Image getImg(int num)
            {
                img.runTime = num;
                return img.curImg();
            }
           
            public enemyType(string healthN, string speedN, string childN, string spawnN, string spawnChanceN, string imgN)
            {
                health = float.Parse(healthN);
                speed = float.Parse(speedN);
                child = int.Parse(childN);
                img = new animg(imgN);
                spawn = int.Parse(spawnN);
                spawnChance = float.Parse(spawnChanceN);
                value = (int)(speed * health / 20 + health / 20);
            }

            public enemyType(string[] data)
            {
                health = float.Parse(data[0]);
                speed = float.Parse(data[1]);
                child = int.Parse(data[2]);
                spawn = int.Parse(data[3]);
                spawnChance = float.Parse(data[4]);
                img = new animg(data[5]);
                value = (int)(speed * health / 50 + health / 20);
            }
        }

        public class enemy
        {
            public int type;
            public float health;
            public float angle;
            public PointF loc;
            public int imgTime;
            public float dX, dY;
           
            public void incImg()
            {
                imgTime++;
            }

            public enemy(int typeN, float healthN, float angleN, PointF locN)
            {
                // have to pass health, enemy cannot work it out
                type = typeN;
                health = healthN;
                angle = angleN;
                loc = locN;
            }
        }

        public class missileType
        {
            public Image img;
            public int speed, damage, spread;
            public float energy;

            public missileType(string imgN, string speedN, string damageN, string spreadN, string energyN)
            {
                img = Image.FromFile(imgN);
                speed = int.Parse(speedN);
                damage = int.Parse(damageN);
                spread = int.Parse(spreadN);
            }

            public missileType(string[] data)
            {
                img = Image.FromFile(data[0]);
                speed = int.Parse(data[1]);
                damage = int.Parse(data[2]);
                spread = int.Parse(data[3]);
            }
        }

        public class towerType
        {
            public Color laserColour;
            public int missileID;
            public float maxEnergy, gainRate, useRate, damage;
            public int cost, range, laserType, extRange, killNum;
            public animg baseImg, turretImg;
            public int req, delay;
            public string sound;
            public string name;
            public string[] details;
           
            public Image getBaseImg()
            {
                return baseImg.curImg();
            }
           
            public Image getTurretImg()
            {
                return turretImg.curImg();
            }
           
            public Image getBaseImg(int num)
            {
                baseImg.runTime = num;
                return baseImg.curImg();
            }
           
            public Image getTurretImg(int num)
            {
                turretImg.runTime = num;
                return turretImg.curImg();
            }

            public towerType(string laserColourN, string maxEnergyN, string gainRateN, string useRateN, string rangeN, string costN, string reqN, string delayN, string baseImgN, string turretImgN, string soundN, string laserTypeN, string extRangeN, string killNumN, string nameN, string detailsN)
            {
                laserColour = Color.FromName(laserColourN);
                maxEnergy = int.Parse(maxEnergyN);
                gainRate = float.Parse(gainRateN);
                useRate = float.Parse(useRateN);
                damage = useRate;
                cost = int.Parse(costN);
                range = int.Parse(rangeN);
                req = int.Parse(reqN);
                delay = int.Parse(delayN);
                baseImg = new animg(baseImgN);
                turretImg = new animg(turretImgN);
                sound = soundN;
                laserType = int.Parse(laserTypeN);
                extRange = int.Parse(extRangeN);
                killNum = int.Parse(killNumN);
                name = nameN;
                details = detailsN.Split(':');
               
                for (int i = 0; i < details.Length; i++)
                        details[i] = details[i].Replace('`', ',');
            }

            public towerType(string missileIDN, string maxEnergyN, string gainRateN, string rangeN, string costN, string reqN, string delayN, string baseImgN, string turretImgN, string soundN, string nameN, string detailsN)
            {
                missileID = int.Parse(missileIDN);
                maxEnergy = int.Parse(maxEnergyN);
                gainRate = float.Parse(gainRateN);
                cost = int.Parse(costN);
                range = int.Parse(rangeN);
                req = int.Parse(reqN);
                delay = int.Parse(delayN);
                baseImg = new animg(baseImgN);
                turretImg = new animg(turretImgN);
                sound = soundN;
                name = nameN;
                details = detailsN.Split(':');
               
                for (int i = 0; i < details.Length; i++)
                        details[i] = details[i].Replace('`', ',');
            }

            public towerType(string[] data)
            {

                if (data.Length == 16)
                {
                    laserColour = Color.FromName(data[0]);
                    maxEnergy = int.Parse(data[1]);
                    gainRate = float.Parse(data[2]);
                    useRate = float.Parse(data[3]);
                    damage = useRate;
                    cost = int.Parse(data[4]);
                    range = int.Parse(data[5]);
                    req = int.Parse(data[6]);
                    delay = int.Parse(data[7]);
                    baseImg = new animg(data[8]);
                    turretImg = new animg(data[9]);
                    sound = @"data/" + data[10];
                    laserType = int.Parse(data[11]);
                    extRange = int.Parse(data[12]);
                    killNum = int.Parse(data[13]);
                    name = data[14];
                    details = data[15].Split(':');
                }
                else
                {
                    missileID = int.Parse(data[0]);
                    maxEnergy = int.Parse(data[1]);
                    gainRate = float.Parse(data[2]);
                    cost = int.Parse(data[3]);
                    range = int.Parse(data[4]);
                        req = int.Parse(data[5]);
                        delay = int.Parse(data[6]);
                        baseImg = new animg(data[7]);
                    turretImg = new animg(data[8]);
                    sound = @"data/" + data[9];
                    name = data[10];
                    details = data[11].Split(':');
                }
               
                for (int i = 0; i < details.Length; i++)
                        details[i] = details[i].Replace('`', ',');
                     
            }
        }

        public class tower
        {
            public int type, delayTime;
            public float energy, glow, angle;
            public bool fireing;
            public Point loc;
            public int baseTime, turretTime;
            public List<int> targets;
//            public WMPLib.WindowsMediaPlayer s;
                                   
                        public int target
                        {
                                get
                                {
                                        if (targets.Count != 0)
                                                return targets[0];
                                        else
                                                return -1;
                                }
                                set
                                {
                                        if (value == -1)
                                                targets.Clear();
                                        else if (targets.Count == 0)
                                                targets.Add(value);
                                        else
                                                targets[0] = value;
                                }
                        }
           
            public void incImgs()
            {
                baseTime++;
                turretTime++;
            }

            public tower(int typeN, Point locN, string soundLoc)
            {
                targets = new List<int>();
                type = typeN;
                target = -1;
                energy = 0;
                glow = 0;
                fireing = false;
                loc = locN;
                angle = 180.0f;
                baseTime = 0;
                turretTime = 0;
                delayTime = 0;
//                s = new WMPLib.WindowsMediaPlayer();
//                s.settings.autoStart = false;
//                s.settings.volume = 50;
//                s.URL = soundLoc;
            }
           
        }
       
        /// <summary>
        /// Animated Img for Blockade
        /// </summary>
        public class animg
        {
               
                public Image[] imgs;
                public int[] delays;
                public int runTime, maxRunTime;
                public string stringEq;
               
                public void inc()
                {
                        runTime++;
                        if (runTime > maxRunTime)
                                runTime = 0;
                }
               
                public Image curImg()
                {
                                int cDelay = 0;
                        for (int i = 0; i < delays.Length; i++)
                        {
                                cDelay += delays[i];
                                if (cDelay > runTime)
                                        return imgs[i];
                        }
                       
                        return imgs[0];
                }
               
                public animg clone()
                {
                        return new animg(stringEq);
                }
                       
                public animg(string s)
                {
                        stringEq = s;
                        string[] data = s.Split(':');
                       
                        imgs = new Image[(int)(data.Length / 2)];
                        delays = new int[(int)(data.Length / 2)];
                       
                                int cDelay = 0;
                        for (int i = 0; i < data.Length; i += 2)
                        {
                                imgs[(int)(i / 2)] = Image.FromFile(@"data/" + data[i]);
                                delays[(int)(i / 2)] = int.Parse(data[i + 1]);
                                cDelay += delays[(int)(i / 2)];
                        }
                       
                        maxRunTime = cDelay;
                       
                }
               
        }

        public List<smoke> smokes = new List<smoke>();

        public List<enemyType> enemyTypes = new List<enemyType>();
        public List<missileType> missileTypes = new List<missileType>();
        public List<towerType> towerTypes = new List<towerType>();

        public List<enemy> enemies = new List<enemy>();
        public List<tower> towers = new List<tower>();

        public List<PictureBox> icons = new List<PictureBox>();
       
        string[] laserType0, laserType1, laserType2, cashA, livesA, levelA;
        string[] laserTypeLookup;
       
        string[] levels;

        public int selTowerType = 0;
        public int cash;
        public int lives;
        public int level = 0;
        public int fCount;
        public bool energyBars, autoRun, rangeRings, sound;
        public Image yesImg, noImg, selImg, bgImg;
        public float smokeMul;
        public Color controlBGColour, controlFGColour;
                public string detailText = "";        
                public int lang;

                public bool extraPretty = false;
                public bool showTotalOfEngery = false;
        Random rnd = new Random();

        public Form1(int language)
        {
            InitializeComponent();
            lang = language;
        }

        void mainLoop()
        {
                System.Threading.Thread.Sleep(1);
            while (enemies.Count > 0)
            {
                fCount++;
                Application.DoEvents();
                enemyLoop();
                towerLoop();
                missileLoop();
                smokeLoop();
                Application.DoEvents();
                draw();
            }
            cash += (int)(lives / 2);
            level++;
            if (autoRun)
                newRun();
            else
            {
                smokes.Clear();
                draw();
            }
        }

        void enemyLoop()
        {
            for (int i = enemies.Count - 1; i >= 0; i--)
            {
                enemies[i].incImg();
                if (enemies[i].health <= 0)
                {
                        cash += enemyTypes[enemies[i].type].value;
                    if (enemyTypes[enemies[i].type].child == -1)
                    {
                        enemies.RemoveAt(i);
                        for (int j = 0; j < towers.Count; j++)
                        {
                                // loop removed
                                if (towers[j].target > i)
                                towers[j].target--;
                            else if (towers[j].target == i)
                                towers[j].target = -1;
                        }
                    }
                    else
                    {
                        enemies[i].type = enemyTypes[enemies[i].type].child;
                        enemies[i].health = enemyTypes[enemies[i].type].health;
                        initMove(i);
                    }
                }
                else
                {
                    move(i);
                        if (enemyTypes[enemies[i].type].spawn != -1)
                        {
                                if (rnd.NextDouble() < enemyTypes[enemies[i].type].spawnChance)
                                {
                                        enemies.Add(new enemy(enemyTypes[enemies[i].type].spawn, enemyTypes[enemyTypes[enemies[i].type].spawn].health, (float)getAngle(FtoP(enemies[i].loc), new Point(500, rnd.Next(40,360))), enemies[i].loc));
                                        initMove(enemies.Count - 1);
                                }
                        }
                    if (enemies[i].loc.X > 500)
                    {
                        lives--;
                        enemies.RemoveAt(i);
                        for (int j = 0; j < towers.Count; j++)
                        {
                                // loop removed
                                if (towers[j].target > i)
                                towers[j].target--;
                            else if (towers[j].target == i)
                                towers[j].target = -1;
                        }
                    }
                }
            }
        }

        void towerLoop()
        {
            for (int i = 0; i < towers.Count; i++)
            {
                towers[i].incImgs();
                if (towers[i].glow > 0)
                        towers[i].glow--;
                if (towers[i].delayTime != 0)
                    towers[i].delayTime--;
               
                if (towers[i].target == -1 || getDist(towers[i].loc, FtoP(enemies[towers[i].target].loc)) > towerTypes[towers[i].type].range)
                {
                        towers[i].target = -1;
                    reTarget(i);
                }
                else if (towerTypes[towers[i].type].req != 0 && towers[i].energy >= towerTypes[towers[i].type].req)
                {
                        if (towerTypes[towers[i].type].laserType == 2)
                                reTarget(i);
                        fire(i, true);
                }
                reAngle(i);
                if (towers[i].fireing && towers[i].target != -1 && towers[i].energy >= towerTypes[towers[i].type].useRate)
                {
//                              towers[i].s.controls.play();
                    if (towerTypes[towers[i].type].laserColour == null)
                    {
                    }
                    else if (towers[i].delayTime == 0)
                    {
                        towers[i].energy -= towerTypes[towers[i].type].useRate;
                        int smokeSpreadWidth = (int)(getEnemyImg(towers[i].target).Width / 3);
                        int smokeSpreadHeight = (int)(getEnemyImg(towers[i].target).Height / 3);
                        int num = rnd.Next(1, (int)(towerTypes[towers[i].type].useRate / 100 + 2));
                        switch (towerTypes[towers[i].type].laserType)
                        {
                                case (0):
                                {
                                        enemies[towers[i].target].health -= towerTypes[towers[i].type].damage;
                                        for (int j = 0; j < (int)(num * smokeMul + rnd.NextDouble() * 1.5 + 0.5); j++)
                                                smokes.Add(new smoke(towerTypes[towers[i].type].laserColour, new Point((int)enemies[towers[i].target].loc.X + rnd.Next(-smokeSpreadWidth, smokeSpreadWidth), (int)enemies[towers[i].target].loc.Y + rnd.Next(-smokeSpreadHeight, smokeSpreadHeight)), 20));
                                        break;
                                }
                                case (1):
                                {
                                        enemies[towers[i].target].health -= towerTypes[towers[i].type].damage;
                                        for (int j = 0; j < (int)(num * smokeMul + rnd.NextDouble() * 1.5 + 0.5); j++)
                                                smokes.Add(new smoke(towerTypes[towers[i].type].laserColour, new Point((int)enemies[towers[i].target].loc.X + rnd.Next(-smokeSpreadWidth, smokeSpreadWidth), (int)enemies[towers[i].target].loc.Y + rnd.Next(-smokeSpreadHeight, smokeSpreadHeight)), 20));
                                        break;
                                }
                                case (2):
                                {
                                        for (int r = 0; r < towers[i].targets.Count; r++)
                                        {
                                                enemies[towers[i].targets[r]].health -= towerTypes[towers[i].type].damage / (float)towers[i].targets.Count;
                                                for (int j = 0; j < (int)(num * smokeMul + rnd.NextDouble() * 1.5 / (float)towers[i].targets.Count + 0.5); j++)
                                                        smokes.Add(new smoke(towerTypes[towers[i].type].laserColour, new Point((int)enemies[towers[i].targets[r]].loc.X + rnd.Next(-smokeSpreadWidth, smokeSpreadWidth), (int)enemies[towers[i].targets[r]].loc.Y + rnd.Next(-smokeSpreadHeight, smokeSpreadHeight)), 20));
                                        }
                                        break;
                                }
                        }
                        towers[i].glow = towerTypes[towers[i].type].useRate;
                        towers[i].delayTime += towerTypes[towers[i].type].delay;
                    }
                }
                else
                {
                        fire(i, false);
                        towers[i].energy += towerTypes[towers[i].type].gainRate - rnd.Next(0, (int)Math.Ceiling((towerTypes[towers[i].type].gainRate / 5)));
                    if (towers[i].energy >= towerTypes[towers[i].type].maxEnergy && towers[i].target != -1)
                        {
                        towers[i].energy = towerTypes[towers[i].type].maxEnergy;
                    }
                }
                if (towers[i].energy > towerTypes[towers[i].type].maxEnergy)
                        towers[i].energy = towerTypes[towers[i].type].maxEnergy;
            }
        }

        void missileLoop()
        {

        }

        void smokeLoop()
        {
            for (int i = smokes.Count - 1; i >= 0 ; i--)
            {
                smokes[i].time--;
                if (smokes[i].time <= 0)
                    smokes.RemoveAt(i);
            }
        }

        void newRun()
        {
            if (level >= levels.Length)
            {
                level = 0;
                for (int i = 0; i < enemyTypes.Count; i++)
                {
                        enemyTypes[i].health *= 1.2f;
                }
            }
            string[] data = levels[level].Split(',');
            PointF start;
            Point end;
            for (int i = 0; i < data.Length; i++)
            {
                start = new PointF(rnd.Next(-150, -55), rnd.Next(40, 360));
                end = new Point(500, rnd.Next(40, 360));
                enemies.Add(new enemy(int.Parse(data[i]), enemyTypes[int.Parse(data[i])].health, (float)getAngle(FtoP(start), end), start));
                initMove(enemies.Count - 1);
                enemies[enemies.Count - 1].imgTime = rnd.Next(enemyTypes[enemies[enemies.Count - 1].type].img.maxRunTime);
            }
            mainLoop();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            initAll();
        }

        public void initAll()
        {
               
                // handels
               
                System.IO.StreamReader reader;
                string r;
            string[] lines;
               
                // textLookUps
               
            reader = new System.IO.StreamReader(@"data/gameTexts.dat", Encoding.UTF8);
            lines = reader.ReadToEnd().Split('\n');
           
            laserType0 = lines[0].Split(':');
            laserType1 = lines[1].Split(':');
            laserType2 = lines[2].Split(':');
            cashA = lines[3].Split(':');
            livesA = lines[4].Split(':');
            levelA = lines[5].Split(':');
           
            laserTypeLookup = new String[3];
            laserTypeLookup[0] = laserType0[lang];
            laserTypeLookup[1] = laserType1[lang];
            laserTypeLookup[2] = laserType2[lang];
       
            // init start vars
           
            reader = new System.IO.StreamReader(@"data/start.dat", Encoding.UTF8);
            r = reader.ReadToEnd();
            reader.Close();
            string[] data = r.Split(',');
            cash = int.Parse(data[0]);
            lives = int.Parse(data[1]);
            bgImg = Image.FromFile(@"data/" + data[2]);
            beamF.Image = Image.FromFile(@"data/" + data[3]);
            smokeMul = float.Parse(data[4]);
            controlBGColour = Color.FromName(data[5]);
            controlFGColour = Color.FromName(data[6]);
               
            // basic UI stuff

            this.Text = "Blockade!";
            yesImg = Image.FromFile(@"data/yesImg.png");
            noImg = Image.FromFile(@"data/noImg.png");
            selImg = Image.FromFile(@"data/selImg.png");
            goF.BackColor = controlBGColour;
                goF.BackgroundImage = yesImg;
            goF.Image = Image.FromFile(@"data/go.png");
            cashF.BackColor = controlBGColour;
            livesF.BackColor = controlBGColour;
            levelF.BackColor = controlBGColour;
            cashF.ForeColor = controlFGColour;
            livesF.ForeColor = controlFGColour;
            levelF.ForeColor = controlFGColour;
           
           
            // load ingame object types
           
            reader = new System.IO.StreamReader(@"data/enemies.dat", Encoding.UTF8);
            r = reader.ReadToEnd();
            reader.Close();
            lines = r.Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length != 0 && lines[i].Substring(0,1) != "#")
                    enemyTypes.Add(new enemyType(lines[i].Split(',')));
            }

            reader = new System.IO.StreamReader(@"data/missiles.dat", Encoding.UTF8);
            r = reader.ReadToEnd();
            reader.Close();
            lines = r.Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length != 0 && lines[i].Substring(0,1) != "#")
                    missileTypes.Add(new missileType(lines[i].Split(',')));
            }

            reader = new System.IO.StreamReader(@"data/towers.dat", Encoding.UTF8);
            r = reader.ReadToEnd();
            reader.Close();
            lines = r.Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length != 0 && lines[i].Substring(0, 1) != "#")
                    towerTypes.Add(new towerType(lines[i].Split(',')));
            }
           
            // load levels
           
            reader = new System.IO.StreamReader(@"data/levels.dat");
            r = reader.ReadToEnd();
            reader.Close();
            levels = r.Split('\n');

            // set up Icons
           
            Point iconLoc = new Point();
           
            for (int i = 0; i < towerTypes.Count; i++)
            {
                icons.Add(new PictureBox());
                icons[i].BackColor = controlBGColour;
                icons[i].SizeMode = PictureBoxSizeMode.Zoom;
                icons[i].Image = towerTypes[i].turretImg.imgs[0];
                iconLoc.X = 150 + (int)Math.Floor(i / 2.0) * 48;
                icons[i].Visible = true;
                icons[i].Click += new EventHandler(IconPress);
                if ((float)Math.Floor(i / 2.0) != (float)(i / 2.0))
                    iconLoc.Y = 454;
                else
                    iconLoc.Y = 408;
                icons[i].Location = iconLoc;
                icons[i].Tag = i;
                icons[i].Size = new Size(40, 40);
                icons[i].MouseHover += new EventHandler(IconEnter);
                icons[i].MouseLeave += new EventHandler(IconLeave);
                Controls.Add(icons[i]);
                icons[i].BringToFront();
                icons[i].Refresh();
            }
           
            // close reader
           
            reader.Close();

            // Draw everything...

            drawBG();
            draw();

        }

        public float notZero(float value)
        {
                if (value == 0)
                        return 0.01f;
                else
                        return value;
        }
       
        public void draw()
        {
               
                for (int i = 0; i < icons.Count; i++)
                {
                        if (cash < towerTypes[i].cost)
                                icons[i].BackgroundImage = noImg;
                        else if (selTowerType == i)
                                icons[i].BackgroundImage = selImg;
                        else
                                icons[i].BackgroundImage = yesImg;
                }
               
                cashF.Text = cashA[lang] + ": " + cash.ToString();
                livesF.Text = lives.ToString() + " " + livesA[lang];
                levelF.Text = levelA[lang] + ": " + level.ToString();

            Bitmap img = new Bitmap(500, 400);
            Graphics g = Graphics.FromImage(img);
                        PointF[] points;
       
            // draw towers
            Image baseImg, turretImg;
            for (int i = 0; i < towers.Count; i++)
            {
                baseImg = getBaseImg(i);
                turretImg = getTurretImg(i);
                if (towers[i].fireing && towers[i].delayTime == towerTypes[towers[i].type].delay && towerTypes[towers[i].type].laserColour != null && towers[i].target != -1)
                {
                        switch (towerTypes[towers[i].type].laserType)
                        {
                                case (0):
                                        {
                                g.DrawLine(new Pen(towerTypes[towers[i].type].laserColour, 3), (PointF)towers[i].loc, enemies[towers[i].target].loc);
                                break;
                                        }
                                case (1):
                        {
                                        //laser
                                        points = new PointF[getDist(towers[i].loc, FtoP(enemies[towers[i].target].loc)) / 50 + 3];
                                                points[0] = enemies[towers[i].target].loc;
                                                        points[points.Length - 1] = towers[i].loc;
                                                for (int j = 1; j < points.Length - 1; j++)
                                                        points[j] = new PointF(enemies[towers[i].target].loc.X + notZero(towers[i].loc.X - (int)enemies[towers[i].target].loc.X) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4), enemies[towers[i].target].loc.Y + notZero(towers[i].loc.Y - (int)enemies[towers[i].target].loc.Y) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4));
                                                g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 3), points);
                                                if (extraPretty)
                                                {
                                                        for (int j = 0; j < 3; j++)
                                                                g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 1), rndmisePoints(points, true));
                                                }
                                                break;
                        }
                                case (2):
                        {
                                        //initialLaser
                                        points = new PointF[getDist(towers[i].loc, FtoP(enemies[towers[i].target].loc)) / 50 + 3];
                                                points[0] = enemies[towers[i].target].loc;
                                                        points[points.Length - 1] = towers[i].loc;
                                                for (int j = 1; j < points.Length - 1; j++)
                                                        points[j] = new PointF(enemies[towers[i].target].loc.X + notZero(towers[i].loc.X - (int)enemies[towers[i].target].loc.X) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4), enemies[towers[i].target].loc.Y + notZero(towers[i].loc.Y - (int)enemies[towers[i].target].loc.Y) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4));
                                                g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 3), points);
                                                if (extraPretty)
                                                {
                                                        for (int j = 0; j < 3; j++)
                                                                g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 1), rndmisePoints(points, true));
                                                }
                                        //furtherLasers
                                        for (int r = 1; r < towers[i].targets.Count; r++)
                                        {
                                                points = new PointF[getDist(towers[i].loc, FtoP(enemies[towers[i].targets[r]].loc)) / 50 + 3];
                                                points[0] = enemies[towers[i].targets[r]].loc;
                                                                points[points.Length - 1] = enemies[towers[i].targets[r - 1]].loc;
                                                        for (int j = 1; j < points.Length - 1; j++)
                                                                points[j] = new PointF(enemies[towers[i].targets[r]].loc.X + notZero(enemies[towers[i].targets[r - 1]].loc.X - (int)enemies[towers[i].targets[r]].loc.X) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4), enemies[towers[i].targets[r]].loc.Y + notZero(enemies[towers[i].targets[r - 1]].loc.Y - (int)enemies[towers[i].targets[r]].loc.Y) / points.Length * j + rnd.Next(-points.Length - 4, points.Length + 4));
                                                        g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 3), points);
                                                        if (extraPretty)
                                                        {
                                                                for (int j = 0; j < 3; j++)
                                                                        g.DrawLines(new Pen(towerTypes[towers[i].type].laserColour, 1), rndmisePoints(points, true));
                                                        }
                                        }
                                                break;
                        }
                        }
                }
                                 
                g.TranslateTransform(towers[i].loc.X, towers[i].loc.Y);
                if (energyBars)
                {
                        if (towers[i].fireing)
                                g.FillRectangle(Brushes.Maroon, (int)(-turretImg.Width / 2), (int)(-turretImg.Height / 2) - 5, (int)(towers[i].energy / towerTypes[towers[i].type].maxEnergy * turretImg.Width), 3);
                        else if (towers[i].energy < towerTypes[towers[i].type].req)
                                g.FillRectangle(Brushes.Green, (int)(-turretImg.Width / 2), (int)(-turretImg.Height / 2) - 5, (int)(towers[i].energy / towerTypes[towers[i].type].maxEnergy * turretImg.Width), 3);
                        else
                                g.FillRectangle(Brushes.LawnGreen, (int)(-turretImg.Width / 2), (int)(-turretImg.Height / 2) - 5, (int)(towers[i].energy / towerTypes[towers[i].type].maxEnergy * turretImg.Width), 3);
                }
                g.RotateTransform(towers[i].angle);
                g.DrawImage(turretImg, (int)(-turretImg.Width / 2), (int)(-turretImg.Height / 2));
                g.ResetTransform();
            }

            // draw enemies
            for (int i = 0; i < enemies.Count; i++)
            {
                g.TranslateTransform(enemies[i].loc.X, enemies[i].loc.Y);
                g.RotateTransform(enemies[i].angle);
                g.DrawImage(getEnemyImg(i), (int)(-getEnemyImg(i).Width / 2), (int)(-getEnemyImg(i).Height / 2));
                g.ResetTransform();
            }

            //draw smoke
            for (int i = 0; i < smokes.Count; i++)
            {
                g.FillEllipse(new SolidBrush(Color.FromArgb(100, smokes[i].colour.R, smokes[i].colour.B, smokes[i].colour.G)), smokes[i].loc.X - (int)(smokes[i].time / 5), smokes[i].loc.Y - (int)(smokes[i].time / 5), smokes[i].time, smokes[i].time);
            }
           
            //draw energy flux!!
            for (int i  = 0; i < towers.Count; i++)
            {
                if (towers[i].fireing && towers[i].delayTime == towerTypes[towers[i].type].delay && towerTypes[towers[i].type].laserColour != null && towers[i].target != -1)
                {
                    g.FillEllipse(new SolidBrush(Color.FromArgb((int)(towers[i].glow / towerTypes[towers[i].type].maxEnergy * 100), towerTypes[towers[i].type].laserColour.R, towerTypes[towers[i].type].laserColour.B, towerTypes[towers[i].type].laserColour.G)), (int)(towers[i].loc.X - towers[i].glow / 2), (int)(towers[i].loc.Y - towers[i].glow / 2), towers[i].glow, towers[i].glow);
                }
            }

            Font font1 = new Font(FontFamily.GenericMonospace, 10, FontStyle.Regular, GraphicsUnit.Pixel);
                       
                        StringFormat sf = new StringFormat();
                        sf.Alignment = StringAlignment.Center;
                       
            // Texts
            if (lives <= 0)
                g.DrawString("You Loose!\nHAHAHA!", new Font(FontFamily.GenericMonospace, 40, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(controlFGColour), 250, 200, sf);
           
            if (detailText != "" && enemies.Count == 0)
                    g.DrawString(textWrap(font1, detailText, 450), font1, new SolidBrush(controlFGColour), 250, 400 - TextRenderer.MeasureText(textWrap(font1, detailText, 450), font1).Height, sf);
           
            if (showTotalOfEngery)
                g.DrawString(energyTotal().ToString(), font1, new SolidBrush(controlFGColour), 10, 10);
           
            // Finals
            view.Image = (Image)img.Clone();
            g.Dispose();
            img.Dispose();

            cashF.Refresh();
            livesF.Refresh();
            levelF.Refresh();
            view.Refresh();

        }
       
        public PointF[] rndmisePoints(PointF[] oldPoints, bool ignoreStartAndEnd)
        {
                PointF[] newPoints = oldPoints;
                if (ignoreStartAndEnd)
                {
                        for (int i = 1; i < newPoints.Length - 1; i++)
                                newPoints[i] = new PointF(oldPoints[i].X + (float)rnd.Next(-5, 6), oldPoints[i].Y + (float)rnd.Next(-5, 6));
                }
                else
                {
                        for (int i = 0; i < newPoints.Length; i++)
                                newPoints[i] = new PointF(oldPoints[i].X + (float)rnd.Next(-5, 6), oldPoints[i].Y + (float)rnd.Next(-5, 6));
                }
                return newPoints;
        }
       
        public string textWrap(Font font, string textN, int width)
        {
                string text = textN;
                int lastSpace = 1;
                for (int i = 1; i < text.Length; i++)
                {
                        if (text.Substring(i, 1) == " ")
                                lastSpace = i;
                        if (TextRenderer.MeasureText(text.Substring(0, i), font).Width > width)
                                text = text.Substring(0, lastSpace) + "\n" + text.Substring(lastSpace + 1);
                }
                return text;
        }
       
        public void drawBG()
        {

            Bitmap img = new Bitmap(500, 400);
            Graphics g = Graphics.FromImage(img);

            g.DrawImage(bgImg, 0, 0);

            Image baseImg;
            for (int i = 0; i < towers.Count; i++)
            {
                baseImg = getBaseImg(i);
                g.TranslateTransform(towers[i].loc.X, towers[i].loc.Y);
                g.DrawImage(baseImg, (int)(-baseImg.Width / 2), (int)(-baseImg.Height / 2));
                if (rangeRings)
                        g.DrawEllipse(new Pen(towerTypes[towers[i].type].laserColour, 3), -towerTypes[towers[i].type].range, -towerTypes[towers[i].type].range, towerTypes[towers[i].type].range * 2, towerTypes[towers[i].type].range * 2);
                g.ResetTransform();
            }

            view.BackgroundImage = (Image)img.Clone();
            g.Dispose();
            img.Dispose();

        }

        private void view_MouseClick(object sender, MouseEventArgs e)
        {
                if (e.Button == MouseButtons.Left)
                   {
                    if (cash >= towerTypes[selTowerType].cost)
                    {
                                for (int i = 0; i < towers.Count; i++)
                                {
                                        if (getDist(towers[i].loc, e.Location) < Math.Max(towerTypes[towers[i].type].baseImg.imgs[0].Width, towerTypes[towers[i].type].baseImg.imgs[0].Width) / 2 + Math.Max(towerTypes[selTowerType].baseImg.imgs[0].Width, towerTypes[selTowerType].baseImg.imgs[0].Width) / 2)
                                        {
                                        return;
                                        }
                                }
                        cash -= towerTypes[selTowerType].cost;
                        towers.Add(new tower(selTowerType, e.Location, towerTypes[selTowerType].sound));
                        drawBG();
                        draw();
                    }
                }
                else
                {
                        for (int i = 0; i < towers.Count; i++)
                        {
                                if (getDist(towers[i].loc, e.Location) < Math.Min(towerTypes[towers[i].type].baseImg.imgs[0].Width, towerTypes[towers[i].type].baseImg.imgs[0].Width) / 2)
                                {
                                        cash += (int)(towerTypes[towers[i].type].cost / 2);
                                        towers.RemoveAt(i);
                                        drawBG();
                                        draw();
                                        return;
                                }
                        }
                }
        }

        float getAngle(Point a, Point b)
        {
            if (a.X == b.X)
            {
                if (a.Y < b.Y)
                    return 90;
                else
                    return 270;
            }
            else if (a.Y == b.Y)
            {
                if (a.X < b.X)
                    return 0;
                else
                    return 180;
            }
            float output;
            output = (float)(Math.Atan((b.Y - a.Y) / (float)(b.X - a.X)) / Math.PI * 180.0f);
            if (a.X >= b.X)
                output += 180;
            if (output > 360)
                output -= 360;
            return output;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if (enemies.Count == 0)
                newRun();
        }

        public void initMove(int num)
        {
            enemies[num].dX = (float)Math.Cos(enemies[num].angle / 180 * Math.PI) * enemyTypes[enemies[num].type].speed;
            enemies[num].dY = (float)Math.Sin(enemies[num].angle / 180 * Math.PI) * enemyTypes[enemies[num].type].speed;
        }
       
        public void move(int num)
        {
                enemies[num].loc.X += enemies[num].dX;
                enemies[num].loc.Y += enemies[num].dY;
        }

        public void reTarget(int num)
        {
                bool res;
                int tempEn;
                if (towers[num].target != -1)
                {
                        tempEn = towers[num].target;
                        towers[num].targets.Clear();
                        towers[num].target = tempEn;
                }
                else
                towers[num].targets.Clear();
                int start = rnd.Next(0, enemies.Count - 1);
                int i;
                for (int inc = 0; inc < enemies.Count; inc++)
            {
                        i = inc + start;
                        if (i >= enemies.Count)
                                i -= enemies.Count;
                if (towerTypes[towers[num].type].laserType == 2 && towers[num].target != -1)
                        res = enemies[i].loc.X >= 0 && getDist(FtoP(enemies[towers[num].targets[towers[num].targets.Count - 1]].loc), FtoP(enemies[i].loc)) <= towerTypes[towers[num].type].range && enemies[i].health > 0;
                else
                        res = enemies[i].loc.X >= 0 && getDist(towers[num].loc, FtoP(enemies[i].loc)) <= towerTypes[towers[num].type].range && enemies[i].health > 0;
                if (res)
                {
                        if (towerTypes[towers[num].type].laserType == 2)
                        {
                                if (!towers[num].targets.Contains(i) || rnd.Next(0,2) == 0)
                                        towers[num].targets.Add(i);
                                if (rnd.Next(0, towerTypes[towers[num].type].killNum) == 0)
                                                return;
                        }
                        else
                        {
                        towers[num].target = i;
                        return;
                        }
                }
            }
                // no target found
            if (towerTypes[towers[num].type].laserType != 2)
                towers[num].target = -1;
        }
       
        public void reAngle(int num)
        {
                if (towers[num].target != -1)
                towers[num].angle = (float)getAngle(towers[num].loc, new Point((int)enemies[towers[num].target].loc.X, (int)enemies[towers[num].target].loc.Y));
        }
       
        public void fire(int num, bool fireing)
        {
                towers[num].fireing = fireing;
//              towers[num].s.controls.stop();
//              if (sound && fireing)
//              {
//                      if (towers[num].s.playState != WMPLib.WMPPlayState.wmppsPlaying)
//                              towers[num].s.controls.play();
//              }
        }

        public Point FtoP(PointF point)
        {
            return new Point((int)point.X, (int)point.Y);
        }

        public int getDist(Point a, Point b)
        {
            return (int)Math.Sqrt(Math.Abs((a.X - b.X) * (a.X - b.X)) + Math.Abs((a.Y - b.Y) * (a.Y - b.Y)));
        }
       
        void IconPress(object sender, EventArgs e)
        {
                PictureBox icon = (PictureBox)sender;
                if (towerTypes[(int)icon.Tag].cost <= cash)
                {
                        selTowerType = (int)icon.Tag;
                        draw();
                }
        }
       
        void IconEnter(object sender, EventArgs e)
        {
                PictureBox icon = (PictureBox)sender;
                if (towerTypes[(int)icon.Tag].laserType != -1)
                        detailText = towerTypes[(int)icon.Tag].name + " - €" + towerTypes[(int)icon.Tag].cost + " - " + laserTypeLookup[towerTypes[(int)icon.Tag].laserType] + "\n" + towerTypes[(int)icon.Tag].details[lang];
//              else
//                      detailText = towerTypes[(int)icon.Tag].name + " - €" + towerTypes[(int)icon.Tag].cost + " - MType\n" + towerTypes[(int)icon.Tag].details;
                        draw();
        }
       
        void IconLeave(object sender, EventArgs e)
        {
                detailText = "";
                draw();
        }
       
        void Form1KeyDown(object sender, KeyEventArgs e)
        {
                switch (e.KeyCode)
                {
                        case Keys.Back:
                                cash += 1000;
                                break;
                        case Keys.Space:
                                energyBars = !energyBars;
                                break;
                        case Keys.Enter:
                            if (enemies.Count == 0)
                                        newRun();
                                break;
                        case Keys.Tab:
                                autoRun = !autoRun;
                                if (autoRun)
                                        goF.BackgroundImage = noImg;
                                else
                                        goF.BackgroundImage = yesImg;
                                break;
                        case Keys.F8:
                                level++;
                                if (level >= levels.Length)
                                        level = 0;
                                break;
                        case Keys.R:
                                rangeRings = !rangeRings;
                                drawBG();
                                break;
                        case Keys.F4:
                                timer1.Enabled = !timer1.Enabled;
                                break;
                        case Keys.E:
                                extraPretty = !extraPretty;
                                break;
                        case Keys.T:
                                showTotalOfEngery = !showTotalOfEngery;
                                break;
//                      case Keys.S:
//                              sound = !sound;
//                              break;
                        default:
                                if (e.KeyCode.ToString().Length > 1)
                                {
                                        int res;
                                        if (int.TryParse(e.KeyCode.ToString().Substring(1, 1), out res))
                                        {
                                                if (res < towerTypes.Count)
                                                {
                                                        if (cash >= towerTypes[res].cost)
                                                                selTowerType = res;
                                                }
                                        }
                                }
                                break;
                }
                draw();
               
        }

        void Form1FormClosing(object sender, FormClosingEventArgs e)
        {
                autoRun = false;
                Form2 menu = new Form2();
                menu.Show();
        }
       
        void Timer1Tick(object sender, EventArgs e)
        {
                this.Text = "Blockade! [" + (fCount * 2) + "FPS]";
                fCount = 0;
        }
       
        Image getBaseImg(int num)
        {
                if (towerTypes[towers[num].type].baseImg.maxRunTime < towers[num].baseTime)
                        towers[num].baseTime = 0;
                return towerTypes[towers[num].type].getBaseImg(towers[num].baseTime);
        }
       
        Image getTurretImg(int num)
        {
                if (towerTypes[towers[num].type].turretImg.maxRunTime < towers[num].turretTime)
                        towers[num].turretTime = 0;
                return towerTypes[towers[num].type].getTurretImg(towers[num].turretTime);
        }
       
        Image getEnemyImg(int num)
        {
                if (enemyTypes[enemies[num].type].img.maxRunTime < enemies[num].imgTime)
                        enemies[num].imgTime = 0;
                return enemyTypes[enemies[num].type].getImg(enemies[num].imgTime);
        }
       
        public double energyTotal()
        {
                double output = 0.0;
                for (int i = 0; i < towers.Count; i++)
                        output += towers[i].energy;
                return output;
        }
    }
}