00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #include "TBadGuy.h"
00015 #include "TPlayersShip.h"
00016 #include "TBullet.h"
00017 #include "CGame.h"
00018 #include "TGamePanics.h"
00019
00020 #include "TMapLineType.h"
00021 #include "TPathLineType.h"
00022
00024 TBadGuy::TBadGuy() {
00025
00026 }
00027
00040 void TBadGuy::Init(TInt16 aType,const TInt16 aArgs[]) {
00041 SetSpriteNo(aArgs[0]);
00042 iX=aArgs[1];
00043 iY=aArgs[2];
00044 iHealth=aArgs[3];
00045 iXVel=0;
00046 iYVel=aArgs[5];
00047 iFlags=0;
00048 iPath=0;
00049 iId=0;
00050 iCounter=0;
00051
00052 if(aType & EMapLineObjectMovementMapRelative) {
00053 iFlags |= TBadGuyFlags::EMapRelative;
00054 }
00055
00056 if(aType & EMapLineObjectMovementSimple) {
00057 iXVel=aArgs[4];
00058 iFlags |= TBadGuyFlags::ESimpleMoves;
00059 if(aType & EMapLineObjectMovementBounceTop)
00060 iFlags |= TBadGuyFlags::EBounceTop;
00061 if(aType & EMapLineObjectMovementBounceBottom)
00062 iFlags |= TBadGuyFlags::EBounceBottom;
00063 if(aType & EMapLineObjectMovementBounceLeft)
00064 iFlags |= TBadGuyFlags::EBounceLeft;
00065 if(aType & EMapLineObjectMovementBounceRight)
00066 iFlags |= TBadGuyFlags::EBounceRight;
00067
00068 } else if(aType & EMapLineObjectMovementHoming) {
00069 iXVel=aArgs[4];
00070 iFlags |= TBadGuyFlags::ESimpleMoves;
00071 if(aType & EMapLineObjectMovementHomingX)
00072 iFlags |= TBadGuyFlags::EHomingX;
00073 if(aType & EMapLineObjectMovementHomingY)
00074 iFlags |= TBadGuyFlags::EHomingY;
00075
00076 } else if(aType & EMapLineObjectMovementPath) {
00077 iPath=aArgs[4];
00078 iXVel=0;
00079 iFlags |= TBadGuyFlags::EPathMove;
00080 }
00081
00082
00083 if(aType & EMapLineObjectBadGuy) {
00084 iScore=20;
00085 iFlags |= TBadGuyFlags::EKillsPlayer;
00086 iId=aArgs[6];
00087
00088
00089 if(iHealth < 0) {
00090 iHealth=-iHealth;
00091 iFlags |= TBadGuyFlags::EInvunerable;
00092 }
00093 } else if(aType & EMapLineObjectCollectable) {
00094 iFlags |= TBadGuyFlags::ETransparent;
00095
00096
00097 if(aArgs[6]==0)
00098 iFlags |= TBadGuyFlags::EHealthBonus;
00099 else if(aArgs[6]==1)
00100 iFlags |= TBadGuyFlags::ELifeBonus;
00101 else if(aArgs[6]==2)
00102 iFlags |= TBadGuyFlags::EWeaponBonus;
00103 }
00104 }
00105
00106
00170 void TBadGuy::Move(TInt aPlayerX, TInt aPlayerY,
00171 const TInt16 *aPaths,CGame &aGame) {
00172
00173 if(iHealth <= 0) {
00174 iHealth--;
00175 TInt16 spriteno= -(iHealth/2);
00176 spriteno+= aGame.FirstExplosionSprite();
00177 if(spriteno>aGame.LastExplosionSprite())
00178 ClearSprite();
00179 else
00180 SetSpriteNo(spriteno);
00181
00182
00183 } else if(iFlags & TBadGuyFlags::ESimpleMoves) {
00184 SimpleMove(aPlayerX,aPlayerY);
00185
00186
00187 } else if(iFlags & TBadGuyFlags::EPathMove) {
00188 PathMove(aPlayerX,aPlayerY,aPaths,aGame);
00189 }
00190
00191
00192 if(iFlags & TBadGuyFlags::EMapRelative) {
00193 iX+=aGame.MapSpeed();
00194 }
00195
00196
00197 if(iY<-24 || iY>200 || iX<0 || iX>336) {
00198 ClearSprite();
00199 }
00200
00201 }
00202
00203
00214 void TBadGuy::PathMove(TInt16 aPlayerX, TInt16 aPlayerY,
00215 const TInt16 *aPaths, CGame &aGame) {
00216
00217 TBool foundMove=EFalse;
00218
00219
00220 while(foundMove==EFalse) {
00221
00222
00223 switch((TPathLineType) (aPaths[iPath*4])) {
00224 case EPathLineEnd:
00225
00226 foundMove=ETrue;
00227 break;
00228 case EPathLineStart:
00229 iPath+=aPaths[(iPath*4)+1];
00230 break;
00231
00232 case EPathLineClone:
00233 {
00234
00235
00236 TInt oldpath=iPath+aPaths[(iPath*4)+1];
00237
00238 iPath+=aPaths[(iPath*4)+2];
00239 aGame.AddBadGuy(*this);
00240
00241 iPath=oldpath;
00242 }
00243 break;
00244
00245
00246 case EPathLineMoveBy:
00247 iX+=aPaths[(iPath*4)+2];
00248 iY+=aPaths[(iPath*4)+3];
00249 iPath+=aPaths[(iPath*4)+1];
00250 foundMove=ETrue;
00251 break;
00252 case EPathLineMoveTo:
00253 iX=aPaths[(iPath*4)+2];
00254 iY=aPaths[(iPath*4)+3];
00255 iPath+=aPaths[(iPath*4)+1];
00256 foundMove=ETrue;
00257 break;
00258 case EPathLineMoveStepTo: {
00259 if(iX < aPaths[(iPath*4)+2]) {
00260 iX += iXVel;
00261
00262 if(iX > aPaths[(iPath*4)+2])
00263 iX=aPaths[(iPath*4)+2];
00264 } else if(iX > aPaths[(iPath*4)+2]) {
00265 iX -= iXVel;
00266
00267 if(iX < aPaths[(iPath*4)+2])
00268 iX=aPaths[(iPath*4)+2];
00269 }
00270
00271 if(iY < aPaths[(iPath*4)+3]) {
00272 iY += iYVel;
00273
00274 if(iY > aPaths[(iPath*4)+3])
00275 iY=aPaths[(iPath*4)+3];
00276 } else if(iY > aPaths[(iPath*4)+3]) {
00277 iY -= iYVel;
00278
00279 if(iY < aPaths[(iPath*4)+3])
00280 iY=aPaths[(iPath*4)+3];
00281 }
00282
00283
00284 if(iX == aPaths[(iPath*4)+2] &&
00285 iY == aPaths[(iPath*4)+3]) {
00286 iPath+=aPaths[(iPath*4)+1];
00287 }
00288 foundMove=ETrue;
00289 break;
00290 }
00291 case EPathLineMoveSimple:
00292 SimpleMove(aPlayerX,aPlayerY);
00293 iPath+=aPaths[(iPath*4)+1];
00294 foundMove=ETrue;
00295 break;
00296
00297
00298
00299
00300
00301 case EPathLineIfXVelLess:
00302 if(iXVel < aPaths[(iPath*4)+3]) {
00303 iPath+=aPaths[(iPath*4)+2];
00304 } else {
00305 iPath+=aPaths[(iPath*4)+1];
00306 }
00307 break;
00308 case EPathLineIfXVelGreater:
00309 if(iXVel > aPaths[(iPath*4)+3]) {
00310 iPath+=aPaths[(iPath*4)+2];
00311 } else {
00312 iPath+=aPaths[(iPath*4)+1];
00313 }
00314 break;
00315 case EPathLineIfXVelEqual:
00316 if(iXVel == aPaths[(iPath*4)+3]) {
00317 iPath+=aPaths[(iPath*4)+2];
00318 } else {
00319 iPath+=aPaths[(iPath*4)+1];
00320 }
00321 break;
00322 case EPathLineIfYVelLess:
00323 if(iYVel < aPaths[(iPath*4)+3]) {
00324 iPath+=aPaths[(iPath*4)+2];
00325 } else {
00326 iPath+=aPaths[(iPath*4)+1];
00327 }
00328 break;
00329 case EPathLineIfYVelGreater:
00330 if(iYVel > aPaths[(iPath*4)+3]) {
00331 iPath+=aPaths[(iPath*4)+2];
00332 } else {
00333 iPath+=aPaths[(iPath*4)+1];
00334 }
00335 break;
00336 case EPathLineIfYVelEqual:
00337 if(iYVel == aPaths[(iPath*4)+3]) {
00338 iPath+=aPaths[(iPath*4)+2];
00339 } else {
00340 iPath+=aPaths[(iPath*4)+1];
00341 }
00342 break;
00343
00344 case EPathLineIfXLess:
00345 if(iX < aPaths[(iPath*4)+3]) {
00346 iPath+=aPaths[(iPath*4)+2];
00347 } else {
00348 iPath+=aPaths[(iPath*4)+1];
00349 }
00350 break;
00351 case EPathLineIfXGreater:
00352 if(iX > aPaths[(iPath*4)+3]) {
00353 iPath+=aPaths[(iPath*4)+2];
00354 } else {
00355 iPath+=aPaths[(iPath*4)+1];
00356 }
00357 break;
00358 case EPathLineIfXEqual:
00359 if(iX == aPaths[(iPath*4)+3]) {
00360 iPath+=aPaths[(iPath*4)+2];
00361 } else {
00362 iPath+=aPaths[(iPath*4)+1];
00363 }
00364 break;
00365 case EPathLineIfYLess:
00366 if(iY < aPaths[(iPath*4)+3]) {
00367 iPath+=aPaths[(iPath*4)+2];
00368 } else {
00369 iPath+=aPaths[(iPath*4)+1];
00370 }
00371 break;
00372 case EPathLineIfYGreater:
00373 if(iY > aPaths[(iPath*4)+3]) {
00374 iPath+=aPaths[(iPath*4)+2];
00375 } else {
00376 iPath+=aPaths[(iPath*4)+1];
00377 }
00378 break;
00379 case EPathLineIfYEqual:
00380 if(iY == aPaths[(iPath*4)+3]) {
00381 iPath+=aPaths[(iPath*4)+2];
00382 } else {
00383 iPath+=aPaths[(iPath*4)+1];
00384 }
00385 break;
00386
00387 case EPathLineIfHealthLess:
00388 if(iHealth < aPaths[(iPath*4)+3]) {
00389 iPath+=aPaths[(iPath*4)+2];
00390 } else {
00391 iPath+=aPaths[(iPath*4)+1];
00392 }
00393 break;
00394 case EPathLineIfHealthGreater:
00395 if(iHealth > aPaths[(iPath*4)+3]) {
00396 iPath+=aPaths[(iPath*4)+2];
00397 } else {
00398 iPath+=aPaths[(iPath*4)+1];
00399 }
00400 break;
00401 case EPathLineIfHealthEqual:
00402 if(iHealth == aPaths[(iPath*4)+3]) {
00403 iPath+=aPaths[(iPath*4)+2];
00404 } else {
00405 iPath+=aPaths[(iPath*4)+1];
00406 }
00407 break;
00408 case EPathLineIfCounterLess:
00409 if(iCounter < aPaths[(iPath*4)+3]) {
00410 iPath+=aPaths[(iPath*4)+2];
00411 } else {
00412 iPath+=aPaths[(iPath*4)+1];
00413 }
00414 break;
00415 case EPathLineIfCounterGreater:
00416 if(iCounter > aPaths[(iPath*4)+3]) {
00417 iPath+=aPaths[(iPath*4)+2];
00418 } else {
00419 iPath+=aPaths[(iPath*4)+1];
00420 }
00421 break;
00422 case EPathLineIfCounterEqual:
00423 if(iCounter == aPaths[(iPath*4)+3]) {
00424 iPath+=aPaths[(iPath*4)+2];
00425 } else {
00426 iPath+=aPaths[(iPath*4)+1];
00427 }
00428 break;
00429
00430
00431 case EPathLineSetPoints:
00432 iScore = aPaths[(iPath*4)+2];
00433 iPath+=aPaths[(iPath*4)+1];
00434 break;
00435 case EPathLineSetId:
00436 iId = aPaths[(iPath*4)+2];
00437 iPath+=aPaths[(iPath*4)+1];
00438 break;
00439 case EPathLineSetHealth:
00440 iHealth = aPaths[(iPath*4)+2];
00441
00442 if(iHealth <= 0) {
00443 Die(aGame);
00444
00445 foundMove=ETrue;
00446 }
00447 iPath+=aPaths[(iPath*4)+1];
00448 break;
00449 case EPathLineAddHealth:
00450 iHealth += aPaths[(iPath*4)+2];
00451
00452 if(iHealth <= 0) {
00453 Die(aGame);
00454
00455 foundMove=ETrue;
00456 }
00457 iPath+=aPaths[(iPath*4)+1];
00458 break;
00459 case EPathLineSetVelocity:
00460 iXVel=aPaths[(iPath*4)+2];
00461 iYVel=aPaths[(iPath*4)+3];
00462 iPath+=aPaths[(iPath*4)+1];
00463 break;
00464 case EPathLineAddVelocity:
00465 iXVel+=aPaths[(iPath*4)+2];
00466 iYVel+=aPaths[(iPath*4)+3];
00467 iPath+=aPaths[(iPath*4)+1];
00468 break;
00469 case EPathLineSetSprite:
00470 SetSpriteNo(aPaths[(iPath*4)+2]);
00471 iPath+=aPaths[(iPath*4)+1];
00472 break;
00473 case EPathLineSetClearFlags:
00474 iFlags |= aPaths[(iPath*4)+2];
00475 iFlags &= ~(aPaths[(iPath*4)+3]);
00476 iPath+=aPaths[(iPath*4)+1];
00477 break;
00478 case EPathLineSetCounter:
00479 iCounter = aPaths[(iPath*4)+2];
00480 iPath+=aPaths[(iPath*4)+1];
00481 break;
00482 case EPathLineAddCounter:
00483 iCounter += aPaths[(iPath*4)+2];
00484 iPath+=aPaths[(iPath*4)+1];
00485 break;
00486
00487 }
00488 }
00489 }
00490
00500 void TBadGuy::SimpleMove(TInt16 aPlayerX, TInt16 aPlayerY) {
00501 if(iFlags & TBadGuyFlags::EHomingX) {
00502 if(iX < aPlayerX) {
00503 iX += iXVel;
00504 if(iX > aPlayerX)
00505 iX=aPlayerX;
00506 } else if(iX > aPlayerX) {
00507 iX -= iXVel;
00508 if(iX < aPlayerX)
00509 iX=aPlayerX;
00510 }
00511 } else {
00512 iX+=iXVel;
00513 if( (iX>303 && (iFlags & TBadGuyFlags::EBounceRight)) ||
00514 (iX<16 && (iFlags & TBadGuyFlags::EBounceLeft))) {
00515 iXVel= -iXVel;
00516 iX+= iXVel;
00517 }
00518 }
00519
00520 if(iFlags & TBadGuyFlags::EHomingY) {
00521 if(iY < aPlayerY) {
00522 iY += iYVel;
00523 if(iY > aPlayerY)
00524 iY=aPlayerY;
00525 } else if(iY > aPlayerY) {
00526 iY -= iYVel;
00527 if(iY < aPlayerY)
00528 iY=aPlayerY;
00529 }
00530 } else {
00531 iY+=iYVel;
00532 if((iY<0 && (iFlags & TBadGuyFlags::EBounceTop)) ||
00533 (iY>176 && (iFlags & TBadGuyFlags::EBounceBottom))) {
00534 iYVel= -iYVel;
00535 iY+= iYVel;
00536 }
00537 }
00538 }
00539
00549 void TBadGuy::HitBullet(TBullet& aBullet, CGame &aGame) {
00550 if(iHealth<=0)
00551 return;
00552
00553 if(iFlags & TBadGuyFlags::EInvunerable) {
00554
00555 aBullet.ClearSprite();
00556 } else if(iFlags & TBadGuyFlags::ETransparent) {
00557
00558 } else {
00559
00560
00561 TInt damageTaken=aBullet.Health();
00562 if(damageTaken > iHealth)
00563 damageTaken=iHealth;
00564
00565 if(damageTaken<0) {
00566 TGamePanics::Panic(TGamePanics::ENegativeDamage);
00567 }
00568
00569 aBullet.AddHealth(-damageTaken);
00570
00571 if(iId > 0) {
00572 aGame.DamageBadGuys(iId,damageTaken);
00573 } else if(iId < 0) {
00574
00575
00576 aGame.DamageBadGuys(-iId,damageTaken);
00577 Damage(damageTaken,aGame);
00578 } else {
00579 Damage(damageTaken,aGame);
00580 }
00581 }
00582 }
00583
00593 void TBadGuy::HitShip(TPlayersShip &aShip, CGame &aGame) {
00594 if(iHealth<=0)
00595 return;
00596
00597 if(iFlags & TBadGuyFlags::EKillsPlayer) {
00598 if(iFlags & TBadGuyFlags::EInvunerable) {
00599 aShip.SetHealth(0);
00600 } else {
00601 aShip.AddHealth(-iHealth);
00602 }
00603
00604
00605
00606 if(iId > 0) {
00607 aGame.DamageBadGuys(iId,iHealth);
00608 } else if(iId < 0) {
00609
00610
00611 aGame.DamageBadGuys(-iId,iHealth);
00612 Damage(iHealth,aGame);
00613 } else {
00614 Damage(iHealth,aGame);
00615 }
00616
00617
00618 } else {
00619 if(iFlags & TBadGuyFlags::EHealthBonus) {
00620 aShip.AddHealth(iHealth);
00621 }
00622 if(iFlags & TBadGuyFlags::ELifeBonus) {
00623 aGame.Bonus(CGame::EBonusLife);
00624 }
00625 if(iFlags & TBadGuyFlags::EWeaponBonus) {
00626 aGame.Bonus(CGame::EBonusPowerup);
00627 }
00628 Die(aGame);
00629 }
00630 }
00631
00638 void TBadGuy::Damage(TInt aHealth, CGame &aGame) {
00639 iHealth-= aHealth;
00640 if(iHealth <=0) {
00641 Die(aGame);
00642 }
00643 }
00644
00653 void TBadGuy::Die(CGame &aGame) {
00654 iHealth=0;
00655 if(iFlags & TBadGuyFlags::EKillsPlayer) {
00656 aGame.AddScore(iScore);
00657 } else {
00658 ClearSprite();
00659 }
00660 }
00661
00667 TInt16 TBadGuy::Id() {
00668 return iId;
00669 }
00670