#include "LevelManager.h" #include "WorldManager.h" #include "GameManager.h" #include "Powerups.h" #include #include #include Boolean ReadLn(short Ref, char * TheData) { int i = 0; long DataSize; OSErr Err = noErr; do { DataSize = 1; FSRead(Ref, &DataSize, &TheData[i]); i++; } while(TheData[i-1] != 0x0A && TheData[i-1] != 0x0D && !Err && DataSize); TheData[i] = '\0'; if(Err || !DataSize) return false; return true; } void DrawLevel(VLevel * l) { int theRoomX; int theRoomY; int theRoomZ; int theWall; glEnable(GL_CULL_FACE); for (theRoomX = 0; theRoomX < l->SizeX; theRoomX++) { for (theRoomY = 0; theRoomY < l->SizeY; theRoomY++) { for (theRoomZ = 0; theRoomZ < l->SizeZ; theRoomZ++) { for(theWall = 0; theWall < 4; theWall++) if(l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[theWall]) DrawObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall]); DrawObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground); DrawObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling); } } } glDisable(GL_CULL_FACE); } void CleanUpLevel(VLevel * l) { int theRoomX; int theRoomY; int theRoomZ; int theWall; VObjectWrapper * theWObject; for (theRoomX = 0; theRoomX < l->SizeX; theRoomX++) { for (theRoomY = 0; theRoomY < l->SizeY; theRoomY++) { for (theRoomZ = 0; theRoomZ < l->SizeZ; theRoomZ++) { for(theWall = 0; theWall < 4; theWall++) CleanUpObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall]); CleanUpObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground); CleanUpObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling); } } } if (l->Rooms != NULL) { DisposePtr((Ptr) l->Rooms); l->Rooms = NULL; } if (l->Cells != NULL) { DisposePtr((Ptr) l->Cells); l->Cells = NULL; } while(l->Objects != NULL) { theWObject = l->Objects; l->Objects = theWObject->next; CleanUpWObject(theWObject); DisposePtr((Ptr) theWObject); } } static void CreateRooms(VLevel * l) { int theRoomX, theRoomY, theRoomZ; int theWall; for (theRoomX = 0; theRoomX < l->SizeX; theRoomX++) { for (theRoomY = 0; theRoomY < l->SizeY; theRoomY++) { for (theRoomZ = 0; theRoomZ < l->SizeZ; theRoomZ++) { for(theWall = 0; theWall < 4; theWall++) { InitObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall]); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall].Position.x = 40*theRoomX; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall].Position.y = 40*theRoomY; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[theWall].Position.z = 40*theRoomZ; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[theWall] = false; } InitObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground.Position.x = 40*theRoomX; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground.Position.y = 40*theRoomY; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground.Position.z = 40*theRoomZ; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[4] = false; InitObject(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling.Position.x = 40*theRoomX; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling.Position.y = 40*theRoomY; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling.Position.z = 40*theRoomZ; l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[5] = false; if(l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX]) { if(theRoomX > 0) { if(!l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + (theRoomX - 1)]) { BuildLeftWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[0].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[0] = true; } } else { BuildLeftWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[0].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[0] = true; } if(theRoomX < (l->SizeX - 1)) { if(!l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + (theRoomX + 1)]) { BuildRightWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[1].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[1] = true; } } else { BuildRightWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[1].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[1] = true; } if(theRoomZ > 0) { if(!l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + ((theRoomZ - 1) * l->SizeX) + theRoomX]) { BuildFrontWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[2].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[2] = true; } } else { BuildFrontWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[2].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[2] = true; } if(theRoomZ < (l->SizeZ - 1)) { if(!l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + ((theRoomZ + 1) * l->SizeX) + theRoomX]) { BuildBackWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[3].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[3] = true; } } else { BuildBackWallModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Walls[3].Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[3] = true; } if(theRoomY > 0) { if(!l->Cells[((theRoomY - 1) * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX]) { BuildFloorModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground.Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[4] = true; } } else { BuildFloorModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ground.Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[4] = true; } if(theRoomY < (l->SizeY - 1)) { if(!l->Cells[((theRoomY + 1) * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX]) { BuildCeilingModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling.Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[5] = true; } } else { BuildCeilingModel(&l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].Ceiling.Model); l->Rooms[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX].IsWall[5] = true; } } } } } } Boolean LoadLevel(VLevel * l, char * name, void * world) { OSErr error; int numMatches; FSRef FileRef; CFURLRef URL; CFBundleRef Bundle; CFStringRef String; FSSpec Spec; short Ref; int theRoomX, theRoomY, theRoomZ; long DataSize; char TheData[1024]; char SymbolName[1024]; Boolean added; VObjectWrapper * o; VEnemy * e; VWorld * w; VObject * ob; w = (VWorld *) world; TheData[1] = '\0'; l->Objects = NULL; String = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); Bundle = CFBundleGetMainBundle(); URL = CFBundleCopyResourceURL(Bundle, String, NULL, NULL); if(URL) { CFURLGetFSRef(URL, &FileRef); error = FSGetCatalogInfo(&FileRef, kFSCatInfoNone, NULL, NULL, &Spec, NULL); CFRelease((CFTypeRef)URL); } CFRelease((CFTypeRef)String); if (error != noErr) return 0; error = FSpOpenDF(&Spec, fsRdPerm, &Ref); if (error != noErr) return 0; if (!ReadLn(Ref, TheData)) return 0; numMatches = sscanf(TheData, "LevelSize: %d, %d, %d", &l->SizeX, &l->SizeY, &l->SizeZ); if (numMatches < 3) return 0; l->Rooms = (VRoom *) NewPtr(sizeof(VRoom) * l->SizeX * l->SizeY * l->SizeZ); l->Cells = (short *) NewPtr(sizeof(short) * l->SizeX * l->SizeY * l->SizeZ); for (theRoomY = 0; theRoomY < l->SizeY; theRoomY++) { for (theRoomZ = 0; theRoomZ < l->SizeZ; theRoomZ++) { for (theRoomX = 0; theRoomX < l->SizeX; theRoomX++) { DataSize = 1; FSRead(Ref, &DataSize, &TheData[0]); while (TheData[0] == 0x0A || TheData[0] == 0x0D) { DataSize = 1; FSRead(Ref, &DataSize, &TheData[0]); } numMatches = sscanf(TheData, "%hd", &l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX]); if (numMatches < 1) { DisposePtr((Ptr) l->Rooms); l->Rooms = NULL; DisposePtr((Ptr) l->Cells); l->Cells = NULL; return 0; } } } } CreateRooms(l); while(ReadLn(Ref, TheData)) { added = false; if (!memcmp(TheData, "StartPos", 8)) sscanf(TheData, "StartPos: %f, %f, %f", &l->StartPos.x, &l->StartPos.y, &l->StartPos.z); else if (!memcmp(TheData, "Look", 4)) { sscanf(TheData, "Look: %s", SymbolName); if (!strcmp(SymbolName, "Left")) l->Look = LEFT; else if (!strcmp(SymbolName, "Right")) l->Look = RIGHT; else if (!memcmp(SymbolName, "Forward", 7)) l->Look = FORWARDS; else if (!memcmp(SymbolName, "Backward", 8)) l->Look = BACKWARDS; } if (!strcmp(TheData, "Enemy\x0A") || !strcmp(TheData, "Enemy\x0D")) { added = true; e = (VEnemy *)NewPtrClear(sizeof(VEnemy)); InitEnemy(e, w); AllocateWObject(&o); o->e = e; o->Type = VENEMY; o->next = l->Objects; do { if (!ReadLn(Ref, TheData)) break; if(!memcmp(TheData, "PosX", 4)) sscanf(TheData, "PosX: %f", &e->Object.Position.x); else if(!memcmp(TheData, "PosY", 4)) sscanf(TheData, "PosY: %f", &e->Object.Position.y); else if(!memcmp(TheData, "PosZ", 4)) sscanf(TheData, "PosZ: %f", &e->Object.Position.z); else if(!memcmp(TheData, "Shields", 7)) sscanf(TheData, "Shields: %d", &e->Shields); else if(!memcmp(TheData, "BonusNum", 8)) sscanf(TheData, "BonusNum: %d", &e->Object.PowerupAmount); else if(!memcmp(TheData, "Destroy", 7)) sscanf(TheData, "Destroy: %hd", &e->Object.MustBeDestroyed); else if(!memcmp(TheData, "Bonus", 5)) { sscanf(TheData, "Bonus: %s", SymbolName); if (!strcmp(SymbolName, "Health")) e->Object.PowerupType = POWERUPTYPEHEALTH; else if (!strcmp(SymbolName, "Rockets")) e->Object.PowerupType = POWERUPTYPEROCKETS; else if (!strcmp(SymbolName, "Turbo")) e->Object.PowerupType = POWERUPTYPETURBO; else if (!strcmp(SymbolName, "MachineGun")) e->Object.PowerupType = POWERUPTYPEMACHINEGUN; else if (!strcmp(SymbolName, "SpreadGun")) e->Object.PowerupType = POWERUPTYPESPREADGUN; else if (!strcmp(SymbolName, "LongShotGun")) e->Object.PowerupType = POWERUPTYPELONGSHOTGUN; } else if(!memcmp(TheData, "AIType", 6)) { sscanf(TheData, "AIType: %s", SymbolName); if (!strcmp(SymbolName, "DumbShooter")) SetEnemyAI(e, DumbShooterAI); else if (!strcmp(SymbolName, "SmartShooter")) SetEnemyAI(e, SmartShooterAI); else if (!strcmp(SymbolName, "Kamikaze")) SetEnemyAI(e, KamikazeAI); else if (!strcmp(SymbolName, "Stationary")) SetEnemyAI(e, StationaryAI); } else if(!memcmp(TheData, "Facing", 6)) { sscanf(TheData, "Bonus: %s", SymbolName); if (!strcmp(SymbolName, "Forward")) { e->Object.Front.x = 0.0; e->Object.Front.y = 0.0; e->Object.Front.z = -1.0; e->Object.Up.x = 0.0; e->Object.Up.y = 1.0; e->Object.Up.z = 0.0; e->Object.Right.x = 1.0; e->Object.Right.y = 0.0; e->Object.Right.z = 0.0; } else if (!strcmp(SymbolName, "Backward")) { e->Object.Front.x = 0.0; e->Object.Front.y = 0.0; e->Object.Front.z = 1.0; e->Object.Up.x = 0.0; e->Object.Up.y = 1.0; e->Object.Up.z = 0.0; e->Object.Right.x = -1.0; e->Object.Right.y = 0.0; e->Object.Right.z = 0.0; } else if (!strcmp(SymbolName, "Left")) { e->Object.Front.x = -1.0; e->Object.Front.y = 0.0; e->Object.Front.z = 0.0; e->Object.Up.x = 0.0; e->Object.Up.y = 1.0; e->Object.Up.z = 0.0; e->Object.Right.x = 0.0; e->Object.Right.y = 0.0; e->Object.Right.z = -1.0; } else if (!strcmp(SymbolName, "Right")) { e->Object.Front.x = 1.0; e->Object.Front.y = 0.0; e->Object.Front.z = 0.0; e->Object.Up.x = 0.0; e->Object.Up.y = 1.0; e->Object.Up.z = 0.0; e->Object.Right.x = 0.0; e->Object.Right.y = 0.0; e->Object.Right.z = 1.0; } else if (!strcmp(SymbolName, "Up")) { e->Object.Front.x = 0.0; e->Object.Front.y = 1.0; e->Object.Front.z = 0.0; e->Object.Up.x = 0.0; e->Object.Up.y = 0.0; e->Object.Up.z = 1.0; e->Object.Right.x = 0.0; e->Object.Right.y = 0.0; e->Object.Right.z = 1.0; } else if (!strcmp(SymbolName, "Down")) { e->Object.Front.x = 0.0; e->Object.Front.y = -1.0; e->Object.Front.z = 0.0; e->Object.Up.x = 0.0; e->Object.Up.y = 0.0; e->Object.Up.z = 1.0; e->Object.Right.x = 0.0; e->Object.Right.y = 0.0; e->Object.Right.z = -1.0; } } } while(strcmp(TheData, "End\x0A") && strcmp(TheData, "End\x0D")); } if(added) { if(l->Objects) { l->Objects->previous = o; } l->Objects = o; } added = false; if(!strcmp(TheData, "Object\x0A") || !strcmp(TheData, "Object\x0D")) { added = true; ob = (VObject *)NewPtrClear(sizeof(VObject)); InitObject(ob); AllocateWObject(&o); o->o = ob; o->Type = VOBJECT; o->next = l->Objects; do { if (!ReadLn(Ref, TheData)) return 0; if(!memcmp(TheData, "PosX", 4)) sscanf(TheData, "PosX: %f", &ob->Position.x); else if(!memcmp(TheData, "PosY", 4)) sscanf(TheData, "PosY: %f", &ob->Position.y); else if(!memcmp(TheData, "PosZ", 4)) sscanf(TheData, "PosZ: %f", &ob->Position.z); else if(!memcmp(TheData, "Shields", 7)) sscanf(TheData, "Shields: %d", &ob->Durability); else if(!memcmp(TheData, "BonusNum", 8)) sscanf(TheData, "BonusNum: %d", &ob->PowerupAmount); else if(!memcmp(TheData, "Destroy", 7)) sscanf(TheData, "Destroy: %hd", &ob->MustBeDestroyed); else if(!memcmp(TheData, "Bonus", 5)) { sscanf(TheData, "Bonus: %s", SymbolName); if (!strcmp(SymbolName, "Health")) ob->PowerupType = POWERUPTYPEHEALTH; else if (!strcmp(SymbolName, "Rockets")) ob->PowerupType = POWERUPTYPEROCKETS; else if (!strcmp(SymbolName, "Turbo")) ob->PowerupType = POWERUPTYPETURBO; else if (!strcmp(SymbolName, "MachineGun")) ob->PowerupType = POWERUPTYPEMACHINEGUN; else if (!strcmp(SymbolName, "SpreadGun")) ob->PowerupType = POWERUPTYPESPREADGUN; else if (!strcmp(SymbolName, "LongShotGun")) ob->PowerupType = POWERUPTYPELONGSHOTGUN; } else if(!memcmp(TheData, "Type:", 5)) { sscanf(TheData, "Type: %s", SymbolName); if(!strcmp(SymbolName, "Target")) BuildTargetModel(&ob->Model); } } while(strcmp(TheData, "End\x0A") && strcmp(TheData, "End\x0D")); CalculateRadius(ob); } if(added) { if(l->Objects) { l->Objects->previous = o; } l->Objects = o; } } FSClose(Ref); return 1; } void BuildEmptyLevel(VLevel * l) { l->SizeX = l->SizeY = l->SizeZ = 1; l->StartPos.x = 20.0; l->StartPos.y = 20.0; l->StartPos.z = 20.0; l->Look = FORWARDS; l->Rooms = (VRoom *) NewPtr(sizeof(VRoom)); l->Cells = (short *) NewPtr(sizeof(short)); *l->Cells = 1; CreateRooms(l); l->Objects = NULL; } void CopyLevel(VLevel * src, VLevel * dest) { VObjectWrapper * srcObjectList, ** destObjectList, * previous; dest->SizeX = src->SizeX; dest->SizeY = src->SizeY; dest->SizeZ = src->SizeZ; dest->StartPos = src->StartPos; dest->Look = src->Look; dest->Rooms = (VRoom *) NewPtr(sizeof(VRoom) * (dest->SizeX * dest->SizeY * dest->SizeZ)); BlockMove(src->Rooms, dest->Rooms, (sizeof(VRoom) * (dest->SizeX * dest->SizeY * dest->SizeZ))); dest->Cells = (short *) NewPtr(sizeof(short) * (dest->SizeX * dest->SizeY * dest->SizeZ)); BlockMove(src->Cells, dest->Cells, (sizeof(short) * (dest->SizeX * dest->SizeY * dest->SizeZ))); if (src->Objects == NULL) dest->Objects = NULL; else { destObjectList = &dest->Objects; previous = NULL; for (srcObjectList = src->Objects; srcObjectList != NULL; srcObjectList = srcObjectList->next) { CopyWObject(srcObjectList, destObjectList); (**destObjectList).previous = previous; if (previous != NULL) previous->next = *destObjectList; previous = *destObjectList; destObjectList = &(**destObjectList).next; } } } void BuildBossArena(VLevel * l, int Length, int Height, int Width) { int x, y, z; l->SizeX = Length; l->SizeY = Height; l->SizeZ = Width; l->StartPos.x = 20.0; l->StartPos.y = 20.0; l->StartPos.z = 20.0; l->Look = FORWARDS; l->Rooms = (VRoom *) NewPtr(sizeof(VRoom) * Length * Height * Width); l->Cells = (short *) NewPtr(sizeof(short) * Length * Height * Width); for(x = 0; x < Length; x++) for(y = 0; y < Height; y++) for(z = 0; z < Width; z++) l->Cells[(y * (l->SizeX * l->SizeZ)) + (z * l->SizeX) + x] = 1; CreateRooms(l); l->Objects = NULL; }