using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Night_Stalker
{
public class classBullet
{
static int uniqueIDCounter;
int myUniqueIdNumber = uniqueIDCounter++;
public classCollisionDetection.udtCDInfo udrCDInfo = new classCollisionDetection.udtCDInfo();
public Point pt;
public double dblAngle;
enuDir dir;
public bool bolJessicafireedThisBullet = false;
int intStepSize = 10;
int intDamageICause = 25;
public classRobot robotThatShotMe;
public classBullet next;
public classBullet prev;
public bool bolDead;
static Microsoft.DirectX.AudioVideoPlayback.Audio DXHardHit;
public enum bulletType { colt, laser, SmurfAttack, FelixFire, bulletEater, bunkerBuster }
public bulletType myType;
classCollisionDetection cLibCD;
classHelperFunctions cLibHelper;
public static Sprite.classSprite[] sprite;
public int intConfig, intConfigStep, intSizeStep;
Sprite.enuMirror mirror = Sprite.enuMirror.none;
public enum enuColt_Configurations // same as laser & Smurf-attack
{
fly_up,
fly_high,
fly_straight,
fly_low,
fly_down,
_numCon
}
public enum enuFelix_Fire_Configurations
{
fly_high,
fly_straight,
fly_low,
_numCon
}
public classBullet(bulletType type,
Point ptLoc,
double dblTravelDirection,
bool bolJessicaBullet,
ref classHelperFunctions Helper)
{
cLibHelper = Helper;
cLibCD = cLibHelper.cLibCD;
myType = type;
pt = ptLoc;
dblAngle = dblTravelDirection;
dir = convertAngleToDir(dblAngle);
setConfig();
bolJessicafireedThisBullet = bolJessicaBullet;
setCDInfo();
setStepSize();
bolDead = false;
if (DXHardHit == null)
{
string strDirectorAndFilename = cLibHelper.getResourceDirectoryString() + cLibHelper.strDX_HitHard;
DXHardHit = new Microsoft.DirectX.AudioVideoPlayback.Audio(strDirectorAndFilename);
initSprites();
}
if (myType == bulletType.bunkerBuster)
cLibHelper.bulletDebug = this;
}
/// <summary>
/// DO NOT USE WITH ANY THING OTHER THAN THE BULLETS!
/// </summary>
/// <param name="angleRad"></param>
/// <returns></returns>
enuDir convertAngleToDir(double angleRad)
{
int intAngle = (int)(cLibHelper.cleanAngle(angleRad) * 180 / Math.PI);
int intE = 180/8;
int intStep = 180/4;
if (intAngle < intE)
return enuDir.E_;
else if (intAngle < (intE + intStep))
return enuDir.SE;
else if (intAngle < (intE + 2 * intStep))
return enuDir.S_;
else if (intAngle < (intE + 3 * intStep))
return enuDir.SW;
else if (intAngle < (intE + 4 * intStep))
return enuDir.W_;
else if (intAngle < (intE + 5 * intStep))
return enuDir.NW;
else if (intAngle < (intE + 6 * intStep))
return enuDir.N_;
else
return enuDir.NE;
}
void initSprites()
{
sprite = new Sprite.classSprite[6];
Sprite.classSpriteMaker cLibSpriteMaker = new Sprite.classSpriteMaker();
string strDir = cLibHelper.getResourceDirectoryString();
sprite[(int)bulletType.colt] = cLibSpriteMaker.loadSprite(strDir + "colt.spr");
sprite[(int)bulletType.laser] = cLibSpriteMaker.loadSprite(strDir + "laser.spr");
sprite[(int)bulletType.FelixFire] = cLibSpriteMaker.loadSprite(strDir + "FelixFire.spr");
sprite[(int)bulletType.bulletEater] = cLibSpriteMaker.loadSprite(strDir + "bulleteater.spr");
sprite[(int)bulletType.SmurfAttack] = cLibSpriteMaker.loadSprite(strDir + "Smurf-attack.spr");
sprite[(int)bulletType.bunkerBuster] = cLibSpriteMaker.loadSprite(strDir + "bunkerbuster.spr");
}
void animateNext(ref Bitmap bmpMap)
{
if (next != null)
next.animate(ref bmpMap);
}
void die()
{
if (cLibCD.bulletQ == this)
cLibCD.bulletQ = this.next;
if (prev != null)
prev.next = next;
if (next != null)
next.prev = prev;
if (bolJessicafireedThisBullet)
cLibCD.Jessica.bolMyBulletIsStillFlying = false;
bolDead = true;
}
public void animate(ref Bitmap bmpMap)
{
Point ptNewLoc = new Point((int)(pt.X + (double)intStepSize * Math.Cos(dblAngle)),
(int)(pt.Y + (double)intStepSize * Math.Sin(dblAngle)));
bool bolDie = false;
if (IHitAWall(ref ptNewLoc))
{
animateNext(ref bmpMap);
bolDie = true;
}
if (bolJessicafireedThisBullet)
{
classRobot robotIHit = IHitARobot(ref ptNewLoc);
if (robotIHit != null)
{
robotIHit.Hit(intDamageICause);
if (robotIHit.bolDead)
cLibCD.Jessica.Score(robotIHit.getMyValue());
else
{
cLibHelper.playSound(DXHardHit);
bolDie = true;
}
}
if (IHitBulletEater(ref ptNewLoc))
{
cLibHelper.playBulletEaten();
bolDie = true;
}
}
else
{
if (IHitJessica(ref ptNewLoc))
{
cLibCD.Jessica.Die();
bolDie = true;
}
classRobot PestIHit = cLibCD.HitAPest(pt, ref ptNewLoc, udrCDInfo);
if (PestIHit != null)
{
PestIHit.Hit(intDamageICause);
if (!PestIHit.bolDead)
bolDie = true;
}
if (myType == bulletType.bulletEater
|| myType == bulletType.bunkerBuster)
{
if (cLibHelper.cLibCD.Jessica.myBullet != null
&& !cLibCD.Jessica.myBullet.bolDead)
{
int intLimit = intStepSize * 2;
int intDistance = (int)Math.Sqrt(Math.Pow(ptNewLoc.X - robotThatShotMe.Jessica.myBullet.pt.X, 2) + Math.Pow(ptNewLoc.Y - robotThatShotMe.Jessica.myBullet.pt.Y, 2));
Point ptRememberLoc = ptNewLoc;
if (intDistance < intLimit)
if (cLibCD.CollisionBetweenTwoCDInfoObjects(pt, ref ptNewLoc, udrCDInfo, robotThatShotMe.Jessica.myBullet.pt, robotThatShotMe.Jessica.myBullet.udrCDInfo))
{
robotThatShotMe.Jessica.myBullet.bolDead = true;
cLibHelper.playBulletEaten();
}
ptNewLoc = ptRememberLoc;
}
}
}
pt = ptNewLoc;
switch (myType)
{
case bulletType.colt:
case bulletType.laser:
case bulletType.SmurfAttack:
case bulletType.FelixFire:
sprite[(int)myType].putConfigurationOnScreen(ref bmpMap, intConfig,0 , ptNewLoc,0,1.0, mirror, false);
break;
case bulletType.bulletEater:
case bulletType.bunkerBuster:
intConfigStep = (intConfigStep + 1) % sprite[(int)bulletType.bulletEater].Configurations[0].steps.Length;
intSizeStep = (intSizeStep+1) % 8;
double dblSize = 1.0;
switch (intSizeStep)
{
case 0 :
dblSize = 0.2;
break;
case 1:
dblSize = 0.4;
break;
case 2 :
dblSize = 0.6;
break;
case 3:
dblSize = 0.8;
break;
case 4 :
dblSize = 0.9;
break;
case 5:
dblSize = 0.8;
break;
case 6:
dblSize = 0.6;
break;
case 7:
dblSize = 0.4;
break;
}
sprite[(int)myType].putConfigurationOnScreen(ref bmpMap, 0, intConfigStep, ptNewLoc, 0, dblSize, mirror,false);
setCDInfo();
break;
}
setCDInfo();
if (cLibCD.bolDrawCDInfo)
cLibCD.drawCDInfo(ref bmpMap, udrCDInfo, pt);
if (!bolDie)
animateNext(ref bmpMap);
if (bolDie)
die();
}
bool IHitBulletEater(ref Point ptLoc)
{
classBullet thisBullet = cLibCD.bulletQ;
while (thisBullet != null)
{
if (thisBullet != this)
{
if (thisBullet.myType == bulletType.bulletEater
|| thisBullet.myType == bulletType.bunkerBuster)
{
int intLimit = intStepSize * 2;
int intDistance = (int)Math.Sqrt(Math.Pow(ptLoc.X - thisBullet.pt.X, 2) + Math.Pow(ptLoc.Y - thisBullet.pt.Y,2));
if (intDistance < intLimit)
if (cLibCD.CollisionBetweenTwoCDInfoObjects(pt, ref ptLoc, udrCDInfo, thisBullet.pt, thisBullet.udrCDInfo))
return true;
}
}
thisBullet = thisBullet.next;
}
return false;
}
void setConfig()
{
switch (myType)
{
case bulletType.colt:
case bulletType.laser:
case bulletType.SmurfAttack:
switch (dir)
{
case enuDir.E_:
case enuDir.W_:
intConfig = (int)enuColt_Configurations.fly_straight;
break;
case enuDir.NE:
case enuDir.NW:
intConfig = (int)enuColt_Configurations.fly_high;
break;
case enuDir.SE:
case enuDir.SW:
intConfig = (int)enuColt_Configurations.fly_low;
break;
case enuDir.N_:
intConfig = (int)enuColt_Configurations.fly_up;
break;
case enuDir.S_:
intConfig = (int)enuColt_Configurations.fly_down;
break;
}
mirror =Sprite. enuMirror.none;
if (dir >= Night_Stalker.enuDir.N_ && dir < Night_Stalker.enuDir.S_)
mirror = Sprite.enuMirror.horizontal;
break;
case bulletType.FelixFire:
switch (dir)
{
case enuDir.E_:
case enuDir.W_:
case enuDir.N_:
case enuDir.S_:
intConfig = (int)enuFelix_Fire_Configurations.fly_straight;
break;
case enuDir.NE:
case enuDir.SW:
intConfig = (int)enuFelix_Fire_Configurations.fly_high;
break;
case enuDir.NW:
case enuDir.SE:
intConfig = (int)enuFelix_Fire_Configurations.fly_low;
break;
}
break;
case bulletType.bulletEater:
case bulletType.bunkerBuster:
intConfig = 0;
break;
}
}
void setDamageICause()
{
switch (myType)
{
case bulletType.bulletEater:
case bulletType.bunkerBuster:
case bulletType.colt:
case bulletType.laser:
case bulletType.SmurfAttack:
intDamageICause = 25;
break;
}
}
void setStepSize()
{
switch (myType)
{
case bulletType.bulletEater:
case bulletType.bunkerBuster:
case bulletType.colt:
case bulletType.laser:
case bulletType.SmurfAttack:
case bulletType.FelixFire:
default:
intStepSize = (int)(cLibCD.Jessica.intStepSize * 2.0);
break;
}
}
void setCDInfo()
{
switch (myType)
{
case bulletType.bulletEater:
case bulletType.bunkerBuster:
switch (intSizeStep)
{
case 0:
udrCDInfo.ptRelPos = new Point(1, 1);
udrCDInfo.sz = new Size(2, 2);
break;
case 1:
udrCDInfo.ptRelPos = new Point(2, 2);
udrCDInfo.sz = new Size(4, 4);
break;
case 2:
udrCDInfo.ptRelPos = new Point(4, 4);
udrCDInfo.sz = new Size(8, 8);
break;
case 3:
udrCDInfo.ptRelPos = new Point(5, 5);
udrCDInfo.sz = new Size(10, 10);
break;
case 4:
udrCDInfo.ptRelPos = new Point(5, 5);
udrCDInfo.sz = new Size(11, 11);
break;
case 5:
udrCDInfo.ptRelPos = new Point(5, 5);
udrCDInfo.sz = new Size(10, 10);
break;
case 6:
udrCDInfo.ptRelPos = new Point(4, 4);
udrCDInfo.sz = new Size(8, 8);
break;
case 7:
udrCDInfo.ptRelPos = new Point(2, 2);
udrCDInfo.sz = new Size(4, 4);
break;
}
break;
case bulletType.colt:
udrCDInfo.ptRelPos = new Point(1, 1);
udrCDInfo.sz = new Size(2, 2);
break;
case bulletType.laser:
case bulletType.SmurfAttack:
switch (dir)
{
case enuDir.N_:
case enuDir.S_:
udrCDInfo.ptRelPos = new Point(1, 1);
udrCDInfo.sz = new Size(1, 3);
break;
case enuDir.E_:
case enuDir.W_:
udrCDInfo.ptRelPos = new Point(1,1);
udrCDInfo.sz = new Size(3, 1);
break;
default:
udrCDInfo.ptRelPos = new Point(1, 1);
udrCDInfo.sz = new Size(2, 2);
break;
}
break;
case bulletType.FelixFire:
udrCDInfo.ptRelPos = new Point(2, 2);
udrCDInfo.sz = new Size(4, 4);
break;
}
}
/// <summary>
/// tests if this bullet hits Jessica
/// </summary>
/// <returns>returns true if bullet hits Jessica</returns>
public bool IHitJessica(ref Point ptNewLoc)
{
if (bolJessicafireedThisBullet)
return false;
return cLibCD.CollisionBetweenTwoCDInfoObjects(pt, ref ptNewLoc, udrCDInfo, cLibCD.Jessica.ptLoc, cLibCD.Jessica.udrCDInfo);
}
/// <summary>
/// tests if this bullet hits a wall
/// </summary>
/// <returns>returns true if this bullet hits a wall</returns>
public bool IHitAWall(ref Point ptNewLoc)
{
return !cLibCD.move(pt, ref ptNewLoc, udrCDInfo, false, (myType == bulletType.bunkerBuster));
}
/// <summary>
/// tests if this bullet hits a robot only if Jessica fireed this bullet
/// </summary>
/// <returns>returns the robot this bullet hits only if the bullet was fired by Jessica</returns>
public classRobot IHitARobot(ref Point ptNewLoc)
{
if (!bolJessicafireedThisBullet)
return null;
return cLibCD.HitARobot(pt, ref ptNewLoc, udrCDInfo);
}
}
}