Setting up Campaigns
This article is an attempt to describe the various options mappers need to consider when setting up campaigns or multi-mission packages (I'll refer to campaigns for both of these for the sake of simplicity). Campaign support has been added in TDM 1.06.
Map Files
Regular, single-map TDM missions are packed in PK4 files, campaigns are no different. If your campaign consists of three missions ("red.map", "blue.map" and "green.map"), all three of them still go into the same maps folder in your PK4 file.
The actual order in which the missions are to be played is defined through the tdm_mapsequence.txt file, which should be added to the PK4 (just next to the readme.txt). Following the example of the "red", "blue" and "green" maps above the map sequence file would look like this:
Mission 1: red Mission 2: blue Mission 3: green
Looking at that, the syntax of the file is pretty much self-explanatory. The first mission has the number one, the map file is mentioned after the colon and the following space. You don't need to specify the ".map" extension of the map file that is handled automatically. See the main tdm_mapsequence.txt article for further reference, for this article it's enough to have the above lines I suppose.
Briefings
Once the map sequence is defined one needs to take care of the briefing. If you like to keep it simple, just refer to the Briefing article in the Text-only Briefing section. Each map needs its own xdata block with the briefing and you'll be done.
For advanced setups like the "Timed Flowing Briefing" mentioned in the Briefing article there are a few modifications to be made to your GUI code. As the mainmenu_briefing.gui file is the same for the whole campaign your GUI needs to know which map the player is about to play next. For this purpose a new GUI variable gui::CurrentMission has been introduced which can be used in if-else GUI code blocks in the BriefingStateInit windowDef. For single-missions, mappers just called the GUI animation block like this:
windowDef BriefingStateInit { noTime 1 // Init methods have onTime 10 instead of onTime 0. onTime 10 { // ... stuff set "BriefingAnimation::visible" "1"; resetTime "BriefingAnimation" 0; // ... stuff } }
For multi-mission setups an if-else block should be added to switch to the correct briefing animation for the current map:
windowDef BriefingStateInit { noTime 1 // Init methods have onTime 10 instead of onTime 0. onTime 10 { // ... stuff if ("gui::CurrentMission" == 1) { set "BriefingMission1Animation::visible" "1"; resetTime "BriefingMission1Animation" 0; } else if ("gui::CurrentMission" == 2) { set "BriefingMission2Animation::visible" "1"; resetTime "BriefingMission2Animation" 0; } // ... stuff } }
Of course you'll need to define a BriefingMissionXAnimation block for each mission. You can use the instructions in the Briefing article to learn how to do that, just keep in mind to change the windowDef's name such that you don't end up with duplicate names for your windowDefs (this will lead to warnings in the console at game startup at best).
Starting the correct mission briefing animation is only half the rent, you'll need to stop the correct animation as well when the player proceeds to the objectives screen:
windowDef BriefingStateEnd { noTime 1 onTime 0 { // ... stuff if ("gui::CurrentMission" == 1) { set "BriefingMission1Animation::visible" "0"; set "BriefingMission1Animation::notime" "1"; } else if ("gui::CurrentMission" == 2) { set "BriefingMission2Animation::visible" "0"; set "BriefingMission2Animation::notime" "1"; } // ... stuff } }
If you don't do that the player might see remnants of the previous mission's briefing when proceeding to the next map briefing.