#include #include #include #include "gamemain.h" #include "sokomain.h" #include using namespace std; bool** CanAccess; int FPuzzleCount, ArrayPos, LevelWidth, LevelHeight, FMaxX, FMaxY = 0; bool NewLevel; bool HasPlayer; BOOL AllowNextStep(int ANextX, int ANextY) { return ((ANextX < LevelWidth) && (ANextY < LevelHeight) && (ANextY > 0) && (ANextX > 0) && (CanAccess[ANextX][ANextY]) && ((FPuzzleFields[FPuzzleCount][ANextX][ANextY].FPartType == ptEmpty) || (FPuzzleFields[FPuzzleCount][ANextX][ANextY].FPartType == ptCrate))); } void CheckTransparency(int AXPos, int AYPos) { if (FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType == ptEmpty) FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptNone; CanAccess[AXPos][AYPos] = false; if (AllowNextStep(AXPos, AYPos - 1)) CheckTransparency(AXPos, AYPos - 1); if (AllowNextStep(AXPos + 1, AYPos)) CheckTransparency(AXPos + 1, AYPos); if (AllowNextStep(AXPos, AYPos + 1)) CheckTransparency(AXPos, AYPos + 1); if (AllowNextStep(AXPos - 1, AYPos)) CheckTransparency(AXPos - 1, AYPos); } void CreatePlayer(int AXPos, int AYPos, bool OnPos) { if (!HasPlayer) // Only one player is allowed { FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptEmpty; /// FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptPlayer; if (OnPos) FPuzzleFields[FPuzzleCount][AXPos][AYPos].FSkinType = stPlayerUpStore; else FPuzzleFields[FPuzzleCount][AXPos][AYPos].FSkinType = stPlayerUp; FGameData[FPuzzleCount].FPlayerPosX = AXPos; FGameData[FPuzzleCount].FPlayerPosY = AYPos; HasPlayer = true; } else { NewLevel = true; } } void CreateCrateTargetPart(int AXPos, int AYPos, int APart) { switch(APart) { case 0: FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptEmpty; break; case 1: { FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptEmpty; /// FPuzzleFields[FPuzzleCount][AXPos][AYPos].FPartType = ptCrate; // FPuzzleFields[FPuzzleCount][AXPos][AYPos].FCrateID = ArrayPos; FGameData[FPuzzleCount].FCratesStoredCount++; FGameData[FPuzzleCount].FCratesCount++; FGameData[FPuzzleCount].FCratesPosX.push_back(AXPos); FGameData[FPuzzleCount].FCratesPosY.push_back(AYPos); // FGameData[FPuzzleCount].FCratesPosX[ArrayPos] = AXPos; // FGameData[FPuzzleCount].FCratesPosY[ArrayPos] = AYPos; // ArrayPos++; break; } case 2: CreatePlayer(AXPos, AYPos, true); break; } FPuzzleFields[FPuzzleCount][AXPos][AYPos].FIsCrateTarget = true; FGameData[FPuzzleCount].FCrateTargetCount++; } bool IsValid(char AString[100]) { int i; if (strlen(AString) == 0) return false; if (strlen(AString) == 1) return false; for (i = 0; i < strlen(AString) - 1; i++) if ((AString[i] != '#') && (AString[i] != '@') && (AString[i] != '$') && (AString[i] != '+') && (AString[i] != '*') && (AString[i] != '.') && (AString[i] != ' ') && (AString[i] != '-')) { return false; } return true; } void MakeLevel(int AMaxX, int AMaxY) { int XPos, YPos; if (!(NewLevel) && HasPlayer) { LevelWidth = AMaxX; LevelHeight = AMaxY; FGameData[FPuzzleCount].FLevelWidth = LevelWidth; FGameData[FPuzzleCount].FLevelHeight = LevelHeight; CanAccess = new bool*[LevelWidth]; FPuzzleFields[FPuzzleCount].resize(LevelWidth); for (XPos = 0; XPos < LevelWidth; XPos++) { CanAccess[XPos] = new bool[LevelHeight]; FPuzzleFields[FPuzzleCount][XPos].resize(LevelHeight); for (YPos = 0; YPos < LevelHeight; YPos++) CanAccess[XPos][YPos] = true; } if (!HasPlayer) // skip this level { NewLevel = true; } else { CheckTransparency(FGameData[FPuzzleCount].FPlayerPosX, FGameData[FPuzzleCount].FPlayerPosY); FPuzzleCount++; } delete [] CanAccess; } } void LoadASCII(string AFileName) { FILE * AFile; int XPos, YPos; int i; LPTSTR ALine; bool NewLevel; AFile = fopen(AFileName.c_str(), "rt"); if (!(AFile == NULL)) { FPuzzleFields.resize(0); FPuzzleFields.resize(1000); FGameData.resize(0); FGameData.resize(1000); char ALine[100]; FPuzzleCount = 0; NewLevel = true; HasPlayer = false; FMaxX = 0; FMaxY = 0; while (!feof(AFile)) { fgets(ALine, 100, AFile); if (IsValid(ALine)) { if (NewLevel) { NewLevel = false; FMaxX = 0; FMaxY = 0; FGameData[FPuzzleCount].FCratesPosX.resize(0); FGameData[FPuzzleCount].FCratesPosY.resize(0); FPuzzleFields[FPuzzleCount].resize(100); for (YPos = 0; YPos < 100; YPos++) { FPuzzleFields[FPuzzleCount][YPos].resize(100); for (XPos = 0; XPos < 100; XPos++) { FPuzzleFields[FPuzzleCount][YPos][XPos].FPartType = ptEmpty; FPuzzleFields[FPuzzleCount][YPos][XPos].FIsCrateTarget = false; } } YPos = 0; ArrayPos = 0; FGameData[FPuzzleCount].FCrateTargetCount = 0; FGameData[FPuzzleCount].FCratesStoredCount = 0; FGameData[FPuzzleCount].FCratesCount = 0; HasPlayer = false; } if (FMaxX < strlen(ALine)) FMaxX = strlen(ALine); FMaxY++; for (XPos = 0; XPos < strlen(ALine); XPos++) { if (ALine[XPos] == '#') FPuzzleFields[FPuzzleCount][XPos][YPos].FPartType = ptWall; if (ALine[XPos] == '@') CreatePlayer(XPos, YPos, false); if (ALine[XPos] == '$') { FPuzzleFields[FPuzzleCount][XPos][YPos].FPartType = ptEmpty; // FPuzzleFields[FPuzzleCount][XPos][YPos].FCrateID = // ArrayPos; FGameData[FPuzzleCount].FCratesCount++; FGameData[FPuzzleCount].FCratesPosX.push_back(XPos); FGameData[FPuzzleCount].FCratesPosY.push_back(YPos); // FGameData[FPuzzleCount].FCratesPosX[ArrayPos] = XPos; // FGameData[FPuzzleCount].FCratesPosY[ArrayPos] = YPos; ArrayPos++; } if ((ALine[XPos] == ' ') || (ALine[XPos] == '-')) FPuzzleFields[FPuzzleCount][XPos][YPos].FPartType = ptEmpty; if (ALine[XPos] == '.') CreateCrateTargetPart(XPos, YPos, 0); if (ALine[XPos] == '*') CreateCrateTargetPart(XPos, YPos, 1); if (ALine[XPos] == '+') CreateCrateTargetPart(XPos, YPos, 2); } YPos++; } else { if (!NewLevel) { MakeLevel(FMaxX, FMaxY); NewLevel = true; } } } MakeLevel(FMaxX, FMaxY - 1); // the last Y is nothing, hence the - 1 FPuzzleFields.resize(FPuzzleCount); FGameData.resize(FPuzzleCount); FSokoData.FLevelsCount = FPuzzleCount; fclose(AFile); } } BOOL AllowNextStep2(int levnum, int ANextX, int ANextY) { return ((ANextX < FGameData[levnum].FLevelWidth) && ( ANextY < FGameData[levnum].FLevelHeight) && (ANextY > 0) && (ANextX > 0) && (CanAccess[ANextX][ANextY]) && ((FPuzzleFields[levnum][ANextX][ANextY].FPartType == ptEmpty) || (FPuzzleFields[levnum][ANextX][ANextY].FPartType == ptCrate))); } void CheckTransparency2(int levnum, int AXPos, int AYPos) { if (FPuzzleFields[levnum][AXPos][AYPos].FPartType == ptEmpty) FPuzzleFields[levnum][AXPos][AYPos].FPartType = ptNone; CanAccess[AXPos][AYPos] = false; if (AllowNextStep2(levnum, AXPos, AYPos - 1)) CheckTransparency2(levnum, AXPos, AYPos - 1); if (AllowNextStep2(levnum, AXPos + 1, AYPos)) CheckTransparency2(levnum, AXPos + 1, AYPos); if (AllowNextStep2(levnum, AXPos, AYPos + 1)) CheckTransparency2(levnum, AXPos, AYPos + 1); if (AllowNextStep2(levnum, AXPos - 1, AYPos)) CheckTransparency2(levnum, AXPos - 1, AYPos); } void MakeLevel2(int levnum) { int XPos, YPos; CanAccess = new bool*[FGameData[levnum].FLevelWidth]; for (int XPos = 0; XPos < FGameData[levnum].FLevelWidth; XPos++) { CanAccess[XPos] = new bool[FGameData[levnum].FLevelHeight]; for (int YPos = 0; YPos < FGameData[levnum].FLevelHeight; YPos++) CanAccess[XPos][YPos] = true; } CheckTransparency2(levnum, FGameData[levnum].FPlayerPosX, FGameData[levnum].FPlayerPosY); FPuzzleCount++; delete [] CanAccess; } void LoadLP0Level(string AFileName) { char buf[10000]; unsigned long kollevel; unsigned long pos; unsigned char leveltype,dx,dy,xx,yy; unsigned int size; char name[256],comment[256],author[256]; char c,ch,tt; unsigned long t1,t2,t3,t4,t,ttt; int i, j, kolerror =0; int FPuzzleCount; int CrateCount; FILE * f = fopen(AFileName.c_str(), "rb"); if (f == NULL) return; i= fread(buf, 17, 1, f); /* if (strcmp(buf,"Soko level pack\x1a")) // check the header { // fprintf(stderr," error %s not lp0 file\n",ss); //kolerror++; goto ex; }*/ i = fread(&kollevel, 4, 1, f); // number of levels i = fread(&ttt,4, 1, f); // position of the info i = fread(&pos,4, 1, f); // position of the levels if (ttt==0x00) { i= fread(&t1,4, 1, f); goto lv; } // if there is no info // if (ttt==0x21) i=_read(f,&t1,4); fseek(f, ttt, SEEK_SET); // i= fread(buf,ttt, 1, f); // go to info i=fread(&t1, 4, 1, f); i=fread(&t2,4, 1, f); i=fread(&t3,4, 1, f); i=fread(&t4, 4, 1, f); // read length info i=fread(buf,t1, 1, f); buf[t1]=0;// fprintf(r,"; Name: %s\n",buf); i=fread(buf,t2, 1, f); buf[t2]=0;// fprintf(r,"; Address: %s\n",buf); i=fread(buf,t3, 1, f); buf[t3]=0;// fprintf(r,"; CopyRight: %s\n",buf); i=fread(buf,t4, 1, f); buf[t4]=0;// fprintf(r,"; Information: %s\n",buf); lv: // i = fread(buf, pos, 1, f); // go to levels i=fseek(f, pos, SEEK_SET); FPuzzleFields.resize(0); FPuzzleFields.resize(kollevel); FGameData.resize(0); FGameData.resize(kollevel); FPuzzleCount = 0; for (int k = 0; k < kollevel; k++) // for each level { i = fread(buf,16, 1, f); /* if (strcmp(buf, "Soko level file\x1a")) // read level data { //fprintf(stderr," error in file %s\n",ss); //kolerror++; goto ex; }*/ i=fread(&leveltype,1, 1, f); i= fread(&tt,1, 1, f); // find type of level i=fread(buf,4, 1, f); i=fread(&dx,1, 1, f); // width level ( no more than 256) i=fread(&dy,1, 1, f); // height level i=fread(&xx,1, 1, f); // player x i=fread(&yy,1, 1, f); // player y HasPlayer = true; FPuzzleFields[FPuzzleCount].resize(dx); FGameData[FPuzzleCount].FLevelWidth = dx; FGameData[FPuzzleCount].FLevelHeight = dy; FGameData[FPuzzleCount].FPlayerPosX = xx; FGameData[FPuzzleCount].FPlayerPosY = yy; FGameData[FPuzzleCount].FCratesPosX.resize(0); FGameData[FPuzzleCount].FCratesPosY.resize(0); if (tt != 0x10) // if there are comments in a level, read them { i= fread(&t,4, 1, f); if ((tt!=0x12)&&(t==0)) goto sk; i=fread(name,t, 1, f); name[t]=0; i= fread(&t,4, 1, f); if ((tt!=0x12)&&(t==0)) goto sk; i=fread(comment,t, 1, f); comment[t]=0; i= fread(&t,4, 1, f); if ((tt!=0x12)&&(t==0)) goto sk; i=fread(author,t, 1, f); author[t]=0; i= fread(&t,4, 1, f); } else { name[0]=0; comment[0]=0; author[0]=0; } sk: size=dx*dy; if (leveltype==01) // leveltype 01 is sokoban level { FGameData[FPuzzleCount].FCrateTargetCount = 0; FGameData[FPuzzleCount].FCratesStoredCount = 0; FGameData[FPuzzleCount].FCratesCount = 0; for (i = 0; i < dx; i++) FPuzzleFields[FPuzzleCount][i].resize(dy); for (i=0;i