00001 00002 // 00003 // Das Tank - Copyright (C) 2006, 2007 Windsor Schmidt <windsor@windsorworld.net> 00004 // 00005 // This program is free software; you can redistribute it and/or modify it 00006 // under the terms of the GNU General Public License as published by the Free 00007 // Software Foundation; either version 2 of the License, or (at your option) 00008 // any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, but WITHOUT 00011 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00013 // more details. 00014 // 00015 // You should have received a copy of the GNU General Public License along with 00016 // this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00017 // Place, Suite 330, Boston, MA 02111-1307 USA 00018 // 00020 00021 00022 #ifndef STDAFX 00023 #include "stdafx.h" 00024 #endif 00025 00026 00032 CVector2D::CVector2D(void) 00033 { 00034 x = 0; 00035 y = 0; 00036 } 00037 00038 00044 CEffect::~CEffect(void) 00045 { 00046 if(PSys) { delete PSys; } 00047 if(SWave) { delete SWave; } 00048 } 00049 00050 00056 CEffect::CEffect(int type) 00057 { 00058 bExpired = false; 00059 00060 PSys = NULL; 00061 SWave = NULL; 00062 MShock = NULL; 00063 TAnim = NULL; 00064 TStorm = NULL; 00065 00066 Previous = NULL; 00067 Next = NULL; 00068 00069 // the effect object is just a flyweight, here we init the object it points to 00070 switch(type) 00071 { 00072 case EFFECTID_NULL: 00073 iType = EFFECTID_NULL; 00074 break; 00075 00076 case EFFECTID_PSYSTEM: 00077 iType = EFFECTID_PSYSTEM; 00078 break; 00079 00080 case EFFECTID_SHOCKWAVE: 00081 iType = EFFECTID_SHOCKWAVE; 00082 break; 00083 00084 case EFFECTID_TILESTORM: 00085 iType = EFFECTID_TILESTORM; 00086 break; 00087 00088 case EFFECTID_TILEANIM: 00089 iType = EFFECTID_TILEANIM; 00090 break; 00091 00092 case EFFECTID_MINISHOCK: 00093 iType = EFFECTID_MINISHOCK; 00094 } 00095 } 00096 00097 00104 void CEffect::Draw(void) 00105 { 00106 // the effect object is just a flyweight, here we draw the object it points to 00107 switch(iType) 00108 { 00109 case EFFECTID_NULL: 00110 break; 00111 00112 case EFFECTID_PSYSTEM: 00113 PSys->Draw(); 00114 break; 00115 00116 case EFFECTID_SHOCKWAVE: 00117 SWave->Draw(); 00118 break; 00119 00120 case EFFECTID_TILESTORM: 00121 TStorm->Draw(); 00122 break; 00123 00124 case EFFECTID_TILEANIM: 00125 TAnim->Draw(); 00126 break; 00127 00128 case EFFECTID_MINISHOCK: 00129 MShock->Draw(); 00130 break; 00131 } 00132 } 00133 00134 00141 bool CEffect::Step(float timeDelta) 00142 { 00143 bool rVal = false; 00144 00145 // the effect object is just a flyweight, here we time-step the object it points to 00146 switch(iType) 00147 { 00148 case EFFECTID_NULL: 00149 break; 00150 00151 case EFFECTID_PSYSTEM: 00152 rVal = PSys->Step(timeDelta); 00153 break; 00154 00155 case EFFECTID_SHOCKWAVE: 00156 rVal = SWave->Step(timeDelta); 00157 break; 00158 00159 case EFFECTID_TILESTORM: 00160 rVal = TStorm->Step(timeDelta); 00161 break; 00162 00163 case EFFECTID_TILEANIM: 00164 rVal = TAnim->Step(timeDelta); 00165 break; 00166 00167 case EFFECTID_MINISHOCK: 00168 rVal = MShock->Step(timeDelta); 00169 } 00170 00171 return rVal; 00172 } 00173 00174 00180 CWorld::CWorld(void) 00181 { 00182 Objects = NULL; // important to ground the list pointers! 00183 PSystems = NULL; 00184 Effects = NULL; 00185 00186 int iX; 00187 for(iX = 0; iX < NUM_PLAYERS; iX++) 00188 { 00189 Player[iX] = NULL; 00190 } 00191 bGameOver = false; 00192 bTakeInput = true; 00193 iStartingState = STARTINGSTATE_IDLE; 00194 iRenderStyle = DEFAULT_RENDERSTYLE; 00195 fZoomBias = 0.5; 00196 iObjectCount = 0; 00197 iEffectCount = 0; 00198 iNumCollisions = 0; 00199 Uint32 iCurrentTime = 0; // milliseconds since SDL init 00200 Uint32 iOldTime = 0; 00201 musicFile = (char *) malloc(sizeof(char) * 256); 00202 } 00203 00204 00210 int CWorld::AddObject(CObject * Obj) 00211 { 00212 if (Objects == NULL) // add the first object in the list 00213 { 00214 Objects = Obj; 00215 } 00216 else // add to the end of the list 00217 { 00218 CObject * Current = Objects; 00219 while(Current->Next != NULL) 00220 { 00221 Current = Current->Next; // traverse the list 00222 } 00223 Current->Next = Obj; // add this object to the end of the list 00224 Obj->Previous = Current; // and create a back-link from the current object 00225 } 00226 00227 iObjectCount++; 00228 00229 return 0; // success 00230 } 00231 00232 00236 int CWorld::RemoveObject(CObject * Obj) 00237 { 00238 if(Obj == NULL) return DAS_ERROR; // error! 00239 00240 if(Obj->Owner != NULL) Obj->Owner->iOwnCount--; // owner doesn't own this after it's gone 00241 00242 CObject * Current = Obj; 00243 00244 if((Obj->Previous == NULL) && (Obj->Next == NULL)) // deleting only object in the list 00245 { 00246 Objects = NULL; 00247 delete Obj; 00248 iObjectCount--; 00249 return 0; 00250 } 00251 00252 if(Obj->Previous == NULL) // deleting the object at the beginning of the list 00253 { 00254 Objects = Obj->Next; 00255 Obj->Next->Previous = NULL; 00256 delete Obj; 00257 iObjectCount--; 00258 return 0; 00259 } 00260 00261 if(Obj->Next == NULL) // deleting the object at the end of the list 00262 { 00263 Obj->Previous->Next = NULL; 00264 delete Obj; 00265 iObjectCount--; 00266 return 0; 00267 } 00268 00269 // deleting an object somewhere in the middle of the list 00270 Obj->Previous->Next = Obj->Next; 00271 Obj->Next->Previous = Obj->Previous; 00272 delete Obj; 00273 00274 iObjectCount--; 00275 00276 return 0; // success 00277 } 00278 00279 00285 int CWorld::AddEffect(CEffect * Effect) 00286 { 00287 if (Effects == NULL) // add the first PSystem in the list 00288 { 00289 Effects = Effect; 00290 } 00291 else // add to the end of the list 00292 { 00293 CEffect * Current = Effects; 00294 while(Current->Next != NULL) 00295 { 00296 Current = Current->Next; // traverse the list 00297 } 00298 Current->Next = Effect; // add this object to the end of the list 00299 Effect->Previous = Current; // and create a back-link from the current object 00300 Effect->Next = NULL; // should already be null on construct, but hey 00301 } 00302 00303 iEffectCount++; 00304 00305 return 0; // success 00306 } 00307 00308 00312 int CWorld::RemoveEffect(CEffect * Effect) 00313 { 00314 if(Effect == NULL) return DAS_ERROR; // error! 00315 00316 CEffect * Current = Effects; 00317 00318 if((Effect->Previous == NULL) && (Effect->Next == NULL)) // deleting only object in the list 00319 { 00320 Effects = NULL; 00321 delete Effect; 00322 iEffectCount--; 00323 return 0; 00324 } 00325 00326 if(Effect->Previous == NULL) // deleting the object at the beginning of the list 00327 { 00328 Effects = Effect->Next; 00329 Effects->Previous = NULL; 00330 delete Effect; 00331 iEffectCount--; 00332 return 0; 00333 } 00334 00335 if(Effect->Next == NULL) // deleting the object at the end of the list 00336 { 00337 Effect->Previous->Next = NULL; 00338 delete Effect; 00339 iEffectCount--; 00340 return 0; 00341 } 00342 00343 // deleting an object somewhere in the middle of the list 00344 Effect->Previous->Next = Effect->Next; 00345 Effect->Next->Previous = Effect->Previous; 00346 delete Effect; 00347 00348 iEffectCount--; 00349 00350 return 0; // success 00351 } 00352 00353 00357 void CWorld::UpdateEffects(float timeDelta) 00358 { 00359 CEffect * Current = Effects; 00360 CEffect * Temp = NULL; 00361 00362 while(Current != NULL) 00363 { 00364 if(Current->bExpired) // particle system is dead, remove it 00365 { 00366 Temp = Current->Next; 00367 RemoveEffect(Current); 00368 Current = Temp; // move down the list 00369 } 00370 else 00371 { 00372 Current->bExpired = Current->Step(timeDelta); 00373 Current = Current->Next; // move down the list 00374 } 00375 } 00376 } 00377 00378 00382 void CWorld::DrawEffects(void) 00383 { 00384 CEffect * Current = Effects; 00385 00386 while(Current != NULL) 00387 { 00388 if(!Current->bExpired) 00389 { 00390 Current->Draw(); 00391 } 00392 00393 Current = Current->Next; 00394 } 00395 } 00396 00397 00404 int CWorld::LoadLevel(const char * filename) 00405 { 00406 char string[256]; 00407 char currentChar = NULL; 00408 int charsRead = 0; 00409 FILE * file = NULL; 00410 int cellType = 0; 00411 int iX, iY, iZ = 0; // index vars 00412 CObject * NewObj = NULL; 00413 00414 // open level file 00415 fopen_s(&file, filename, "r" ); 00416 if(file == NULL) return DAS_ERROR; 00417 00418 // read in tile map 00419 for(iY = MAP_SIZE-1; iY>=0; iY--) // for each row (read these in backwards for correct placement) 00420 { 00421 for(iX = 0; iX < MAP_SIZE; iX++) // for each cell on that row 00422 { 00423 for(iZ=0; iZ<256; iZ++) // read in this cell's data 00424 { 00425 fread(¤tChar, 1, 1, file); 00426 00427 if(currentChar == 9 || currentChar == 10) // tab or newline 00428 { 00429 string[iZ] = 0; 00430 break; 00431 } 00432 else // another character 00433 { 00434 string[iZ] = currentChar; 00435 } 00436 00437 cellType = atoi(string); 00438 } 00439 00440 switch(cellType) 00441 { 00442 case TILEID_NULL: 00443 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_NULL; 00444 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_NULL; 00445 break; 00446 00447 case TILEID_BLANK: 00448 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_BLANK; 00449 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_GRID; 00450 break; 00451 00452 case TILEID_DIRT: 00453 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_DIRT; 00454 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_DIRT; 00455 break; 00456 00457 case TILEID_SAND: 00458 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_SAND; 00459 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_SAND; 00460 break; 00461 00462 case TILEID_MUD: 00463 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_MUD; 00464 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_MUD; 00465 break; 00466 00467 case TILEID_WATER: 00468 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_WATER; 00469 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_WATER; 00470 this->tiles[(iY * MAP_SIZE) + iX].bPassable = false; 00471 break; 00472 00473 case TILEID_LAVA: 00474 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_LAVA; 00475 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_LAVA; 00476 this->tiles[(iY * MAP_SIZE) + iX].iTileEffect = TILE_EFFECT_DAMAGE; 00477 this->tiles[(iY * MAP_SIZE) + iX].iDamage = TILE_DAMAGE_LAVA; 00478 break; 00479 00480 case TILEID_ICE: 00481 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_ICE; 00482 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_ICE; 00483 break; 00484 00485 case TILEID_TARMAC: 00486 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_TARMAC; 00487 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_TARMAC; 00488 break; 00489 00490 case TILEID_GRASS: 00491 this->tiles[(iY * MAP_SIZE) + iX].iType = TILEID_GRASS; 00492 this->tiles[(iY * MAP_SIZE) + iX].iTexture = TEXID_GRASS; 00493 break; 00494 } 00495 } 00496 } 00497 00498 // skip the following newline (blank line) 00499 //fread(¤tChar, 1, 1, file); // newline 00500 00501 // read in object map 00502 for(iY = 0; iY < MAP_SIZE; iY++) // for each row 00503 { 00504 for(iX = MAP_SIZE -1; iX >= 0; iX--) // for each cell on that row 00505 { 00506 for(iZ=0; iZ<256; iZ++) // read in this cell's data 00507 { 00508 fread(¤tChar, 1, 1, file); 00509 00510 if(currentChar == 9 || currentChar == 10) // tab or newline 00511 { 00512 string[iZ] = 0; 00513 break; 00514 } 00515 else // another char 00516 { 00517 string[iZ] = currentChar; 00518 string[iZ+1] = 0; 00519 } 00520 00521 cellType = atoi(string); 00522 } 00523 00524 switch(cellType) 00525 { 00526 case TYPEID_POWERUP_HEALTH: 00527 NewObj = new CObject(TYPEID_POWERUP_HEALTH, this); 00528 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00529 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00530 NewObj->iRemovalEffects = 2; 00531 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00532 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00533 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00534 this->AddObject(NewObj); 00535 break; 00536 00537 case TYPEID_POWERUP_PS: 00538 NewObj = new CObject(TYPEID_POWERUP_PS, this); 00539 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00540 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00541 NewObj->iRemovalEffects = 2; 00542 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00543 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00544 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00545 this->AddObject(NewObj); 00546 break; 00547 00548 case TYPEID_POWERUP_BS: 00549 NewObj = new CObject(TYPEID_POWERUP_BS, this); 00550 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00551 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00552 NewObj->iRemovalEffects = 2; 00553 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00554 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00555 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00556 this->AddObject(NewObj); 00557 break; 00558 00559 case TYPEID_POWERUP_SB: 00560 NewObj = new CObject(TYPEID_POWERUP_SB, this); 00561 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00562 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00563 NewObj->iRemovalEffects = 2; 00564 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00565 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00566 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00567 this->AddObject(NewObj); 00568 break; 00569 00570 case TYPEID_POWERUP_LM: 00571 NewObj = new CObject(TYPEID_POWERUP_LM, this); 00572 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00573 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00574 NewObj->iRemovalEffects = 2; 00575 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00576 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00577 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00578 this->AddObject(NewObj); 00579 break; 00580 00581 case TYPEID_POWERUP_HS: 00582 NewObj = new CObject(TYPEID_POWERUP_HS, this); 00583 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00584 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00585 NewObj->iRemovalEffects = 2; 00586 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00587 NewObj->iRemovalEffect[1] = EFFECTID_SHOCKWAVE; 00588 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00589 this->AddObject(NewObj); 00590 break; 00591 00592 case TYPEID_TNT_BLOCK: 00593 NewObj = new CObject(TYPEID_TNT_BLOCK, this); 00594 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00595 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00596 NewObj->iRemovalEffects = 1; 00597 NewObj->iRemovalEffect[0] = EFFECTID_PSYSTEM; 00598 NewObj->iRemovalSound = SOUNDID_EXPLOSION; 00599 NewObj->iDamageSound = SOUNDID_HIT; 00600 this->AddObject(NewObj); 00601 break; 00602 00603 case TYPEID_WALL_BLOCK: 00604 NewObj = new CObject(TYPEID_WALL_BLOCK, this); 00605 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00606 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00607 NewObj->iDamageSound = SOUNDID_HIT; 00608 this->AddObject(NewObj); 00609 break; 00610 00611 case TYPEID_WOOD_BLOCK: 00612 NewObj = new CObject(TYPEID_WOOD_BLOCK, this); 00613 NewObj->Position.x = iX * CELL_SIZE + CELL_SIZE / 2; 00614 NewObj->Position.y = iY * CELL_SIZE + CELL_SIZE / 2; 00615 NewObj->iRemovalSound = SOUNDID_HIT; 00616 NewObj->iDamageSound = SOUNDID_HIT; 00617 NewObj->iRemovalEffects = 1; 00618 NewObj->iRemovalEffect[0] = EFFECTID_TILEANIM; 00619 NewObj->iRemovalAnim = ANIMID_CRATECRUSH; 00620 this->AddObject(NewObj); 00621 break; 00622 } 00623 } 00624 } 00625 00626 // read in the music file name for this level 00627 for(iX=0; iX < 256; iX++) // read in a line 00628 { 00629 charsRead = fread(¤tChar, 1, 1, file); 00630 if(charsRead < 1) 00631 { 00632 return DAS_ERROR; // couldn't read from file? return error 00633 } 00634 00635 if(currentChar == 10) 00636 { 00637 musicFile[iX] = 0; // terminate string and exit loop 00638 break; 00639 } 00640 else 00641 { 00642 musicFile[iX] = currentChar; // add current char string 00643 } 00644 } 00645 00646 fclose(file); 00647 00648 return 0; //success 00649 } 00650 00651 00657 CTile::CTile(void) 00658 { 00659 iType = TILEID_NULL; 00660 iTexture = TEXID_NULL; 00661 iTileEffect = TILE_EFFECT_NULL; 00662 bPassable = true; 00663 iDamage = 0; 00664 Previous = NULL; 00665 Next = NULL; 00666 } 00667 00668 00674 CObject::CObject(void) 00675 { 00676 ParentWorld = NULL; 00677 Geometry = NULL; 00678 Effects = NULL; 00679 Previous = NULL; 00680 Next = NULL; 00681 Owner = NULL; 00682 00683 fBBLeft = DEFAULT_BB_LEFT; 00684 fBBRight = DEFAULT_BB_RIGHT; 00685 fBBBottom = DEFAULT_BB_BOTTOM; 00686 fBBTop = DEFAULT_BB_TOP; 00687 00688 fDrawLeft = DEFAULT_DRAW_LEFT; 00689 fDrawRight = DEFAULT_DRAW_RIGHT; 00690 fDrawBottom = DEFAULT_DRAW_BOTTOM; 00691 fDrawTop = DEFAULT_DRAW_TOP; 00692 00693 fAngle = DEFAULT_ANGLE; 00694 fSubAngle = DEFAULT_SUB_ANGLE; 00695 00696 iOwnCount = 0; 00697 iHealth = DEFAULT_HEALTH; 00698 bDying = false; 00699 bVisible = true; 00700 iDamage = DEFAULT_DAMAGE; 00701 iType = TYPEID_NULL; 00702 iLives = DEFAULT_LIVES; 00703 iTexture = TEXID_NULL; 00704 iTint = TINTID_NULL; 00705 iRemovalEffects = 0; 00706 iRemovalSound = SOUNDID_NULL; 00707 iDamageSound = SOUNDID_NULL; 00708 iWeapon = WEAPONID_PEA_SHOT; 00709 iAmmo = -1; // start with infinite pea-shooter ammo 00710 00711 // animation variables 00712 iCreationAnim = ANIMID_NULL; 00713 iCreationAnimSpeed = 100; 00714 iNormalAnim = ANIMID_NULL; 00715 iNormalAnimSpeed = 100; 00716 iRemovalAnim = ANIMID_NULL; 00717 iRemovalAnimSpeed = 100; 00718 bAnimCycle = ANIM_CYCLE_CYCLE; 00719 bAnimating = false; 00720 iCurrentFrame = 0; 00721 iAnimTimeStamp = 0; 00722 iLingerTime = DEFAULT_LINGER_TIME; 00723 00724 // collision variables 00725 bCheckedForCollision = false; 00726 00727 for(int iX=0; iX<8; iX++) 00728 { 00729 iInput[iX] = false; 00730 } 00731 00732 } 00733 00741 CObject::CObject(int typeID, CWorld * ThisWorld) 00742 { 00743 iType = typeID; 00744 ParentWorld = ThisWorld; 00745 Geometry = NULL; 00746 Effects = NULL; 00747 Previous = NULL; 00748 Next = NULL; 00749 Owner = NULL; 00750 00751 fBBLeft = DEFAULT_BB_LEFT; 00752 fBBRight = DEFAULT_BB_RIGHT; 00753 fBBBottom = DEFAULT_BB_BOTTOM; 00754 fBBTop = DEFAULT_BB_TOP; 00755 00756 fDrawLeft = DEFAULT_DRAW_LEFT; 00757 fDrawRight = DEFAULT_DRAW_RIGHT; 00758 fDrawBottom = DEFAULT_DRAW_BOTTOM; 00759 fDrawTop = DEFAULT_DRAW_TOP; 00760 00761 fAngle = DEFAULT_ANGLE; 00762 fSubAngle = DEFAULT_SUB_ANGLE; 00763 00764 iOwnCount = 0; 00765 iHealth = DEFAULT_HEALTH; 00766 bDying = false; 00767 bVisible = true; 00768 iDamage = DEFAULT_DAMAGE; 00769 iLives = DEFAULT_LIVES; 00770 iTexture = TEXID_NULL; 00771 iTint = TINTID_NULL; 00772 iRemovalEffects = 0; 00773 iRemovalSound = NULL; 00774 iDamageSound = SOUNDID_NULL; 00775 iWeapon = WEAPONID_NULL; 00776 iAmmo = 0; 00777 00778 // animation variables 00779 iCreationAnim = ANIMID_NULL; 00780 iCreationAnimSpeed = 100; 00781 iNormalAnim = ANIMID_NULL; 00782 iNormalAnimSpeed = 100; 00783 iRemovalAnim = ANIMID_NULL; 00784 iRemovalAnimSpeed = 100; 00785 bAnimCycle = ANIM_CYCLE_CYCLE; 00786 bAnimating = false; 00787 iCurrentFrame = 0; 00788 iAnimTimeStamp = 0; 00789 iLingerTime = DEFAULT_LINGER_TIME; 00790 00791 bCheckedForCollision = false; 00792 00793 for(int iX=0; iX<8; iX++) 00794 { 00795 iInput[iX] = false; 00796 } 00797 00798 switch(iType) 00799 { 00800 case TYPEID_PEA_SHOT: 00801 iDamage = 10; 00802 fBBLeft = -.3; 00803 fBBRight = .3; 00804 fBBBottom = -.3; 00805 fBBTop = .3; 00806 fDrawLeft = -.6; 00807 fDrawRight = .6; 00808 fDrawBottom = -.6; 00809 fDrawTop = .6; 00810 iTexture = TEXID_PEA_SHOT; 00811 break; 00812 00813 case TYPEID_BOUNCY_SHOT: 00814 iHealth = 100; 00815 iDamage = 10; 00816 fBBLeft = -.3; 00817 fBBRight = .3; 00818 fBBBottom = -.3; 00819 fBBTop = .3; 00820 fDrawLeft = -.5; 00821 fDrawRight = .5; 00822 fDrawBottom = -.5; 00823 fDrawTop = .5; 00824 iTexture = TEXID_BOUNCY_SHOT; 00825 break; 00826 00827 case TYPEID_SUPER_BULLET: 00828 iHealth = 100; 00829 iDamage = 15; 00830 fBBLeft = -.3; 00831 fBBRight = .3; 00832 fBBBottom = -.3; 00833 fBBTop = .3; 00834 fDrawLeft = -.5; 00835 fDrawRight = .5; 00836 fDrawBottom = -.5; 00837 fDrawTop = .5; 00838 iTexture = TEXID_SUPER_BULLET; 00839 break; 00840 00841 case TYPEID_LAND_MINE: 00842 iDamage = 100; 00843 fBBLeft = -.5; 00844 fBBRight = .5; 00845 fBBBottom = -.5; 00846 fBBTop = .5; 00847 fDrawLeft = -.8; 00848 fDrawRight = .8; 00849 fDrawBottom = -.8; 00850 fDrawTop = .8; 00851 iTexture = TEXID_LAND_MINE; 00852 break; 00853 00854 case TYPEID_HEAT_SEEKER: 00855 iDamage = 50; 00856 fBBLeft = -.3; 00857 fBBRight = .3; 00858 fBBBottom = -.3; 00859 fBBTop = .3; 00860 fDrawLeft = -1; 00861 fDrawRight = 1; 00862 fDrawBottom = -1; 00863 fDrawTop = 1; 00864 iTexture = TEXID_HEAT_SEEKER; 00865 break; 00866 00867 case TYPEID_POWERUP_HEALTH: 00868 iDamage = -30; 00869 iTexture = TEXID_POWERUP_HEALTH; 00870 break; 00871 00872 case TYPEID_POWERUP_PS: 00873 iTexture = TEXID_POWERUP_PS; 00874 break; 00875 00876 case TYPEID_POWERUP_BS: 00877 iTexture = TEXID_POWERUP_BS; 00878 break; 00879 00880 case TYPEID_POWERUP_SB: 00881 iTexture = TEXID_POWERUP_SB; 00882 break; 00883 00884 case TYPEID_POWERUP_LM: 00885 iTexture = TEXID_POWERUP_LM; 00886 break; 00887 00888 case TYPEID_POWERUP_HS: 00889 iTexture = TEXID_POWERUP_HS; 00890 break; 00891 00892 case TYPEID_TNT_BLOCK: 00893 iHealth = 10; 00894 iDamage = 20; 00895 iTexture = TEXID_TNT_BLOCK; 00896 break; 00897 00898 case TYPEID_WALL_BLOCK: 00899 iHealth = 1000; 00900 iDamage = 10; 00901 iTexture = TEXID_WALL_BLOCK; 00902 break; 00903 00904 case TYPEID_WOOD_BLOCK: 00905 iHealth = 40; 00906 iDamage = 25; 00907 iTexture = TEXID_CRATE; 00908 break; 00909 00910 case TYPEID_TANK: 00911 iHealth = 100; 00912 iDamage = 50; 00913 iWeapon = WEAPONID_PEA_SHOT; 00914 iAmmo = -1; // start with infinite pea-shooter ammo 00915 iLives = 3; 00916 iTexture = TEXID_TANK; 00917 break; 00918 } 00919 } 00920 00928 int CObject::Draw(void) 00929 { 00930 // draw object 00931 glPushMatrix(); // save matrix state 00932 glTranslatef(Position.x, Position.y, 0.0f); // position in WCS 00933 switch(iTint) 00934 { 00935 case TINTID_ARMYGREEN: 00936 glColor4f(0.67,0.82,0.45,1.0); 00937 break; 00938 case TINTID_ARMYBROWN: 00939 glColor4f(0.65,0.53,0.17,1.0); 00940 break; 00941 case TINTID_NULL: 00942 glColor4f(1.0,1.0,1.0,1.0); 00943 break; 00944 case TINTID_RED: 00945 glColor4f(1.0,0.4,0.4,1.0); 00946 break; 00947 case TINTID_ORANGE: 00948 glColor4f(1.0,0.8,0.4,1.0); 00949 break; 00950 case TINTID_YELLOW: 00951 glColor4f(1.0,1.0,0.4,1.0); 00952 break; 00953 case TINTID_GREEN: 00954 glColor4f(0.4,1.0,0.4,1.0); 00955 break; 00956 case TINTID_BLUE: 00957 glColor4f(0.4,0.8,1.0,1.0); 00958 break; 00959 case TINTID_PURPLE: 00960 glColor4f(1.0,0.4,1.0,1.0); 00961 break; 00962 } 00963 00964 glRotatef(fAngle,0,0,1); 00965 00966 if (!bAnimating) // draw the objects regular tile 00967 { 00968 glBindTexture( GL_TEXTURE_2D, GetTexture(this->iTexture)); 00969 } 00970 else // otherwise draw it's current animation frame 00971 { 00972 glBindTexture( GL_TEXTURE_2D, GetFrame(ANIMID_CRATECRUSH, iCurrentFrame)); 00973 } 00974 00975 glBegin(GL_QUADS); // start drawing a polygon (4 sided) 00976 glTexCoord2d(0.0,1.0); glVertex3f(fDrawLeft, fDrawTop, 0.1f); // top left 00977 glTexCoord2d(1.0,1.0); glVertex3f(fDrawRight, fDrawTop, 0.1f); // top right 00978 glTexCoord2d(1.0,0.0); glVertex3f(fDrawRight, fDrawBottom, 0.1f); // bottom right 00979 glTexCoord2d(0.0,0.0); glVertex3f(fDrawLeft, fDrawBottom, 0.1f); // bottom left 00980 glEnd(); // done with the polygon 00981 00982 glPopMatrix(); 00983 00984 // draw bounding box if flag is set 00985 if(DRAW_BOUNDING_BOXES) 00986 { 00987 glDisable( GL_TEXTURE_2D ); // enable texture mapping 00988 glPushMatrix(); // save the state (CYA) 00989 glTranslatef(Position.x, Position.y, 0.0f); // position in WCS 00990 glColor3f(1.0,0.0,1.0); 00991 glBegin(GL_LINE_LOOP); // start drawing a polygon (4 sided) 00992 glVertex3f(fBBLeft, fBBTop, 0.1f); // Top Left 00993 glVertex3f(fBBRight, fBBTop, 0.1f); // Top Right 00994 glVertex3f(fBBRight, fBBBottom, 0.1f); // Bottom Right 00995 glVertex3f(fBBLeft, fBBBottom, 0.1f); // Bottom Left 00996 glEnd(); // done with the polygon 00997 glPopMatrix(); 00998 glEnable( GL_TEXTURE_2D ); // enable texture mapping 00999 } 01000 01001 return 0; // success 01002 } 01003 01011 void CObject::StartAnimating(void) 01012 { 01013 iCurrentFrame = 0; 01014 bAnimating = true; 01015 iAnimTimeStamp = this->ParentWorld->iCurrentTime; 01016 } 01017 01024 void CObject::StopAnimating(void) 01025 { 01026 bAnimating = false; 01027 } 01028 01037 void CObject::SetBB(float left, float right, float bottom, float top) 01038 { 01039 fBBLeft = left; 01040 fBBRight = right; 01041 fBBBottom = bottom; 01042 fBBTop = top; 01043 }
Copyright Windsor Schmidt 2006 - All rights reserved.