public Derrick(Vector2 scroll, String[] flags)
            : base(scroll)
        {
            //Source sprite
            //Body
            this.sRect          = new Rectangle(0, 0, 400, 600);
            this.antennaSrcRect = new Rectangle(30, 725, 258, 270);
            this.Scale          = Vector2.One;

            this.ttl = InfiniteTimeToLive;

            //Stats
            this.wpn = null;
            this.go  = false;
            this.hp  = BodyHP;

            this.points = 182000;

            this.attackType     = DerrickAttacks.None;
            this.attackCooldown = 5000f;
            this.faceState      = DerrickFaceState.Normal;

            this.flagsOnDeath        = flags;
            this.Flip                = SpriteEffects.None;
            this.InfiniteMovePattern = true;
            this.hitbox              = new EmptyHitbox(this);

            this.speed   = new Vector2(0f, 140.0f);
            this.Pattern = new MovePattern();
            this.Pattern.AddPoint((int)location.X + dRect.Width / 2, 0);

            this.DrawWarning = true;

            this.initializeY = false;
            this.deltaX      = 0;

            this.Removable  = false;
            this.drawPoster = false;
            this.alarmColor = 0.0f;
            this.alarmDelta = 0.05f;

            this.posterSrc   = new Rectangle(888, 202, 132, 100);
            this.posterDst   = this.posterSrc;
            this.posterDst.X = 123;
            this.posterDst.Y = 176;
        }
        public override void Update(GameTime gameTime)
        {
            bool attack = go;

            if (this.hp <= 0)
            {
                //Add smoke
                Vector2 smokeLoc = new Vector2(this.dRect.Left + 175, this.dRect.Top + 235);
                TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLoc
                                                                           , RandomMachine.GetRandomVector2(20f, 100f, -50f, -150f),
                                                                           1f, 1f, 1f, 1f, RandomMachine.GetRandomFloat(1.5f, 4.5f), RandomMachine.GetRandomInt(0, 4)), true);

                this.attackType = DerrickAttacks.None;
                this.wpn        = null;

                attack = false;
            }

            //Decrease cooldowns
            if (this.faceCooldown > 0f)
            {
                this.faceCooldown -= gameTime.ElapsedGameTime.TotalMilliseconds;
            }

            if (this.attackCooldown > 0f)
            {
                this.attackCooldown -= gameTime.ElapsedGameTime.TotalMilliseconds;
                attack = false;
            }

            //Change state is necessary
            if ((this.faceCooldown < 0f) && (this.faceState != DerrickFaceState.Normal))
            {
                this.faceState = DerrickFaceState.Normal;
            }

            //Boss is hit : change face
            if (IsHit)
            {
                this.faceState    = DerrickFaceState.Hit;
                this.faceCooldown = 2000f;
            }

            //Special updates
            //***************************************************************************
            //Only one of the pair has to be killed. If one die, we kill the other
            int brokenThingsCount = 0;

            if (leftEar.HP <= 0)
            {
                brokenThingsCount++;

                if (rightEar.HP > -999)
                {
                    rightEar.HP = -999;
                    rightEar.TodoOnDeath();
                    this.attackCooldown = 200f;
                    TGPAContext.Instance.AddBonus(new Bonus(Weapon.GetRandomWeapon().GetType().Name.ToString()));
                }
            }

            if (rightHand.HP <= 0)
            {
                brokenThingsCount++;

                if (leftHand.HP > -999)
                {
                    leftHand.HP = -999;
                    leftHand.TodoOnDeath();
                    this.attackCooldown = 200f;
                    TGPAContext.Instance.AddBonus(new Bonus("Life"));
                }
            }


            if (rightWheels.HP <= 0)
            {
                brokenThingsCount++;

                if (leftWheels.HP > -999)
                {
                    leftWheels.HP = -999;
                    leftWheels.TodoOnDeath();
                    this.attackCooldown = 250f;
                    TGPAContext.Instance.AddBonus(new Bonus(Weapon.GetRandomWeapon().GetType().Name.ToString()));
                }
            }

            if ((brokenThingsCount >= 2) && (hp > 0))
            {
                this.drawPoster = true;
                this.sRect.Y    = 600;
            }

            if ((brokenThingsCount >= 3) && (hp > 0))
            {
                this.alarmColor += this.alarmDelta;

                if ((this.alarmColor >= 2f) || (this.alarmColor < 0f))
                {
                    this.alarmDelta = -this.alarmDelta;
                }
            }

            //In case of charge : Each shot make Derrick go back a little
            if (this.attackType == DerrickAttacks.Charge)
            {
                this.Speed += new Vector2(30, 0);
            }

            //***************************************************************************

            //Find a new attack
            if (attack)
            {
                //Initialisation for combat
                if (this.attackType == DerrickAttacks.None)
                {
                    leftEar.InitPart();
                    rightHand.InitPart();
                    rightWheels.InitPart();
                    this.hitbox = new SquareHitbox(this, new Vector2(0.5f, 0.32f));
                }


                this.faceState    = DerrickFaceState.Attack;
                this.faceCooldown = 2000f;
                this.speed        = Vector2.Zero;
                this.movePattern  = null;
                this.Background   = true;
                int rand = RandomMachine.GetRandomInt(0, 8);
                this.deltaX         = 0;
                this.FiringLocation = Vector2.Zero;

                this.leftHand.Weapon  = null;
                this.rightHand.Weapon = null;

                //Launch charge !
                //****************************************************
                if (this.attackType == DerrickAttacks.ChargeWait)
                {
                    this.attackType     = DerrickAttacks.Charge;
                    this.attackCooldown = 2500f;
                    this.wpn            = null;

                    this.movePattern = new MovePattern();

                    if (leftEar.HP >= 0)
                    {
                        this.movePattern.AddPoint(new Point(300, (int)this.DstRect.Center.Y));
                        this.speed.X = 1;
                    }
                    else
                    {
                        this.movePattern.AddPoint(new Point(150, (int)this.DstRect.Center.Y));
                        this.speed.X = 20;
                    }

                    this.movePattern.AddPoint(new Point(850, (int)this.DstRect.Center.Y));

                    this.InfiniteMovePattern = true;
                    this.Background          = false;
                    this.wpn = new CarotteWaveLauncherWeapon(false);
                }
                else
                {
                    //Simple carottes Attack
                    //****************************************************
                    if ((rand < 2) && (rightHand.HP > 0))
                    {
                        this.attackType = DerrickAttacks.Carrote;
                        this.wpn        = null;

                        int p = RandomMachine.GetRandomInt(2, 5);
                        int d = (RandomMachine.GetRandomFloat(0, 1) > 0.5f) ? 1 : -1;

                        this.attackCooldown = p * 2500f;

                        this.rightHand.InitializeFire(p, d);
                        this.leftHand.InitializeFire(p, -1 * d);

                        this.leftHand.Weapon  = new CarotteLauncherWeapon(this.leftHand);
                        this.rightHand.Weapon = new CarotteLauncherWeapon(this.rightHand);
                    }
                    //Wave carottes (from behind) Attack
                    //****************************************************
                    else if (rand < 4)
                    {
                        this.attackType     = DerrickAttacks.CarotteWave;
                        this.attackCooldown = 1500f;

                        this.wpn = new CarotteWaveLauncherWeapon(true);

                        this.movePattern = new MovePattern();
                        this.movePattern.AddPoint(new Point(800, (int)this.DstRect.Center.Y));
                        this.movePattern.AddPoint(new Point(850, (int)this.DstRect.Center.Y));
                        this.Speed = RandomMachine.GetRandomVector2(0, 50, 0, 0);
                    }
                    //Charge !!!
                    //****************************************************
                    else if ((rand < 5) && (this.attackType != DerrickAttacks.Charge) && (this.rightWheels.HP > 0))
                    {
                        this.attackType     = DerrickAttacks.ChargeWait;
                        this.attackCooldown = 4000f;
                        this.deltaX         = 2;
                    }
                    //Laser (from ears) Attack
                    //****************************************************
                    else if ((rand >= 5) && (this.rightEar.HP > 0))
                    {
                        this.attackType     = DerrickAttacks.Laser;
                        this.attackCooldown = 2000f;
                        this.wpn            = new EarLaserWeapon();
                        this.FiringLocation = new Vector2(100, 280) + this.location;
                    }
                }
            }

            //Sprite updates
            //************************************************
            //Facial animation
            switch (this.faceState)
            {
            case DerrickFaceState.Normal:

                break;

            case DerrickFaceState.Attack:

                break;

            case DerrickFaceState.Hit:

                break;
            }

            //Updates part
            leftEar.Location = this.location + this.leftEarRelativeLoc + leftEar.SpriteOrigin;
            leftEar.Update(gameTime);

            rightEar.Location = this.location + this.rightEarRelativeLoc + rightEar.SpriteOrigin;
            rightEar.Update(gameTime);

            leftHand.Location = this.location + this.leftHandRelativeLoc + leftHand.SpriteOrigin;
            leftHand.Update(gameTime);

            rightHand.Location = this.location + this.rightHandRelativeLoc + rightHand.SpriteOrigin;
            rightHand.Update(gameTime);

            leftWheels.Location = this.location + this.leftWheelsRelativeLoc;
            leftWheels.Update(gameTime);

            rightWheels.Location = this.location + this.rightWheelsRelativeLoc;
            rightWheels.Update(gameTime);

            //First thing : boss come from the ground
            if ((location.Y < (TGPAContext.Instance.ScreenHeight - dRect.Height)) && !go)
            {
                this.go      = true;
                this.speed   = Vector2.Zero;
                this.Pattern = null;
            }
            else if (!go)
            {
                if (!this.initializeY)
                {
                    this.deltaX      = -1;
                    this.location.Y += rightEar.DstRect.Height;
                    this.initializeY = true;
                }

                this.location.X = TGPAContext.Instance.ScreenWidth - this.dRect.Width;
                deltaX          = -deltaX;

                for (int i = 7; i <= 15; i++)
                {
                    Vector2 smokeLoc = new Vector2(i * TGPAContext.Instance.ScreenWidth / 15, TGPAContext.Instance.ScreenHeight);

                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLoc, RandomMachine.GetRandomVector2(-5f, 5f, -10f, 10f),
                                                                               0.70f, 0.70f, 0.70f, 1f,
                                                                               RandomMachine.GetRandomFloat(0.5f, 2.0f),
                                                                               RandomMachine.GetRandomInt(0, 4)), true);
                }
            }

            this.displayedLocation = location;

            //Shake shake shake
            //****************************************************************
            if (deltaX != 0)
            {
                this.displayedLocation.X += deltaX;
                TGPAContext.Instance.Player1.SetRumble(new Vector2(1.0f, 1.0f));
                if (TGPAContext.Instance.Player2 != null)
                {
                    TGPAContext.Instance.Player2.SetRumble(new Vector2(1.0f, 1.0f));
                }

                this.leftEar.Shake(deltaX);
                this.rightEar.Shake(deltaX);
                this.leftHand.Shake(deltaX);
                this.rightHand.Shake(deltaX);
            }

            //Need to update before changing manually dstRect.X value
            //Hack : Stop displaying lifebar...
            base.Update(gameTime);

            this.dRect.X = (int)this.displayedLocation.X;
            //****************************************************************

            //Smoke
            if ((this.attackType == DerrickAttacks.Charge) || (this.attackType == DerrickAttacks.ChargeWait))
            {
                Vector2 smokeLocBehind = this.displayedLocation + new Vector2(370, 245);

                for (int i = 0; i < 4; i++)
                {
                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLocBehind, RandomMachine.GetRandomVector2(10f, 75f, 10f, 40f),
                                                                               0.10f, 0.10f, 0.10f, 1f,
                                                                               RandomMachine.GetRandomFloat(1f, 4.0f),
                                                                               RandomMachine.GetRandomInt(0, 4)), true);
                }

                Vector2 smokeLocBis = this.displayedLocation + new Vector2(70, 255);

                for (int i = 0; i < 4; i++)
                {
                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLocBis, RandomMachine.GetRandomVector2(10f, 75f, 10f, 40f),
                                                                               0.10f, 0.10f, 0.10f, 1f,
                                                                               RandomMachine.GetRandomFloat(1f, 4.0f),
                                                                               RandomMachine.GetRandomInt(0, 4)), false);
                }
            }
        }
        public Derrick(Vector2 scroll, String[] flags)
            : base(scroll)
        {
            //Source sprite
            //Body
            this.sRect = new Rectangle(0, 0, 400, 600);
            this.antennaSrcRect = new Rectangle(30, 725, 258, 270);
            this.Scale = Vector2.One;

            this.ttl = InfiniteTimeToLive;

            //Stats
            this.wpn = null;
            this.go = false;
            this.hp = BodyHP;

            this.points = 182000;

            this.attackType = DerrickAttacks.None;
            this.attackCooldown = 5000f;
            this.faceState = DerrickFaceState.Normal;

            this.flagsOnDeath = flags;
            this.Flip = SpriteEffects.None;
            this.InfiniteMovePattern = true;
            this.hitbox = new EmptyHitbox(this);

            this.speed = new Vector2(0f, 140.0f);
            this.Pattern = new MovePattern();
            this.Pattern.AddPoint((int)location.X + dRect.Width / 2, 0);

            this.DrawWarning = true;

            this.initializeY = false;
            this.deltaX = 0;

            this.Removable = false;
            this.drawPoster = false;
            this.alarmColor = 0.0f;
            this.alarmDelta = 0.05f;

            this.posterSrc = new Rectangle(888,202,132,100);
            this.posterDst = this.posterSrc;
            this.posterDst.X = 123;
            this.posterDst.Y = 176;
        }
        public override void Update(GameTime gameTime)
        {
            bool attack = go;

            if (this.hp <= 0)
            {
                //Add smoke
                Vector2 smokeLoc = new Vector2(this.dRect.Left + 175, this.dRect.Top + 235);
                TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLoc
                    , RandomMachine.GetRandomVector2(20f, 100f, -50f, -150f),
            1f, 1f, 1f, 1f, RandomMachine.GetRandomFloat(1.5f, 4.5f), RandomMachine.GetRandomInt(0, 4)), true);

                this.attackType = DerrickAttacks.None;
                this.wpn = null;

                attack = false;
            }

            //Decrease cooldowns
            if (this.faceCooldown > 0f)
            {
                this.faceCooldown -= gameTime.ElapsedGameTime.TotalMilliseconds;
            }

            if (this.attackCooldown > 0f)
            {
                this.attackCooldown -= gameTime.ElapsedGameTime.TotalMilliseconds;
                attack = false;
            }

            //Change state is necessary
            if ((this.faceCooldown < 0f) && (this.faceState != DerrickFaceState.Normal))
            {
                this.faceState = DerrickFaceState.Normal;
            }

            //Boss is hit : change face
            if (IsHit)
            {
                this.faceState = DerrickFaceState.Hit;
                this.faceCooldown = 2000f;
            }

            //Special updates
            //***************************************************************************
            //Only one of the pair has to be killed. If one die, we kill the other
            int brokenThingsCount = 0;

            if (leftEar.HP <= 0)
            {
                brokenThingsCount++;

                if (rightEar.HP > -999)
                {
                    rightEar.HP = -999;
                    rightEar.TodoOnDeath();
                    this.attackCooldown = 200f;
                    TGPAContext.Instance.AddBonus(new Bonus(Weapon.GetRandomWeapon().GetType().Name.ToString()));
                }
            }

            if (rightHand.HP <= 0)
            {
                brokenThingsCount++;

                if (leftHand.HP > -999)
                {
                    leftHand.HP = -999;
                    leftHand.TodoOnDeath();
                    this.attackCooldown = 200f;
                    TGPAContext.Instance.AddBonus(new Bonus("Life"));
                }
            }

            if (rightWheels.HP <= 0)
            {
                brokenThingsCount++;

                if (leftWheels.HP > -999)
                {
                    leftWheels.HP = -999;
                    leftWheels.TodoOnDeath();
                    this.attackCooldown = 250f;
                    TGPAContext.Instance.AddBonus(new Bonus(Weapon.GetRandomWeapon().GetType().Name.ToString()));
                }
            }

            if ((brokenThingsCount >= 2) && (hp > 0))
            {
                this.drawPoster = true;
                this.sRect.Y = 600;
            }

            if ((brokenThingsCount >= 3) && (hp > 0))
            {
                this.alarmColor += this.alarmDelta;

                if ((this.alarmColor >= 2f) || (this.alarmColor < 0f))
                {
                    this.alarmDelta = -this.alarmDelta;
                }
            }

            //In case of charge : Each shot make Derrick go back a little
            if (this.attackType == DerrickAttacks.Charge)
            {
                this.Speed += new Vector2(30, 0);
            }

            //***************************************************************************

            //Find a new attack
            if (attack)
            {
                //Initialisation for combat
                if (this.attackType == DerrickAttacks.None)
                {
                    leftEar.InitPart();
                    rightHand.InitPart();
                    rightWheels.InitPart();
                    this.hitbox = new SquareHitbox(this, new Vector2(0.5f, 0.32f));
                }

                this.faceState = DerrickFaceState.Attack;
                this.faceCooldown = 2000f;
                this.speed = Vector2.Zero;
                this.movePattern = null;
                this.Background = true;
                int rand = RandomMachine.GetRandomInt(0, 8);
                this.deltaX = 0;
                this.FiringLocation = Vector2.Zero;

                this.leftHand.Weapon = null;
                this.rightHand.Weapon = null;

                //Launch charge !
                //****************************************************
                if (this.attackType == DerrickAttacks.ChargeWait)
                {
                    this.attackType = DerrickAttacks.Charge;
                    this.attackCooldown = 2500f;
                    this.wpn = null;

                    this.movePattern = new MovePattern();

                    if (leftEar.HP >= 0)
                    {
                        this.movePattern.AddPoint(new Point(300, (int)this.DstRect.Center.Y));
                        this.speed.X = 1;
                    }
                    else
                    {
                        this.movePattern.AddPoint(new Point(150, (int)this.DstRect.Center.Y));
                        this.speed.X = 20;
                    }

                    this.movePattern.AddPoint(new Point(850, (int)this.DstRect.Center.Y));

                    this.InfiniteMovePattern = true;
                    this.Background = false;
                    this.wpn = new CarotteWaveLauncherWeapon(false);
                }
                else
                {
                    //Simple carottes Attack
                    //****************************************************
                    if ((rand < 2) && (rightHand.HP > 0))
                    {
                        this.attackType = DerrickAttacks.Carrote;
                        this.wpn = null;

                        int p = RandomMachine.GetRandomInt(2, 5);
                        int d = (RandomMachine.GetRandomFloat(0, 1) > 0.5f) ? 1 : -1;

                        this.attackCooldown = p * 2500f;

                        this.rightHand.InitializeFire(p, d);
                        this.leftHand.InitializeFire(p, -1 * d);

                        this.leftHand.Weapon = new CarotteLauncherWeapon(this.leftHand);
                        this.rightHand.Weapon = new CarotteLauncherWeapon(this.rightHand);
                    }
                    //Wave carottes (from behind) Attack
                    //****************************************************
                    else if (rand < 4)
                    {
                        this.attackType = DerrickAttacks.CarotteWave;
                        this.attackCooldown = 1500f;

                        this.wpn = new CarotteWaveLauncherWeapon(true);

                        this.movePattern = new MovePattern();
                        this.movePattern.AddPoint(new Point(800, (int)this.DstRect.Center.Y));
                        this.movePattern.AddPoint(new Point(850, (int)this.DstRect.Center.Y));
                        this.Speed = RandomMachine.GetRandomVector2(0, 50, 0, 0);
                    }
                    //Charge !!!
                    //****************************************************
                    else if ((rand < 5) && (this.attackType != DerrickAttacks.Charge) && (this.rightWheels.HP > 0))
                    {
                        this.attackType = DerrickAttacks.ChargeWait;
                        this.attackCooldown = 4000f;
                        this.deltaX = 2;
                    }
                    //Laser (from ears) Attack
                    //****************************************************
                    else if ((rand >= 5) && (this.rightEar.HP > 0))
                    {
                        this.attackType = DerrickAttacks.Laser;
                        this.attackCooldown = 2000f;
                        this.wpn = new EarLaserWeapon();
                        this.FiringLocation = new Vector2(100, 280) + this.location;
                    }
                }
            }

            //Sprite updates
            //************************************************
            //Facial animation
            switch (this.faceState)
            {
                case DerrickFaceState.Normal:

                    break;

                case DerrickFaceState.Attack:

                    break;

                case DerrickFaceState.Hit:

                    break;
            }

            //Updates part
            leftEar.Location = this.location + this.leftEarRelativeLoc + leftEar.SpriteOrigin;
            leftEar.Update(gameTime);

            rightEar.Location = this.location + this.rightEarRelativeLoc + rightEar.SpriteOrigin;
            rightEar.Update(gameTime);

            leftHand.Location = this.location + this.leftHandRelativeLoc + leftHand.SpriteOrigin;
            leftHand.Update(gameTime);

            rightHand.Location = this.location + this.rightHandRelativeLoc + rightHand.SpriteOrigin;
            rightHand.Update(gameTime);

            leftWheels.Location = this.location + this.leftWheelsRelativeLoc;
            leftWheels.Update(gameTime);

            rightWheels.Location = this.location + this.rightWheelsRelativeLoc;
            rightWheels.Update(gameTime);

            //First thing : boss come from the ground
            if ((location.Y < (TGPAContext.Instance.ScreenHeight - dRect.Height)) && !go)
            {
                this.go = true;
                this.speed = Vector2.Zero;
                this.Pattern = null;
            }
            else if (!go)
            {
                if (!this.initializeY)
                {
                    this.deltaX = -1;
                    this.location.Y += rightEar.DstRect.Height;
                    this.initializeY = true;
                }

                this.location.X = TGPAContext.Instance.ScreenWidth - this.dRect.Width;
                deltaX = -deltaX;

                for (int i = 7; i <= 15; i++)
                {
                    Vector2 smokeLoc = new Vector2(i * TGPAContext.Instance.ScreenWidth / 15, TGPAContext.Instance.ScreenHeight);

                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLoc, RandomMachine.GetRandomVector2(-5f, 5f, -10f, 10f),
            0.70f, 0.70f, 0.70f, 1f,
            RandomMachine.GetRandomFloat(0.5f, 2.0f),
            RandomMachine.GetRandomInt(0, 4)), true);
                }
            }

            this.displayedLocation = location;

            //Shake shake shake
            //****************************************************************
            if (deltaX != 0)
            {
                this.displayedLocation.X += deltaX;
                TGPAContext.Instance.Player1.SetRumble(new Vector2(1.0f, 1.0f));
                if (TGPAContext.Instance.Player2 != null)
                {
                    TGPAContext.Instance.Player2.SetRumble(new Vector2(1.0f, 1.0f));
                }

                this.leftEar.Shake(deltaX);
                this.rightEar.Shake(deltaX);
                this.leftHand.Shake(deltaX);
                this.rightHand.Shake(deltaX);
            }

            //Need to update before changing manually dstRect.X value
            //Hack : Stop displaying lifebar...
            base.Update(gameTime);

            this.dRect.X = (int)this.displayedLocation.X;
            //****************************************************************

            //Smoke
            if ((this.attackType == DerrickAttacks.Charge) || (this.attackType == DerrickAttacks.ChargeWait))
            {
                Vector2 smokeLocBehind = this.displayedLocation + new Vector2(370, 245);

                for (int i = 0; i < 4; i++)
                {
                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLocBehind, RandomMachine.GetRandomVector2(10f, 75f, 10f, 40f),
                        0.10f, 0.10f, 0.10f, 1f,
                        RandomMachine.GetRandomFloat(1f, 4.0f),
                        RandomMachine.GetRandomInt(0, 4)), true);
                }

                Vector2 smokeLocBis = this.displayedLocation + new Vector2(70, 255);

                for (int i = 0; i < 4; i++)
                {
                    TGPAContext.Instance.ParticleManager.AddParticle(new Smoke(smokeLocBis, RandomMachine.GetRandomVector2(10f, 75f, 10f, 40f),
                        0.10f, 0.10f, 0.10f, 1f,
                        RandomMachine.GetRandomFloat(1f, 4.0f),
                        RandomMachine.GetRandomInt(0, 4)), false);
                }
            }
        }