| MCS' Coding Tips "Success!" |
![]() |
Seamless level progression Written by MCS Tested by BrotherTank |
| Main Page News Wolfenstein 3D Texture Library MCS' Coding Tips - "Success"! Utilities Spear Resurrection Wolfendoom Wolf Collection Original Wolf 3D Doom/Duke maps Other Stuff Links Questions? Email us! |
| Most ppl use the seamless level tutorial by B.J. Rowan these days. It works OK, but it has a few drawbacks, as stated by B.J. Rowan himself. Using this method, you will have flawless level progression like in Spear of Destiny, with full level ratios (including total mission ratios) without memory constraints. In WL_MENU.C, do a search for this line: // JAPANESE VERSION remove EVERYTHING from this line to end of file and insert this block instead: if (!findfirst("*.WL6",&f,FA_ARCH)) { strcpy(extension,"WL6"); } else Quit("NO WOLFENSTEIN DATA FILES TO BE FOUND!"); strcat(configname,extension); strcat(SaveName,extension); strcat(PageFileName,extension); strcat(audioname,extension); strcat(demoname,extension); strcat(helpfilename,extension); strcat(endfilename,extension); } Also in WL_MENU.C, do a search for: void CP_NewGame(void) and scroll down until you'll find pickquick = 0; remove anything between these lines, and reinsert the block below. The complete function should read like this: void CP_NewGame(void) { int which,episode; episode = 0; // // ALREADY IN A GAME? // DrawNewGame(); if (ingame) if (!Confirm(CURGAME)) { MenuFadeOut(); return; } DrawNewGame(); which=HandleMenu(&NewItems,&NewMenu[0],DrawNewGameDiff); if (which<0) { MenuFadeOut(); return; } ShootSnd(); NewGame(which,episode); StartGame=1; MenuFadeOut(); // // CHANGE "READ THIS!" TO NORMAL COLOR // #ifndef SPEAR #ifndef GOODTIMES MainMenu[readthis].active=1; #endif #endif pickquick = 0; } Now open WL_GAME.C and remove this block: #ifndef SPEAR // // COMING BACK FROM SECRET LEVEL // if (gamestate.mapon == 9) gamestate.mapon = ElevatorBackTo[gamestate.episode]; // back from secret else // // GOING TO SECRET LEVEL // if (playstate == ex_secretlevel) gamestate.mapon = 9; #else now scroll down 25 lines until you reach #endif and remove this as well. Next, open WL_INTER.C and locate this block: #ifndef SPEAR LRstruct LevelRatios[8]; Change the 8 to the amount of levels you want to have in your project. Same goes for the following line: (Thanks to Andy_Nonymous for pointing this out!) for (kr = sr = tr = sec = i = 0;i < 8;i++) Again, change the 8 to the desired amount of levels (boss and secret levels included) Next, locate these lines: #ifndef SPEAR // // Episode One Par Times remove all lines up to and including the next #else now scroll down 24 lines until you reach #endif and remove this as well. If all went well, you should end up with the following: {1.5, "01:30"}, {3.5, "03:30"}, {2.75, "02:45"}, {3.5, "03:30"}, {0, "??:??"}, // Boss 1 {4.5, "04:30"}, {3.25, "03:15"}, {2.75, "02:45"}, {4.75, "04:45"}, {1, "01:00"}, // Boss 2 {6.5, "06:30"}, {4.5, "04:30"}, {2.75, "02:45"}, {4.5, "04:30"}, {6, "06:00"}, {0, "??:??"}, // Boss 3 {6, "06:00"}, {0, "??:??"}, // Boss 4 {0, "??:??"}, // Secret level 1 {0, "??:??"}, // Secret level 2 These are the par times for your levels. IMPORTANT: The number of par time lines has to match the value you entered in the LRstruct LevelRatios variable (see previous page). The par times are calculated in minutes. Look at the first line in this block: {1.5, "01:30"}, 1.5 means one minute and a half. The "01:30" is just the time to display in the intermission screen. All regular levels must have a par time greater than zero. The zero values and the "??:??" strings are for boss and secret levels only. Handling secret levels. Using this method, secret levels should be handled in a different way. I'll show you what I mean. Open WL_GAME.C and locate this block: #define FROMSECRET1 3 #define FROMSECRET2 11 // // GOING TO SECRET LEVEL // if (playstate == ex_secretlevel) switch(gamestate.mapon) { case FROMSECRET1: gamestate.mapon = 18; break; case FROMSECRET2: gamestate.mapon = 19; break; } else // // COMING BACK FROM SECRET LEVEL // if (gamestate.mapon == 18 || gamestate.mapon == 19) switch(gamestate.mapon) { case 18: gamestate.mapon = FROMSECRET1+1; break; case 19: gamestate.mapon = FROMSECRET2+1; break; } Remember, the gamestate.mapon variable always points to the level referred to, MINUS 1! So gamestate.mapon == 18 refers to level 19 and so on. Study the abovementioned block carefully: #define FROMSECRET1 3 #define FROMSECRET2 11 This means that both level 4 and 12 contain secret elevators. case FROMSECRET1: gamestate.mapon = 18; break; case FROMSECRET2: gamestate.mapon = 19; break; This means that after entering a secret elevator, gameplay should continue with secret levels 19 and/or 20 respectively. case 18: gamestate.mapon = FROMSECRET1+1; break; case 19: gamestate.mapon = FROMSECRET2+1; break; This means that upon completion of a secret level, gameplay should resume with the next regular level, i.c. 5 and/or 13 respectively. If you understand all of this, it should be easy to modify things to suit your needs. Customized boss and secret level intermission screens. As stated before, both boss and secret levels don't have any par times. Instead, a screen is displayed that says "Hans Grosse defeated!" or "Secret Castle Level Completed". To have your own boss and secret intermission messages, do the following: Open WL_INTER.C and locate this block: #ifdef SPEAR #ifndef SPEARDEMO switch(mapon) { case 4: Write(14,4," trans\n" " grosse\n" STR_DEFEATED); break; case 9: Write(14,4,"barnacle\n" "wilhelm\n" STR_DEFEATED); break; case 15: Write(14,4,"ubermutant\n" STR_DEFEATED); break; case 17: Write(14,4," death\n" " knight\n" STR_DEFEATED); break; case 18: Write(13,4,"secret tunnel\n" " area\n" " completed!"); break; case 19: Write(13,4,"secret castle\n" " area\n" " completed!"); break; } #endif #else Write(14,4,"secret floor\n completed!"); #endif Remove the yellow lines. Boss intermission texts will follow levels 5, 10, 16 and 18, while secret level intermission texts will be displayed after level 19 and 20. Needless to say that the levels mentioned above have to match your par time table, as stated above. Next, locate this block: #ifndef SPEAR if (mapon<8) #else if (mapon != 4 && mapon != 9 && mapon != 15 && mapon < 17) #endif Again, remove the yellow lines. Also make sure that the mentioned mapon values represent your boss and secret levels (remember, MINUS 1) Finally, locate these lines: kr /= 8; sr /= 8; tr /= 8; and replace the 8 with the number of regular levels in your addon (boss and secret levels excluded). I realize it would be quite some work to build all of this into your addon. And if you already made lots of modifications, it isn't worth the trouble anyway, I presume. But if you're about to start a new project, you might want to use these alterations as a starting point. To make things easy, you can download all the modifications in one package here. This package is prepared to have 60 levels. To save some memory, you might want to delete the par times that you don't need and adjust the LRstruct LevelRatios accordingly. Success! MCS. |