#include "LevelManager.h" #include "WorldManager.h" #include "GameManager.h" #include "Powerups.h" #include #include #include static 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] != '\n' && TheData[i-1] != '\r' && !Err && DataSize); TheData[i] = '\0'; if(Err || !DataSize) return false; return true; } void DrawLevel(VLevel * l) { int theRoomX; int theRoomY; int 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++) 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); } } } } 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); } } } DisposePtr((Ptr) l->Rooms); DisposePtr((Ptr) l->Cells); 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; } } } } } } /* MAKES LOTS OF ASSUMTIONS; REALLY NEEDS ERROR CHECKING */ void LoadLevel(VLevel * l, char * name, void * world) { Str255 path; ProcessSerialNumber PID; ProcessInfoRec Info; #ifdef __MWERKS__ FSRef FileRef; CFURLRef URL; CFBundleRef Bundle; CFStringRef String; #endif 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; #ifdef __MWERKS__ String = CFStringCreateWithCString(NULL, name, NULL); #pragma unused (path, PID, Info, Spec) Bundle = CFBundleGetMainBundle(); Bundle = (CFBundleRef)CFRetain((CFTypeRef)Bundle); URL = CFBundleCopyResourceURL(Bundle, String, NULL, NULL); CFURLGetFSRef(URL, &FileRef); FSGetCatalogInfo(&FileRef, kFSCatInfoNone, NULL, NULL, &Spec, NULL); CFRelease((CFTypeRef)Bundle); CFRelease((CFTypeRef)URL); CFRelease((CFTypeRef)String); #else path[0] = sprintf((char *) &path[1], ":Levels:%s", name); GetCurrentProcess(&PID); Info.processName = NULL; Info.processAppSpec = &Spec; GetProcessInformation(&PID, &Info); FSMakeFSSpec(Spec.vRefNum, Spec.parID, path, &Spec); #endif FSpOpenDF(&Spec, fsRdPerm, &Ref); ReadLn(Ref, TheData); sscanf(TheData, "LevelSize: %d, %d, %d", &l->SizeX, &l->SizeY, &l->SizeZ); 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] == '\r' || TheData[0] == '\n') { DataSize = 1; FSRead(Ref, &DataSize, &TheData[0]); } sscanf(TheData, "%hd", &l->Cells[(theRoomY * (l->SizeX * l->SizeZ)) + (theRoomZ * l->SizeX) + theRoomX]); } } } 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\n")) { added = true; e = (VEnemy *)NewPtrClear(sizeof(VEnemy)); InitEnemy(e, w); AllocateWObject(&o); o->e = e; o->Type = VENEMY; o->next = l->Objects; do { ReadLn(Ref, TheData); 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(!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); } } while(strcmp(TheData, "End\n")); } if(added) { if(l->Objects) { l->Objects->previous = o; } l->Objects = o; } added = false; if(!strcmp(TheData, "Object\n")) { added = true; ob = (VObject *)NewPtrClear(sizeof(VObject)); InitObject(ob); AllocateWObject(&o); o->o = ob; o->Type = VOBJECT; o->next = l->Objects; do { ReadLn(Ref, TheData); 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(!memcmp(TheData, "Type:", 5)) { sscanf(TheData, "Type: %s", SymbolName); if(!strcmp(SymbolName, "Target")) BuildTargetModel(&ob->Model); } } while(strcmp(TheData, "End\n")); CalculateRadius(ob); } if(added) { if(l->Objects) { l->Objects->previous = o; } l->Objects = o; } } FSClose(Ref); } 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->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))); 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; } }