Click here to Skip to main content
11,721,289 members (81,308 online)
Click here to Skip to main content
Add your own
alternative version

Sprite Editor for .NET

, 27 Jan 2010 CPOL 74.3K 9.2K 153
Build, edit, and animate your own sprites.
classSprite_C_2008.zip
classSprite
classSprite
classSprite.csproj.user
bin
Release
classSprite.dll
Properties
GraphicsEditor_C_2008.zip
GraphicsEditor CSharp
GraphicsEditor CSharp
graphics editor icon.ico
GraphicsEditor CSharp.csproj.user
Properties
Settings.settings
Resources
Brush_Icon.bmp
click to load image.bmp
colorTemplate.bmp
cursor_cross.bmp
cursor_move.bmp
cursor_resizeDiagonal_BL_TR.bmp
cursor_resizeDiagonal_TL_BR.bmp
cursor_resizeLeftRight.bmp
cursor_resizeUpDown.bmp
Edit_Redo_Icon.bmp
Edit_Undo_Icon.bmp
Eraser_Icon.bmp
FloodFill_Icon.bmp
FloodFill_pnlBackground_sameColor.bmp
FloodFill_pnlBackground_toBorder.bmp
Free-Form Select_Icon.bmp
Gun.bmp
Line_Icon.bmp
Magnify_Icon.bmp
Pencil_Icon.bmp
Pick-color_Icon.bmp
Select_Icon.bmp
sprite Editor.jpg
Straighten_Icon.bmp
Night_Stalker__C_2008.zip
Night Stalker
Night Stalker
Night Stalker.csproj.user
nightstalker.ico
Properties
Settings.settings
Resources
bomb.wav
bulletEaten.wav
BulletEater.spr
bulletEater.wav
bunker.png
bunkerbuster.spr
BunkerBuster.wav
CDbunkerWalls.bmp
Colt Round.png
Colt.spr
colt45.wav
corpse (small).spr
diescream.wav
emptychamber.wav
Evil Jessica (small).spr
Felix the Cat (small).spr
FelixFire.spr
FelixFire.wav
freeLife.wav
gun.png
gun.spr
heartbeat.wav
help_background.jpg
hithard.wav
Jessica Rabbit Small.spr
largeJessica.spr
Laser.spr
laserFire.wav
loadclip.wav
Map WPs.png
Map.jpg
MapCD.bmp
mini bat.spr
NearestWayPointsTable.bfs
nightstalker.bmp
nightstalker.png
red bunker.png
Robot Den New.png
Robot_A.spr
smurf (small).spr
smurf-attack.spr
spider (small).spr
Spider Web.png
splat.wav
WayPointsArray.bfs
WayPointsTable.bfs
Sprites.zip
Sprites
Robot1.bmp
Robot2.bmp
robot3.bmp
Bat
bat.spr
head.bmp
head.jpg
leftwing.bmp
mini bat.spr
wing.bmp
Bullets
bulletEater original.png
bulletEater.bmp
BulletEater.spr
bunkerbuster.bmp
bunkerbuster.spr
Colt.bmp
Colt.spr
Laser.bmp
Laser.spr
master limb.bmp
smurf-attack.bmp
smurf-attack.spr
Claudia Schiffer
alt.spr
Claudia.spr
Claudia_Arm.bmp
Claudia_Foot.bmp
Claudia_Forearm.bmp
Claudia_Hand_Left.bmp
Claudia_Hand_Right.bmp
Claudia_head.bmp
Claudia_head2.bmp
Claudia_mini.spr
Claudia_Schiffer_1.jpg
Claudia_Shin.bmp
Claudia_Thigh.bmp
Claudia_Torso.bmp
gunHand.bmp
Corpse
blood.bmp
corpse (small).spr
Corpse.spr
guts.bmp
master limb.bmp
robot.png
smurfcorpse.png
Evil Jessica
Evil Jessica (small).spr
Evil Jessica.spr
GunHand(near).bmp
JR_Arm.bmp
JR_Arm.png
JR_Dress.bmp
JR_Dress_resized.bmp
JR_Foot.bmp
JR_Forearm.bmp
JR_Hair(far).bmp
JR_Hair(near).bmp
JR_Hand.bmp
JR_Hand_Right.bmp
JR_Head.bmp
JR_MasterBlock.bmp
JR_Shin.bmp
JR_Thigh_far.bmp
JR_Thigh_near.bmp
JR_Torso.bmp
gun
gun.bmp
gun.spr
master block.bmp
Jessica Rabbit
GunHand(near).bmp
Jessica Rabbit Small.spr
Jessica Rabbit.spr
jessica_rabbit at mic.jpg
JR_Arm.bmp
JR_Dress.bmp
JR_Dress_resized.bmp
JR_Foot.bmp
JR_Forearm.bmp
JR_Hair(far).bmp
JR_Hair(near).bmp
JR_Hand.bmp
JR_Hand_Right.bmp
JR_Head.bmp
JR_MasterBlock.bmp
JR_Shin.bmp
JR_Thigh_far.bmp
JR_Thigh_near.bmp
JR_Torso.bmp
Lindsay Lohan
arm.bmp
foot.bmp
forearm.bmp
gunHand.bmp
Hand_Left.bmp
head.bmp
Lindsay Lohan.spr
Mini Lindsay Lohan.spr
shin.bmp
skirt_ass.bmp
skirt_front.bmp
thigh.bmp
torso.bmp
NightStalkerSprites
BulletEater.spr
bunkerbuster.spr
Colt.spr
corpse (small).spr
Evil Jessica (small).spr
gun.spr
Jessica Rabbit Small.spr
Laser.spr
mini bat.spr
Mini Lindsay Lohan.spr
Robot_A.spr
smurf (small).spr
smurf-attack.spr
spider (small).spr
Robot Heart
RobotHeart_Head.bmp
RobotHeart_Torso.bmp
Robot_EyeShut.bmp
ROBOT_heart.bmp
Robot_Heart.spr
Robot_Heart_small.spr
Robot_LeftArm.bmp
Robot_Leg.bmp
Robot_dumb
Arm.bmp
Arm_right_front.bmp
Hand.bmp
Head.bmp
head_back.bmp
Head_Front.bmp
Leg.bmp
leg_back.bmp
leg_front.bmp
Robot_A.spr
Robot_A_original.spr
Robot_A_original_copy.spr
Torso.bmp
Torso_Front.bmp
Smurf
arm(far).bmp
arm(near).bmp
head.bmp
leg.bmp
smurf (small).spr
smurf.spr
Torso.bmp
spider
body.bmp
eyes shut.bmp
head.bmp
legA_left.bmp
legA_right.bmp
legB_left.bmp
legB_right.bmp
LegC_left.bmp
legC_right.bmp
legD_left.bmp
legD_right.bmp
mandible_left.bmp
mandible_right.bmp
spider (small).spr
spider 2.spr
spider.png
spider.spr
sprite_Demo_C_2008.zip
Sprite demo
Sprite demo
Sprite demo.csproj.user
bin
Release
Sprite demo.exe
Properties
Settings.settings
Resources
cartoon grass.jpg
smurf (small).spr
sprite_Editor_C_2008.zip
Sprite Editor
Sprite Editor
Sprite Editor.csproj.user
sprite Editor.ico
bin
Release
cLibPicBoxViewer.dll
Sprite Editor.exe
Properties
Settings.settings
Resources
click to load image.bmp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Night_Stalker
{
    public class classCollisionDetection
    {
        /// <summary>
        /// object described as a rectangle
        /// where the ptRelPos is the point inside the rectangle relative to the object's position
        /// </summary>
        public struct udtCDInfo
        {
            public Size sz;
            public Point ptRelPos;
        }

        public int intPixelSize = 5; // map has been shrunk to 1/5th original size and made into mapCD

        public Bitmap bmpCD = Night_Stalker.Properties.Resources.MapCD;
        classHelperFunctions cLibHelper;
        public classJessica Jessica;
        public classRobot[] robots;

        Color clrCollision;
        Color clrSnares;
        Color clrBunkerWalls;
        Color clrBunkerDoor;

        Point ptJessicaCD;
        Point ptJessicaTL;
        Point ptJessicaTR;
        Point ptJessicaBL;
        Point ptJessicaBR;

        public enum enuCanISeeJessica
        {
            unknown,
            yes,
            no
        }
        enuCanISeeJessica[,] CanISeeJessicaTable;
        const int intCanISeeJessicaGridSize = 15; //5x CD points = 25 real points
        Size szCanISeeJessica = new Size();

        /// <summary>
        /// flood fill function used in bunker-buster
        /// </summary>
        udtQ picQ = new udtQ();
        public struct udtQ
        {
            public classPixelPos head;
            public classPixelPos tail;
        }
        public class classPixelPos
        {
            public Point pos;
            public classPixelPos next;
        }

        public struct udtWallLine
        {
            public Point pt1;
            public Point pt2;
        }

        public classBullet bulletQ;

        public bool bolDrawCDInfo = false;
        public bool bolEnableSnares = false;

        public classCollisionDetection(ref classHelperFunctions Helper)
        {
            cLibHelper = Helper;
            resetCDMap();

            clrCollision = bmpCD.GetPixel(0, 0);
            clrSnares = bmpCD.GetPixel(1, 0);
            clrBunkerWalls = bmpCD.GetPixel(2, 0);
            clrBunkerDoor = bmpCD.GetPixel(3, 0);

            initCanISeeJessica();
        }

        public void resetCDMap()
        {
           bmpCD  =new Bitmap( Night_Stalker.Properties.Resources.MapCD);
        }

        void initCanISeeJessica()
        {
            int intNumX = bmpCD.Width / 5 +2;
            int intNumY = bmpCD.Height / 5 +2;


            szCanISeeJessica = new Size(intNumX, intNumY);
            int intNumPoints = intNumX * intNumY;

            CanISeeJessicaTable = new enuCanISeeJessica[intNumPoints, intNumPoints];

        }

        /// <summary>
        /// adds the referenced bullet to the bullet Q
        /// </summary>
        /// <param name="thisBullet">reference to bullet to be inserted into Q</param>
        public void enQBullet(ref classBullet thisBullet)
        {
            thisBullet.next = bulletQ;
            if (thisBullet.next != null)
                thisBullet.next.prev = thisBullet;

            bulletQ = thisBullet;
        }       

        public void animateBullets(ref Bitmap bmpMap)
        {
            if (bulletQ != null)
                bulletQ.animate(ref bmpMap);
        }

        /// <summary>
        /// translates a location on game map into its equivalent scaled location on CD-map
        /// </summary>
        /// <param name="ptRealLoc">point on real  map</param>
        /// <returns></returns>
        public Point getCDLoc(Point ptRealLoc) { return new Point(ptRealLoc.X / intPixelSize, ptRealLoc.Y / intPixelSize); }

        /// <summary>
        /// translates a location on the CD-map into its equivalent scaled location on the game map
        /// </summary>
        /// <param name="ptCDLoc">point on CD-map</param>
        /// <returns></returns>
        public Point getRealLoc(Point ptCDLoc) { return new Point(ptCDLoc.X * intPixelSize, ptCDLoc.Y * intPixelSize); }

        /// <summary>
        /// tests if a point on the CD map is inside a CDInfo rectangle 
        /// </summary>
        /// <param name="pt">test point</param>
        /// <param name="udrCDInfo">CD info inside which the test is made</param>
        /// <returns>returns true if test point is inside the CD Info rectangle</returns>
        bool PtIsInCDInfo(Point ptTest, Point ptCDLoc, udtCDInfo udrCDInfo)
        {
            Point ptTL = new Point(ptCDLoc.X - udrCDInfo.ptRelPos.X, 
                                   ptCDLoc.Y - udrCDInfo.ptRelPos.Y);
            Point ptBR = new Point(ptCDLoc.X + udrCDInfo.sz.Width - udrCDInfo.ptRelPos.X,
                                             ptCDLoc.Y + udrCDInfo.sz.Height - udrCDInfo.ptRelPos.Y);

            return (ptTest.X >= ptTL.X && ptTest.X <= ptBR.X
                   && ptTest.Y >= ptTL.Y && ptTest.Y <= ptBR.Y);
        }

        public void drawCDOnMap(ref Bitmap bmp)
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                Size sz = new Size(intPixelSize, intPixelSize);
                Pen thisPen = new Pen(Color.Yellow);
                for (int intX = 0; intX < bmpCD.Width; intX++)
                    for (int intY = 0; intY < bmpCD.Height; intY++)
                        if (bmpCD.GetPixel(intX, intY) == clrCollision)
                            g.DrawRectangle(thisPen, new Rectangle(intX * intPixelSize, intY * intPixelSize, sz.Width, sz.Height));
                        else if (bmpCD.GetPixel(intX,intY) == clrSnares)
                            g.DrawRectangle(new Pen(Color.Green), new Rectangle(intX * intPixelSize, intY * intPixelSize, sz.Width, sz.Height));
            }
        }

        public void drawCDInfo(ref Bitmap bmp, udtCDInfo udrCDInfo, Point pt)
        {
            Point ptTL = new Point(pt.X - udrCDInfo.ptRelPos.X * intPixelSize,
                                    pt.Y - udrCDInfo.ptRelPos.Y * intPixelSize);
            Point ptBR = new Point(ptTL.X + udrCDInfo.sz.Width * intPixelSize,
                                   ptTL.Y + udrCDInfo.sz.Height * intPixelSize);

            using (Graphics g = Graphics.FromImage(bmp))
                g.DrawRectangle(new Pen(Color.Yellow), new Rectangle(ptTL.X, ptTL.Y, ptBR.X - ptTL.X, ptBR.Y - ptTL.Y));
        }

        /// <summary>
        /// compares the position of a dynamic object from start position and end position of a move
        /// against the position of another static object then returns true if there is a collision
        /// </summary>
        /// <param name="ptDynamicStart">start location of the dynamic object</param>
        /// <param name="ptDynamicEnd">final location of the dynamic object</param>
        /// <param name="udrDynamicCDInfo">CD info of the dynamic object</param>
        /// <param name="ptStatic">static location of static object</param>
        /// <param name="udrStaticCDInfo">CD info of static object</param>
        /// <returns>returns true only if the dynamic object's move creates a collision with the static object, and sets the dynamic object's end location 'ptDynamicEnd' at the point of impact</returns>
        public bool CollisionBetweenTwoCDInfoObjects(Point ptDynamicStart,
                                                     ref Point ptDynamicEnd,
                                                     udtCDInfo udrDynamicCDInfo,
                                                     Point ptStatic,
                                                     udtCDInfo udrStaticCDInfo)
        {
            enuDir dir = cLibHelper.getDirBetweenTwoPoints(ptDynamicStart, ptDynamicEnd);
            // pt1, pt2 are ptStart & ptEnd translated into the CDMap scale
            Point pt1 = getCDLoc(ptDynamicStart);
            Point pt2 = getCDLoc(ptDynamicEnd);

            Point ptStaticCD = getCDLoc(ptStatic);

            classMath.classRadialCoor radMove
                = new classMath.classRadialCoor(cLibHelper.cLibMath.arcTan(pt2.X - pt1.X, pt2.Y - pt1.Y),
                                                Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2) + Math.Pow(pt2.Y - pt1.Y, 2)));

            bool bolDynamicUp = false, bolDynamicRight = false, bolDynamicDown = false, bolDynamicLeft = false;

            switch (dir)
            {
                case enuDir.E_:
                    bolDynamicRight = true;
                    break;

                case enuDir.N_:
                    bolDynamicUp = true;
                    break;

                case enuDir.NE:
                    bolDynamicUp = true;
                    bolDynamicRight = true;
                    break;

                case enuDir.NW:
                    bolDynamicUp = true;
                    bolDynamicLeft = true;
                    break;

                case enuDir.S_:
                    bolDynamicDown = true;
                    break;

                case enuDir.SE:
                    bolDynamicDown = true;
                    bolDynamicRight = true;
                    break;

                case enuDir.SW:
                    bolDynamicLeft = true;
                    bolDynamicDown = true;
                    break;

                case enuDir.W_:
                    bolDynamicLeft = true;
                    break;
            }

            int intNumSteps = (int)Math.Ceiling(radMove.radius);
            int intStepCounter = 0;
            Point ptBest = new Point(pt1.X, pt1.Y);
            for (intStepCounter = 0; intStepCounter <= radMove.radius; intStepCounter++)
            {
                Point pt = new Point((int)(pt1.X + intStepCounter * Math.Cos(radMove.angle)),
                                     (int)(pt1.Y + intStepCounter * Math.Sin(radMove.angle)));

                if (bolDynamicLeft)
                {
                    for (int intY = 0; intY < udrDynamicCDInfo.sz.Height; intY++)
                    {
                        Point ptTest = new Point(pt.X - udrDynamicCDInfo.ptRelPos.X, pt.Y - udrDynamicCDInfo.ptRelPos.Y + intY);
                        if (PtIsInCDInfo(ptTest, ptStaticCD, udrStaticCDInfo))
                        {
                            ptDynamicEnd =getRealLoc( ptBest);
                            return true;
                        }
                    }
                }

                if (bolDynamicRight)
                {
                    for (int intY = 0; intY < udrDynamicCDInfo.sz.Height; intY++)
                    {
                        Point ptTest = new Point(pt.X + udrDynamicCDInfo.sz.Width - udrDynamicCDInfo.ptRelPos.X, pt.Y - udrDynamicCDInfo.ptRelPos.Y + intY);
                        if (PtIsInCDInfo(ptTest, ptStaticCD, udrStaticCDInfo))
                        {
                            ptDynamicEnd =getRealLoc( ptBest);
                            return true;
                        }
                    }
                }

                if (bolDynamicUp)
                {
                    for (int intX = 0; intX < udrDynamicCDInfo.sz.Width; intX++)
                    {
                        Point ptTest = new Point(pt.X - udrDynamicCDInfo.ptRelPos.X + intX, pt.Y - udrDynamicCDInfo.ptRelPos.Y);
                        if (PtIsInCDInfo(ptTest, ptStaticCD, udrStaticCDInfo))
                        {
                            ptDynamicEnd =getRealLoc( ptBest);
                            return true;
                        }
                    }
                }

                if (bolDynamicDown)
                {
                    for (int intX = 0; intX < udrDynamicCDInfo.sz.Width; intX++)
                    {
                        Point ptTest = new Point(pt.X - udrDynamicCDInfo.ptRelPos.X + intX, pt.Y + udrDynamicCDInfo.sz.Height - udrDynamicCDInfo.ptRelPos.Y);
                        if (PtIsInCDInfo(ptTest, ptStaticCD, udrStaticCDInfo))
                        {
                            ptDynamicEnd =getRealLoc( ptBest);
                            return true;
                        }
                    }
                }

                ptBest = pt;
            }

            return false;

        }

        public classRobot HitARobot(Point ptStart, ref Point ptEnd, udtCDInfo udrCDInfo)
        {
            for (int intRobotCounter = 0; intRobotCounter < robots.Length; intRobotCounter++)
            {
                if (robots[intRobotCounter] != null
                    && !robots[intRobotCounter].bolDead)
                {
                    if (CollisionBetweenTwoCDInfoObjects(ptStart,
                                                         ref ptEnd,
                                                         udrCDInfo,
                                                         robots[intRobotCounter].loc,
                                                         robots[intRobotCounter].udrCDInfo))
                        return robots[intRobotCounter];
                }
            }
            return null;
        }

        public classRobot HitAPest(Point ptStart, ref Point ptEnd, udtCDInfo udrCDInfo)
        {
            for (int intRobotCounter = 0; intRobotCounter < robots.Length; intRobotCounter++)
            {
                if (robots[intRobotCounter] != null
                    && !robots[intRobotCounter].bolDead
                    && robots[intRobotCounter].iBite())  
                {
                    if (CollisionBetweenTwoCDInfoObjects(ptStart,
                                                         ref ptEnd,
                                                         udrCDInfo,
                                                         robots[intRobotCounter].loc,
                                                         robots[intRobotCounter].udrCDInfo))
                        return robots[intRobotCounter];
                }
            }
            return null;
        }

        bool PtOnMapIsCollision(Point pt) { return PtOnMapIsCollision(pt, false); }
        bool PtOnMapIsCollision(Point pt, bool bolIgnoreBunkerDoor) { return PtOnMapIsCollision(pt.X, pt.Y, bolIgnoreBunkerDoor); }
        bool PtOnMapIsCollision(int intX, int intY, bool bolIgnoreBunkerDoor)
        {
            if (bmpCD == null)
                return true;
            Color clr = bmpCD.GetPixel(intX, intY);
            return ((bolEnableSnares && clr == clrSnares)
                 || (clr == clrCollision)
                 || (clr == clrBunkerWalls)
                 || (!bolIgnoreBunkerDoor && clr == clrBunkerDoor));
        }

        /// <summary>
        /// tests if a point on CD map is part of bunker door or wall
        /// </summary>
        /// <param name="pt">location on CD map to test</param>
        /// <returns>true if the point is either part of the Bunker door or wall</returns>
        bool PtHitsBunker(Point pt) { return PtHitsBunker(pt.X, pt.Y); }
        
        /// <summary>
        /// tests if coordinate (x,y) is on CD map is part of bunker door or wall
        /// </summary>
        /// <param name="intX">x location to test on CD map</param>
        /// <param name="intY">y location to test on CD map</param>
        /// <returns>true if the point is either part of the Bunker door or wall</returns>
        bool PtHitsBunker(int intX, int intY)
        {
            if (bmpCD == null)
                return true;
            Color clr = bmpCD.GetPixel(intX, intY);
            return (clr == clrBunkerDoor
                    || clr == clrBunkerWalls);
        }
    
        /// <summary>
        /// this function tests if the move from start to end causes the object to hit the maps's walls.
        /// this call will NOT ignore bunker door, and does NOT damage the bunker
        /// </summary>
        /// <param name="ptStart">start location of object to be moved in the game map</param>
        /// <param name="ptEnd">end location of object to be moved in the game map</param>
        /// <param name="udrCDInfo">the object's Collision-Detection description information</param>
        /// <returns>returns true only if this move does NOT cause a collision with any walls</returns>
        public bool move(Point ptStart, ref Point ptEnd, udtCDInfo udrCDInfo) { return move(ptStart, ref ptEnd, udrCDInfo, false, false); }        
        
        public enum enuMoveRetry {bothVAndH, VAlone, HAlone, quit }
        /// <summary>
        /// this function tests if the move from start to end causes the object to hit the maps's walls.
        /// </summary>
        /// <param name="ptStart">start location of object to be moved in the game map</param>
        /// <param name="ptEnd">end location of object to be moved in the game map</param>
        /// <param name="udrCDInfo">the object's Collision-Detection description information</param>
        /// <returns>returns true only if this move does NOT cause a collision with any walls</returns>
        public bool move(Point ptStart, ref Point ptEnd, udtCDInfo udrCDInfo, bool bolIgnoreBunkerDoor, bool bolDamageBunker)
        {
            enuDir dir = cLibHelper.getDirBetweenTwoPoints(ptStart, ptEnd);

            // pt1, pt2 are ptStart & ptEnd translated into the CDMap scale
            Point pt1 = getCDLoc(ptStart);
            Point pt2 = getCDLoc(ptEnd);

            if (pt2.X > bmpCD.Width || pt2.X < 0
                || pt2.Y > bmpCD.Height || pt2.Y < 0)
                return false;

            classMath.classRadialCoor radMove = new classMath.classRadialCoor();

            radMove.angle = cLibHelper.cLibMath.arcTan(ptEnd.X - ptStart.X, ptEnd.Y - ptStart.Y);
            radMove.radius = Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2) + Math.Pow(pt2.Y - pt1.Y, 2));

            bool bolUp = false, bolRight = false, bolDown = false, bolLeft = false;

            switch (dir)
            {
                case enuDir.E_:
                    bolRight = true;
                    break;

                case enuDir.N_:
                    bolUp = true;
                    break;

                case enuDir.NE:
                    bolUp = true;
                    bolRight = true;
                    break;

                case enuDir.NW:
                    bolUp = true;
                    bolLeft = true;
                    break;

                case enuDir.S_:
                    bolDown = true;
                    break;

                case enuDir.SE:
                    bolDown = true;
                    bolRight = true;
                    break;

                case enuDir.SW:
                    bolLeft = true;
                    bolDown = true;
                    break;

                case enuDir.W_:
                    bolLeft = true;
                    break;
            }
           
            int intNumSteps = (int)Math.Ceiling(radMove.radius);
            int intStepCounter = 0;
            Point ptBest = new Point(pt1.X, pt1.Y);

            int intNewX = pt1.X;
            int intNewXBase = intNewX;
            int intNewY = pt1.Y;
            int intNewYBase = intNewY;

            bool bolDiagonal = (bolUp || bolDown) && (bolLeft || bolRight);
            enuMoveRetry retry = enuMoveRetry.bothVAndH;
            bool bolLeftCollision = false, bolUpCollision = false, bolRightCollision = false, bolDownCollision = false;
            bool bolRetVal = true;

            for (intStepCounter = 1; intStepCounter <= radMove.radius; intStepCounter++)
            {
                if (!bolLeftCollision && !bolRightCollision)
                    intNewX = intNewXBase + (int)((double)intStepCounter * Math.Cos(radMove.angle));
                else
                    intNewX = ptBest.X;
                if (!bolUpCollision && !bolDownCollision)
                    intNewY = intNewYBase + (int)((double)intStepCounter * Math.Sin(radMove.angle));
                else
                    intNewY = ptBest.Y;
                Point pt = new Point(intNewX, intNewY);

            startLoop:            
                if (bolLeft && !bolLeftCollision)
                {
                    for (int intY = 0; intY < udrCDInfo.sz.Height; intY++)
                    {
                        Point ptTest = ptTest = new Point(pt.X - udrCDInfo.ptRelPos.X, pt.Y - udrCDInfo.ptRelPos.Y + intY);
                        if (retry == enuMoveRetry.HAlone)
                            ptTest = new Point(pt.X - udrCDInfo.ptRelPos.X, ptBest.Y - udrCDInfo.ptRelPos.Y + intY);
                        else if (retry == enuMoveRetry.VAlone)
                            ptTest = new Point(ptBest.X - udrCDInfo.ptRelPos.X, pt.Y - udrCDInfo.ptRelPos.Y + intY);

                        if (isValidCDMapLoc(ptTest))
                        {
                            Color clrThisPix = bmpCD.GetPixel(ptTest.X, ptTest.Y);
                            if (PtOnMapIsCollision(ptTest, bolIgnoreBunkerDoor))
                            {
                                bolLeftCollision = true;
                                if (bolDamageBunker)
                                    if (PtHitsBunker(ptTest))
                                        damageBunker(ptTest);
                                break;
                            }
                        }
                    }
                }

                if (bolRight && !bolRightCollision)
                {
                    for (int intY = 0; intY < udrCDInfo.sz.Height; intY++)
                    {
                        Point ptTest;
                        if (retry == enuMoveRetry.HAlone)
                            ptTest = new Point(pt.X +udrCDInfo.sz.Width  - udrCDInfo.ptRelPos.X-1, ptBest.Y - udrCDInfo.ptRelPos.Y + intY);
                        else if (retry == enuMoveRetry.VAlone)
                            ptTest = new Point(ptBest.X + udrCDInfo.sz.Width - udrCDInfo.ptRelPos.X-1, pt.Y - udrCDInfo.ptRelPos.Y + intY);
                        else
                            ptTest = new Point(pt.X + udrCDInfo.sz.Width - udrCDInfo.ptRelPos.X-1, pt.Y - udrCDInfo.ptRelPos.Y + intY);
                        
                        if (isValidCDMapLoc(ptTest))
                        {
                            Color clrThisPix = bmpCD.GetPixel(ptTest.X, ptTest.Y);
                            if (PtOnMapIsCollision(ptTest, bolIgnoreBunkerDoor))
                            {
                                bolRightCollision = true;
                                if (bolDamageBunker)
                                    if (PtHitsBunker(ptTest))
                                        damageBunker(ptTest);
                                break;
                            }
                        }
                    }
                }

                if (bolUp && !bolUpCollision)
                {
                    for (int intX = 0; intX < udrCDInfo.sz.Width; intX++)
                    {
                        Point ptTest;
                        if (retry == enuMoveRetry.HAlone)
                            ptTest = new Point(pt.X - udrCDInfo.ptRelPos.X +intX, ptBest.Y - udrCDInfo.ptRelPos.Y);
                        else if (retry == enuMoveRetry.VAlone)
                            ptTest = new Point(ptBest.X - udrCDInfo.ptRelPos.X  + intX, pt.Y - udrCDInfo.ptRelPos.Y);
                        else
                            ptTest = new Point(pt.X  - udrCDInfo.ptRelPos.X + intX, pt.Y - udrCDInfo.ptRelPos.Y);
                     
                        if (isValidCDMapLoc(ptTest))
                        {
                            Color clrThisPix = bmpCD.GetPixel(ptTest.X, ptTest.Y);
                            if (PtOnMapIsCollision(ptTest, bolIgnoreBunkerDoor))
                            {
                                bolUpCollision = true;
                                if (bolDamageBunker)
                                    if (PtHitsBunker(ptTest))
                                        damageBunker(ptTest);
                                break;
                            }
                        }
                    }
                }

                if (bolDown && !bolDownCollision)
                {
                    for (int intX = 0; intX < udrCDInfo.sz.Width; intX++)
                    {
                        Point ptTest = new Point(pt.X - udrCDInfo.ptRelPos.X + intX, pt.Y + udrCDInfo.sz.Height - udrCDInfo.ptRelPos.Y - 1);
                        if (retry == enuMoveRetry.HAlone)
                            ptTest = new Point(pt.X - udrCDInfo.ptRelPos.X + intX, ptBest.Y + udrCDInfo.sz.Height - udrCDInfo.ptRelPos.Y - 1);
                        else if (retry== enuMoveRetry.VAlone)
                            ptTest = new Point(ptBest.X - udrCDInfo.ptRelPos.X + intX, pt.Y + udrCDInfo.sz.Height - udrCDInfo.ptRelPos.Y - 1);

                        if (isValidCDMapLoc(ptTest))
                        {
                            Color clrThisPix = bmpCD.GetPixel(ptTest.X, ptTest.Y);
                            if (PtOnMapIsCollision(ptTest, bolIgnoreBunkerDoor))
                            {
                                bolDownCollision = true;
                                if (bolDamageBunker)
                                    if (PtHitsBunker(ptTest))
                                        damageBunker(ptTest);
                                break;
                            }
                        }
                    }
                }

                if (bolDownCollision || bolUpCollision || bolLeftCollision || bolRightCollision)
                {
                    bool bolHCollision = bolLeftCollision || bolRightCollision;
                    bool bolVCollision = bolUpCollision || bolDownCollision;
                    bolRetVal = false;
                    if (bolDiagonal)
                    {
                        {
                            bolDownCollision = bolUpCollision = bolLeftCollision = bolRightCollision = false;
                            retry++;
                            if (retry != enuMoveRetry.quit)
                                goto startLoop;
                            else
                                goto CollisionDetected;
                        }
                    }
                    else
                    {
                        goto CollisionDetected;
                    }
                }
                else
                {
                    if (retry == enuMoveRetry.bothVAndH)
                        ptBest = pt;
                    else if (retry == enuMoveRetry.VAlone)
                        ptBest = new Point(ptBest.X, pt.Y);
                    else if (retry == enuMoveRetry.HAlone)
                        ptBest = new Point(pt.X, ptBest.Y);
                }
                
                ptEnd = getRealLoc(ptBest);                
            }

            return bolRetVal;

        CollisionDetected:
            ptEnd = getRealLoc(ptBest);
            return bolRetVal;
        }

        void damageBunker(Point pt)
        {
            Point ptBunkerLoc = new Point(88, 48);
            Size szBunkerSize = new Size(117 - 88, 71 - 48+1);

            Bitmap bmpCDBunker_bordered = new Bitmap(szBunkerSize.Width + 2, szBunkerSize.Height + 2);
            using (Graphics g = Graphics.FromImage(bmpCDBunker_bordered))
            {
                g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bmpCDBunker_bordered.Width, bmpCDBunker_bordered.Height));
                g.DrawImage(bmpCD, new Rectangle(1, 1, szBunkerSize.Width, szBunkerSize.Height), new Rectangle(ptBunkerLoc, szBunkerSize), GraphicsUnit.Pixel);
            }
            // draw a solid color around the border 
            // this assures that flood fill to unify wall-clr w/ door-clr doesn't miss any part of the wall
       
            Pen borderPen = new Pen(clrBunkerWalls);
            using (Graphics g = Graphics.FromImage(bmpCDBunker_bordered))
            {
                g.DrawLine(borderPen, 0, 0, 0, bmpCDBunker_bordered.Height);
                g.DrawLine(borderPen, 0, bmpCDBunker_bordered.Height - 1, bmpCDBunker_bordered.Width - 1, bmpCDBunker_bordered.Height - 1);
                g.DrawLine(borderPen, bmpCDBunker_bordered.Width - 1, bmpCDBunker_bordered.Height - 1, bmpCDBunker_bordered.Width - 1, 0);
                g.DrawLine(borderPen, bmpCDBunker_bordered.Width - 1, 0, 0, 0);
            }
          
            floodfill_sameColor(ref bmpCDBunker_bordered, new Point(0, 0), clrBunkerDoor);
            // now whatever is left of the bunker (plus a 1-pixel wide border) are all the same color

            Point ptDamage = new Point(pt.X - ptBunkerLoc.X, pt.Y - ptBunkerLoc.Y);
            int intDamageSize = 3;

            // remove border from door colored bunker image
            Bitmap bmpCDBunker = new Bitmap(bmpCDBunker_bordered.Width - 2, bmpCDBunker_bordered.Height - 2);
            using (Graphics g = Graphics.FromImage(bmpCDBunker))
                g.DrawImage(bmpCDBunker_bordered, new Rectangle(0, 0, bmpCDBunker.Width, bmpCDBunker.Height), new Rectangle(1, 1, bmpCDBunker.Width, bmpCDBunker.Height), GraphicsUnit.Pixel);

            using (Graphics g = Graphics.FromImage(bmpCDBunker))
                g.FillEllipse(new SolidBrush(Color.White), new Rectangle(ptDamage.X - intDamageSize, ptDamage.Y - intDamageSize, intDamageSize * 2, intDamageSize * 2));

            /// redraw bunker walls onto image
            Bitmap bmpTempCDBunker = new Bitmap(bmpCDBunker);
            bmpTempCDBunker.MakeTransparent(clrBunkerDoor);
            
            Bitmap bmpBunkerWalls = new Bitmap(Night_Stalker.Properties.Resources.CDbunkerWalls);

            // first draw white of door-colored bunker over top of walls
            using (Graphics g = Graphics.FromImage(bmpBunkerWalls))
                g.DrawImage(bmpTempCDBunker, new Point(0, 0));

            // then draw remaining walls overtop of door-colored bunker
            bmpBunkerWalls.MakeTransparent(Color.White);
            using (Graphics g = Graphics.FromImage(bmpCDBunker))
                g.DrawImage(bmpBunkerWalls, new Point(0, 0));
           // copy new bunker image over old bmpCD
            using (Graphics g = Graphics.FromImage(bmpCD))
                g.DrawImage(bmpCDBunker, new Rectangle(new Point (ptBunkerLoc.X, ptBunkerLoc.Y), szBunkerSize), new Rectangle(0, 0, szBunkerSize.Width, szBunkerSize.Height), GraphicsUnit.Pixel);

            // resize the CD-bunker image to real-map size (5x bigger)
            Bitmap bmpRealMask = new Bitmap(cLibHelper.bmpBunker.Width, cLibHelper.bmpBunker.Height);
            SolidBrush brsClrDoor = new SolidBrush(clrBunkerDoor);
            SolidBrush brsWhite = new SolidBrush(Color.White);

            using (Graphics g = Graphics.FromImage(bmpRealMask))
            {
                g.FillRectangle(brsWhite, new Rectangle(0, 0, bmpRealMask.Width, bmpRealMask.Height));
                for (int intX = 0; intX < bmpCDBunker.Width ; intX++)
                    for (int intY = 0; intY < bmpCDBunker.Height ; intY++)
                        if (bmpCDBunker.GetPixel(intX, intY) == clrBunkerDoor
                            || bmpCDBunker.GetPixel (intX, intY) == clrBunkerWalls)
                            g.FillRectangle(brsClrDoor, new Rectangle((intX) * 5, (intY ) * 5, 5, 5));
                        else
                            g.FillRectangle(brsWhite, new Rectangle((intX ) * 5, (intY ) * 5, 5, 5));
            }

            // make the bunker-door color transparent
            bmpRealMask.MakeTransparent(clrBunkerDoor);

            using (Graphics g = Graphics.FromImage(cLibHelper.bmpBunker))
                g.DrawImage(bmpRealMask, new Point(0, 0));
        }

        enum enuDirections { north = 0, east, south, west, _numDir }
        private void floodfill_sameColor(ref Bitmap bmp, Point ptSeed, Color clrFloodFill_set)
        {
            picQ.head = null;
            picQ.tail = null;
            if (ptSeed.X >= bmp.Width || ptSeed.Y >= bmp.Height)
                return;
            Color clrOriginal = bmp.GetPixel(ptSeed.X, ptSeed.Y);

            classPixelPos seed = new classPixelPos();
            seed.pos.X = ptSeed.X; seed.pos.Y = ptSeed.Y;

            if (bmp == null) return;

            enQ(ref picQ, ref seed);

            bool[,] bolSeenMap = new bool[bmp.Width, bmp.Height];

            while (picQ.head != null)
            {
                classPixelPos pixel = deQ(ref picQ);
                Color clrPixel = bmp.GetPixel(pixel.pos.X, pixel.pos.Y);

                if (clrPixel != clrFloodFill_set)
                    bmp.SetPixel(pixel.pos.X, pixel.pos.Y, clrFloodFill_set);

                for (enuDirections dircounter = 0; dircounter < enuDirections._numDir; dircounter++)
                {
                    Point ptNext = move(pixel.pos, dircounter);
                    if (ptNext.X >= 0 && ptNext.X < bmp.Width)
                        if (ptNext.Y >= 0 && ptNext.Y < bmp.Height)
                        {
                            if (!bolSeenMap[ptNext.X, ptNext.Y])
                            {
                                Color clrPix = bmp.GetPixel(ptNext.X, ptNext.Y);
                                if (clrPix == clrOriginal)
                                {
                                    classPixelPos pixelNew = new classPixelPos();
                                    pixelNew.pos = ptNext;
                                    enQ(ref picQ, ref pixelNew);
                                }
                            }
                            bolSeenMap[ptNext.X, ptNext.Y] = true;
                        }
                }
            }           
        }

        void enQ(ref udtQ picQ, ref classPixelPos Qele)
        {
            if (picQ.tail == null)
                picQ.tail = Qele;
            else
                picQ.tail.next = Qele;
            Qele.next = null;
            picQ.tail = Qele;

            if (picQ.head == null)
                picQ.head = picQ.tail;
        }

        classPixelPos deQ(ref udtQ picQ)
        {
            classPixelPos Qret = picQ.head;
            picQ.head = picQ.head.next;
            Qret.next = null;
            return Qret;
        }

        Point move(Point pt, enuDirections dir)
        {
            Point ptRetVal = new Point();
            ptRetVal.X = pt.X;
            ptRetVal.Y = pt.Y;

            switch (dir)
            {
                case enuDirections.north:
                    ptRetVal.Y--;
                    break;

                case enuDirections.east:
                    ptRetVal.X++;
                    break;

                case enuDirections.south:
                    ptRetVal.Y++;
                    break;

                case enuDirections.west:
                    ptRetVal.X--;
                    break;
            }

            return ptRetVal;
        }

        bool isValidCDMapLoc(Point ptTest)
        {
            return (ptTest.X >= 0
                    && ptTest.X < bmpCD.Width
                    && ptTest.Y >= 0
                    && ptTest.Y < bmpCD.Height);
        }

        /// <summary>
        /// sets Jessica's 5 CD values(TL, TR, BL, BR + loc)
        /// </summary>
        public void setJessicaLocation()
        {
            ptJessicaCD = getCDLoc(Jessica.ptLoc);
            ptJessicaTL = new Point(ptJessicaCD.X - Jessica.udrCDInfo.ptRelPos.X, ptJessicaCD.Y - Jessica.udrCDInfo.ptRelPos.Y);
            ptJessicaTR = new Point(ptJessicaTL.X + Jessica.udrCDInfo.sz.Width, ptJessicaTL.Y);
            ptJessicaBL = new Point(ptJessicaTL.X, ptJessicaTL.Y + Jessica.udrCDInfo.sz.Height);
            ptJessicaBR = new Point(ptJessicaTR.X, ptJessicaBL.Y);
        }

        /// <summary>
        /// Jessica is falling asleep and may be shoving her legs through a wall.  
        /// This function will slide her away from the wall if she is.
        /// </summary>
        ///      
        public void stretchJessicaAwayFromWall()
        {
            Point ptCDLoc = getCDLoc(Jessica.ptLoc);
            Point[] ptTest = new Point[56];

            if (Jessica.mirror == Sprite.enuMirror.none)
            {// she is facing right
                ptTest[0] = ptCDLoc;
                ptTest[1] = new Point(ptCDLoc.X + 1, ptCDLoc.Y);
                ptTest[2] = new Point(ptCDLoc.X, ptCDLoc.Y - 1);
                ptTest[3] = new Point(ptCDLoc.X + 1, ptCDLoc.Y - 1);
                ptTest[4] = new Point(ptCDLoc.X + 2, ptCDLoc.Y - 1);
                ptTest[5] = new Point(ptCDLoc.X + 2, ptCDLoc.Y - 2);
                ptTest[6] = new Point(ptCDLoc.X + 3, ptCDLoc.Y );                
                ptTest[7] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 1);
                ptTest[8] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 2);
                ptTest[9] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 3);
                ptTest[10] = new Point(ptCDLoc.X + 4, ptCDLoc.Y);
                ptTest[11] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 1);
                ptTest[12] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 2);
                ptTest[13] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 3);
                ptTest[14] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 4);
                ptTest[15] = new Point(ptCDLoc.X - 1, ptCDLoc.Y);
                ptTest[16] = new Point(ptCDLoc.X - 1, ptCDLoc.Y - 1);
                ptTest[17] = new Point(ptCDLoc.X - 2, ptCDLoc.Y);
                ptTest[18] = new Point(ptCDLoc.X - 2, ptCDLoc.Y - 1);
                ptTest[19] = new Point(ptCDLoc.X - 2, ptCDLoc.Y - 2);
                ptTest[20] = new Point(ptCDLoc.X - 3, ptCDLoc.Y);
                ptTest[21] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 1);
                ptTest[22] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 2);
                ptTest[23] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 3);
                ptTest[24] = new Point(ptCDLoc.X - 4, ptCDLoc.Y);
                ptTest[25] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 1);
                ptTest[26] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 2);
                ptTest[27] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 3);
                ptTest[28] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 4);

                ptTest[29] = new Point(ptCDLoc.X, ptCDLoc.Y +1);
                ptTest[30] = new Point(ptCDLoc.X + 1, ptCDLoc.Y +1);
                ptTest[31] = new Point(ptCDLoc.X + 2, ptCDLoc.Y +1);
                ptTest[32] = new Point(ptCDLoc.X + 2, ptCDLoc.Y +2);
                ptTest[33] = new Point(ptCDLoc.X + 3, ptCDLoc.Y);
                ptTest[34] = new Point(ptCDLoc.X + 3, ptCDLoc.Y +1);
                ptTest[35] = new Point(ptCDLoc.X + 3, ptCDLoc.Y +2);
                ptTest[36] = new Point(ptCDLoc.X + 3, ptCDLoc.Y +3);
                ptTest[37] = new Point(ptCDLoc.X + 4, ptCDLoc.Y);
                ptTest[38] = new Point(ptCDLoc.X + 4, ptCDLoc.Y +1);
                ptTest[39] = new Point(ptCDLoc.X + 4, ptCDLoc.Y +2);
                ptTest[40] = new Point(ptCDLoc.X + 4, ptCDLoc.Y +3);
                ptTest[41] = new Point(ptCDLoc.X + 4, ptCDLoc.Y +4);
                ptTest[42] = new Point(ptCDLoc.X - 1, ptCDLoc.Y);
                ptTest[43] = new Point(ptCDLoc.X - 1, ptCDLoc.Y +1);
                ptTest[44] = new Point(ptCDLoc.X - 2, ptCDLoc.Y);
                ptTest[45] = new Point(ptCDLoc.X - 2, ptCDLoc.Y +1);
                ptTest[46] = new Point(ptCDLoc.X - 2, ptCDLoc.Y +2);
                ptTest[47] = new Point(ptCDLoc.X - 3, ptCDLoc.Y);
                ptTest[48] = new Point(ptCDLoc.X - 3, ptCDLoc.Y +1);
                ptTest[49] = new Point(ptCDLoc.X - 3, ptCDLoc.Y +2);
                ptTest[50] = new Point(ptCDLoc.X - 3, ptCDLoc.Y +3);
                ptTest[51] = new Point(ptCDLoc.X - 4, ptCDLoc.Y);
                ptTest[52] = new Point(ptCDLoc.X - 4, ptCDLoc.Y +1);
                ptTest[53] = new Point(ptCDLoc.X - 4, ptCDLoc.Y +2);
                ptTest[54] = new Point(ptCDLoc.X - 4, ptCDLoc.Y +3);
                ptTest[55] = new Point(ptCDLoc.X - 4, ptCDLoc.Y +4);
            }
            else
            {// she is facing left
                ptTest[0] = ptCDLoc;
                ptTest[1] = new Point(ptCDLoc.X - 1, ptCDLoc.Y);
                ptTest[2] = new Point(ptCDLoc.X, ptCDLoc.Y - 1);
                ptTest[3] = new Point(ptCDLoc.X - 1, ptCDLoc.Y - 1);
                ptTest[4] = new Point(ptCDLoc.X - 2, ptCDLoc.Y - 1);
                ptTest[5] = new Point(ptCDLoc.X - 2, ptCDLoc.Y - 2);
                ptTest[6] = new Point(ptCDLoc.X - 3, ptCDLoc.Y);
                ptTest[7] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 1);
                ptTest[8] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 2);
                ptTest[9] = new Point(ptCDLoc.X - 3, ptCDLoc.Y - 3);
                ptTest[10] = new Point(ptCDLoc.X - 4, ptCDLoc.Y);
                ptTest[11] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 1);
                ptTest[12] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 2);
                ptTest[13] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 3);
                ptTest[14] = new Point(ptCDLoc.X - 4, ptCDLoc.Y - 4);

                ptTest[15] = new Point(ptCDLoc.X + 1, ptCDLoc.Y);
                ptTest[16] = new Point(ptCDLoc.X + 1, ptCDLoc.Y - 1);
                ptTest[17] = new Point(ptCDLoc.X + 2, ptCDLoc.Y);
                ptTest[18] = new Point(ptCDLoc.X + 2, ptCDLoc.Y - 1);
                ptTest[19] = new Point(ptCDLoc.X + 2, ptCDLoc.Y - 2);
                ptTest[20] = new Point(ptCDLoc.X + 3, ptCDLoc.Y);
                ptTest[21] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 1);
                ptTest[22] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 2);
                ptTest[23] = new Point(ptCDLoc.X + 3, ptCDLoc.Y - 3);
                ptTest[24] = new Point(ptCDLoc.X + 4, ptCDLoc.Y);
                ptTest[25] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 1);
                ptTest[26] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 2);
                ptTest[27] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 3);
                ptTest[28] = new Point(ptCDLoc.X + 4, ptCDLoc.Y - 4);

                ptTest[29] = new Point(ptCDLoc.X, ptCDLoc.Y + 1);
                ptTest[30] = new Point(ptCDLoc.X - 1, ptCDLoc.Y + 1);
                ptTest[31] = new Point(ptCDLoc.X - 2, ptCDLoc.Y + 1);
                ptTest[32] = new Point(ptCDLoc.X - 2, ptCDLoc.Y + 2);
                ptTest[33] = new Point(ptCDLoc.X - 3, ptCDLoc.Y);
                ptTest[34] = new Point(ptCDLoc.X - 3, ptCDLoc.Y + 1);
                ptTest[35] = new Point(ptCDLoc.X - 3, ptCDLoc.Y + 2);
                ptTest[36] = new Point(ptCDLoc.X - 3, ptCDLoc.Y + 3);
                ptTest[37] = new Point(ptCDLoc.X - 4, ptCDLoc.Y);
                ptTest[38] = new Point(ptCDLoc.X - 4, ptCDLoc.Y + 1);
                ptTest[39] = new Point(ptCDLoc.X - 4, ptCDLoc.Y + 2);
                ptTest[40] = new Point(ptCDLoc.X - 4, ptCDLoc.Y + 3);
                ptTest[41] = new Point(ptCDLoc.X - 4, ptCDLoc.Y + 4);

                ptTest[42] = new Point(ptCDLoc.X + 1, ptCDLoc.Y);
                ptTest[43] = new Point(ptCDLoc.X + 1, ptCDLoc.Y + 1);
                ptTest[44] = new Point(ptCDLoc.X + 2, ptCDLoc.Y);
                ptTest[45] = new Point(ptCDLoc.X + 2, ptCDLoc.Y + 1);
                ptTest[46] = new Point(ptCDLoc.X + 2, ptCDLoc.Y + 2);
                ptTest[47] = new Point(ptCDLoc.X + 3, ptCDLoc.Y);
                ptTest[48] = new Point(ptCDLoc.X + 3, ptCDLoc.Y + 1);
                ptTest[49] = new Point(ptCDLoc.X + 3, ptCDLoc.Y + 2);
                ptTest[50] = new Point(ptCDLoc.X + 3, ptCDLoc.Y + 3);
                ptTest[51] = new Point(ptCDLoc.X + 4, ptCDLoc.Y);
                ptTest[52] = new Point(ptCDLoc.X + 4, ptCDLoc.Y + 1);
                ptTest[53] = new Point(ptCDLoc.X + 4, ptCDLoc.Y + 2);
                ptTest[54] = new Point(ptCDLoc.X + 4, ptCDLoc.Y + 3);
                ptTest[55] = new Point(ptCDLoc.X + 4, ptCDLoc.Y + 4);
            }

            for (int intCounter = 0; intCounter < ptTest.Length ; intCounter++)
            {
                if (!objectHitsWall(ptTest[intCounter], Jessica.udrCDInfo))
                {
                    // calculate how much to move Jessica
                    Point ptMove = new Point(ptTest[intCounter].X - ptCDLoc.X, ptTest[intCounter].Y - ptCDLoc.Y);
                    if (ptMove.X != 0 || ptMove.Y != 0)
                    {
                        // while Jessica is asleep her true position is 
                        Point ptCDLocBeforeSleep = getCDLoc(Jessica.ptLocBeforeSleepShift);
                        Point ptCDLocAfter = new Point(ptCDLocBeforeSleep.X + ptMove.X, ptCDLocBeforeSleep.Y + ptMove.Y);
                        Jessica.ptLocBeforeSleepShift = getRealLoc(ptCDLocAfter);
                    }
                    return;
                }
            }
        }

        bool objectHitsWall(Point ptCDLoc, udtCDInfo udrCDInfo)
        {
            return RightSideOfObjectsHitsWall(ptCDLoc, udrCDInfo)
                || LeftSideOfObjectsHitsWall(ptCDLoc, udrCDInfo)
                || BottomOfObjectHitsWall(ptCDLoc, udrCDInfo);
        }

        bool RightSideOfObjectsHitsWall(Point ptCDLoc, udtCDInfo udrCDInfo)
        {
            for (int intY = 0; intY < udrCDInfo.sz.Height; intY++)
            {
                Point ptTest = new Point(ptCDLoc.X + udrCDInfo.sz.Width - udrCDInfo.ptRelPos.X - 1, ptCDLoc.Y - udrCDInfo.ptRelPos.Y + intY);
                if (isValidCDMapLoc(ptTest))
                    if (PtOnMapIsCollision(ptTest))
                        return true;
            }
            return false;
        }

        bool LeftSideOfObjectsHitsWall(Point ptCDLoc, udtCDInfo udrCDInfo)
        {
            for (int intY = 0; intY < udrCDInfo.sz.Height; intY++)
            {
                Point ptTest = new Point(ptCDLoc.X - udrCDInfo.ptRelPos.X, ptCDLoc.Y - udrCDInfo.ptRelPos.Y + intY);
                if (isValidCDMapLoc(ptTest))
                    if (PtOnMapIsCollision(ptTest))
                        return true;
            }
            return false;
        }

        bool BottomOfObjectHitsWall(Point ptCDLoc, udtCDInfo udrCDInfo)
        {
            for (int intX = 0; intX < udrCDInfo.sz.Width; intX++)
            {
                Point ptTest = new Point(ptCDLoc.X - udrCDInfo.ptRelPos.X + intX, ptCDLoc.Y - udrCDInfo.ptRelPos.Y - 1);
                if (isValidCDMapLoc(ptTest))
                    if (PtOnMapIsCollision(ptTest))
                        return true;
            }
            return false;
        }

        double getHypotenuse(Point pt1, Point pt2) { return Math.Sqrt(Math.Pow(pt1.X - pt2.X, 2) + Math.Pow(pt1.Y - pt2.Y, 2)); }

        Point getCanSeePoint(Point ptRealPoint)
        {
            return new Point(ptRealPoint.X / intCanISeeJessicaGridSize + intCanISeeJessicaGridSize / 2,
                             ptRealPoint.Y / intCanISeeJessicaGridSize + intCanISeeJessicaGridSize / 2);
        }

        int getCanSeeIndex(Point ptCanSee) { return ptCanSee.X * szCanISeeJessica.Height + ptCanSee.Y; }

        public bool JessicaCanBeSeenFromHere(Point ptLoc)
        {
            Point pt1 = getCDLoc(ptLoc), pt2 = getCDLoc(Jessica.ptLoc);
            
            Point ptCanSee1 = getCanSeePoint(pt1);
            Point ptCanSee2 = getCanSeePoint(pt2);

            Point ptCanSeeTableAddress = new Point(getCanSeeIndex(ptCanSee1), getCanSeeIndex(ptCanSee2));
            enuCanISeeJessica CanSeeTableEntry = CanISeeJessicaTable[ptCanSeeTableAddress.X, ptCanSeeTableAddress.Y];

            switch (CanSeeTableEntry)
            {
                case enuCanISeeJessica.unknown:
                    bool bolRetVal = JessicaCanBeSeenFromHere_Short(ptLoc);
                    CanISeeJessicaTable[ptCanSeeTableAddress.X, ptCanSeeTableAddress.Y] = bolRetVal ? enuCanISeeJessica.yes : enuCanISeeJessica.no;
                    return bolRetVal;

                case enuCanISeeJessica.no:
                    return false;

                case enuCanISeeJessica.yes:
                    return true;
            }

            System.Windows.Forms.MessageBox.Show("this should not happen");
            return false; 
        }

        public bool JessicaCanBeSeenFromHere_Short(Point ptLoc)
        {
            enuDir dir = cLibHelper.getDirBetweenTwoPoints(ptLoc, Jessica.ptLoc);
            Point ptTestA, ptTestB;

            switch (dir)
            {
                case enuDir.N_:
                    ptTestA = ptJessicaBL;
                    ptTestB = ptJessicaBR;
                    break;

                case enuDir.NE:
                    ptTestA = ptJessicaTL;
                    ptTestB = ptJessicaBR;
                    break;

                case enuDir.E_:
                    ptTestA = ptJessicaTL;
                    ptTestB = ptJessicaBL;
                    break;

                case enuDir.SE:
                    ptTestA = ptJessicaTR;
                    ptTestB = ptJessicaBL;
                    break;

                case enuDir.S_:
                    ptTestA = ptJessicaTL;
                    ptTestB = ptJessicaTR;
                    break;

                case enuDir.SW:
                    ptTestA = ptJessicaTL;
                    ptTestB = ptJessicaBR;
                    break;

                case enuDir.W_:
                    ptTestA = ptJessicaTR;
                    ptTestB = ptJessicaBR;
                    break;

                case enuDir.NW:
                default:
                    ptTestA = ptJessicaTR;
                    ptTestB = ptJessicaBL;
                    break;
            }

            bool retVal = !collisionBetweenTwoCDPoints(getCDLoc( ptLoc), ptTestA, true, true)
                       || !collisionBetweenTwoCDPoints(getCDLoc(ptLoc), ptTestB, true, true)
                       || !collisionBetweenTwoCDPoints(getCDLoc(ptLoc), getCDLoc(Jessica.ptLoc), true, true);

            return retVal;
        }

        /// <summary>
        /// tests if there is a clear straight line path between two points, e.g. line-of-sight
        /// </summary>
        /// <param name="pt1">real map point location A</param>
        /// <param name="pt2">real map point location B</param>
        /// <returns>returns true if there is a wall obstructing a straight line test between the two points</returns>
        public bool collisionBetweenTwoPoints(Point pt1, Point pt2) { return collisionBetweenTwoCDPoints(getCDLoc(pt1), getCDLoc(pt2)); }

        /// <summary>
        /// tests if there is a clear straight line path between two points, e.g. line-of-sight
        /// this call will consider collisions with the bunker door
        /// </summary>
        /// <param name="pt1">CD-map point location A</param>
        /// <param name="pt2">CD-map point location B</param>
        /// <returns>returns true if there is a wall obstructing a straight line test between the two points</returns>
        bool collisionBetweenTwoCDPoints(Point pt1, Point pt2) { return collisionBetweenTwoCDPoints(pt1, pt2, false, false); }

        /// <summary>
        /// tests if there is a clear straight line path between two points, e.g. line-of-sight
        /// </summary>
        /// <param name="pt1">CD-map point location A</param>
        /// <param name="pt2">CD-map point location B</param>
        /// <param name="bolIgnoreBunkerDoor">bullets should not ignore bunker door but Jessica must</param>
        /// <param name="bolIgnoreBunkerWalls">bullets should not ignore bunker walls but robots can see through</param>
        /// <returns>returns true if there is a wall obstructing a straight line test between the two points</returns>
        bool collisionBetweenTwoCDPoints(Point pt1, Point pt2, bool bolIgnoreBunkerDoor, bool bolIgnoreBunkerWalls)
        {
            Point ptTL = new Point(pt1.X < pt2.X ? pt1.X : pt2.X, pt1.Y < pt2.Y ? pt1.Y : pt2.Y);
            Point ptBR = new Point(pt1.X > pt2.X ? pt1.X : pt2.X, pt1.Y > pt2.Y ? pt1.Y : pt2.Y);

            if (pt1.X > pt2.X)
            {
                Point ptTemp = new Point(pt2.X, pt2.Y);
                pt2 = new Point(pt1.X, pt1.Y);
                pt1 = new Point(ptTemp.X, ptTemp.Y);
            }

            // traverse line for every X
            // y = mx + b
            // calculate slope of the line
            double m = (double)(pt2.Y - pt1.Y) / (double)(pt2.X - pt1.X);
            // calculate y offset 'b'
            int b = pt2.Y - (int)(m * pt2.X);

            for (int intX = pt1.X; intX <= pt2.X; intX++)
            {
                int intLeft = (intX) * intPixelSize + 1;
                int intY = (int)(m * intX) + b;
                int intTop = (intY) * intPixelSize + 1;
                if (intY >= ptTL.Y && intY <= ptBR.Y)
                {
                    if (isValidCDMapLoc(new Point( intX, intY)))
                    {
                        Color clrThisPix = bmpCD.GetPixel(intX, intY);
                        if (clrThisPix == clrCollision
                            || (clrThisPix == clrBunkerDoor && !bolIgnoreBunkerDoor)
                            || (clrThisPix == clrBunkerWalls && !bolIgnoreBunkerWalls))
                            return true;
                    }
                }
            }

            Point ptStart = new Point();
            Point ptEnd = new Point();
            // traverse line for every Y
            // x = (y-b)/m
            if (pt1.Y < pt2.Y)
            {
                ptStart = pt1;
                ptEnd = pt2;
            }
            else
            {
                ptStart = pt2;
                ptEnd = pt1;
            }

            for (int intY = ptStart.Y; intY <= ptEnd.Y; intY++)
            {
                int intX = 0;
                if (ptStart.X == ptEnd.X)
                    intX = ptStart.X;
                else
                    if (intY - b != 0)
                        intX = (int)((intY - b) / m);
                    else
                    {
                        intX = ptStart.X;
                    }
                int intTop = (intY) * intPixelSize + 1;
                int intLeft = (intX) * intPixelSize + 1;
                if (intX >= ptTL.X && intX <= ptBR.X)
                {
                    if (isValidCDMapLoc(new Point(intX, intY)))
                    {
                        Color clrThisPix = bmpCD.GetPixel(intX, intY);
                        if (clrThisPix == clrCollision
                            || (clrThisPix == clrBunkerDoor && !bolIgnoreBunkerDoor))
                            return true;
                    }
                }
            }
            return false;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Christ Kennedy
CEO unemployable
Canada Canada
Christ Kennedy, published his fourth novel "Cleats of the Counter Revolution" in the summer of 2010. He grew up in the suburbs of Montreal and is a bilingual Quebecois with a bachelor’s degree in computer engineering from McGill University and is currently walking across ontario plotting a new novel, far away from any computer.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150901.1 | Last Updated 27 Jan 2010
Article Copyright 2010 by Christ Kennedy
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid