1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
|
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef _MISSION_CAMPAIGN_H
#define _MISSION_CAMPAIGN_H
#include "stats/scoring.h"
#include "parse/sexp.h"
#include "cfile/cfile.h"
#include "parse/sexp_container.h"
struct sexp_variable;
// name of the builtin campaign.
#define BUILTIN_CAMPAIGN "FreeSpace2"
#define MAX_CAMPAIGN_MISSIONS 100 // maximum number of missions in a campaign
#define CAMPAIGN_ERROR_CORRUPT -1
#define CAMPAIGN_ERROR_SEXP_EXHAUSTED -2
#define CAMPAIGN_ERROR_MISSING -3
#define CAMPAIGN_ERROR_SAVEFILE -4
#define CAMPAIGN_ERROR_IGNORED -5
// types of campaigns -- these defines match the string literals listed below which
// are found in the campaign files. I don't think that we need campaigns for furball
// missions.
#define CAMPAIGN_TYPE_SINGLE 0
#define CAMPAIGN_TYPE_MULTI_COOP 1
#define CAMPAIGN_TYPE_MULTI_TEAMS 2
#define MAX_CAMPAIGN_TYPES 3
// type of movies we may be able to play
#define CAMPAIGN_MOVIE_PRE_MISSION 1
#define CMAPAIGN_MOVIE_POST_MISSION 2
#define CAMPAIGN_SINGLE_PLAYER_SIG 0xddddeeee
#define CAMPAIGN_MULTI_PLAYER_SIG 0xeeeeffff
// defines for possibly persistent information
#define CAMPAIGN_PERSISTENT_SHIP 1
#define CAMPAIGN_PERSISTENT_WEAPON 2
// Goober5000 - Bastion flag is not needed anymore; there can now be more than two main halls;
// but the flag is kept in order to maintain compatibility with older campaigns
#define CMISSION_FLAG_BASTION (1<<0) // set if stationed on Bastion, else Galatea
#define CMISSION_FLAG_SKIPPED (1<<1) // set if skipped, else not
#define CMISSION_FLAG_HAS_LOOP (1<<2) // mission loop, e.g. FS2 SOC loops
#define CMISSION_FLAG_HAS_FORK (1<<3) // campaign fork, e.g. Scroll or BWO (mutually exclusive with loop)
// internal flags start from the end, except for some flags that are grandfathered in
#define CMISSION_FLAG_FRED_LOAD_PENDING (1<<31) // originally handled by num_goals being set to -1
#define CMISSION_FIRST_INTERNAL_FLAG CMISSION_FLAG_FRED_LOAD_PENDING
// all flags below FIRST_INTERNAL_FLAG, except SKIPPED, HAS_LOOP, and HAS_FORK
#define CMISSION_EXTERNAL_FLAG_MASK ((static_cast<unsigned int>(CMISSION_FIRST_INTERNAL_FLAG) - 1) & ~CMISSION_FLAG_SKIPPED & ~CMISSION_FLAG_HAS_LOOP & ~CMISSION_FLAG_HAS_FORK)
#define CAMPAIGN_LOOP_MISSION_UNINITIALIZED -2
extern const char *campaign_types[MAX_CAMPAIGN_TYPES];
// campaign flags - Goober5000
#define CF_DEFAULT_VALUE 0
#define CF_CUSTOM_TECH_DATABASE (1 << 0) // Goober5000
// structure for a campaign definition. It contains the mission names and other interesting
// information about a campaign and the mission strucuture within.
typedef struct mgoal {
char name[NAME_LENGTH]; // name of the goal (same as name in the mission_goal structure
char status; // failed, satisfied, or incomplete (same as goal completion);
} mgoal;
typedef struct mevent {
char name[NAME_LENGTH];
char status;
} mevent;
class cmission
{
public:
char *name; // name of the mission
char *notes; // mission notes for mission (used by Fred)
char briefing_cutscene[NAME_LENGTH]; // name of the cutscene to be played before this mission
int formula; // sexpression used to determine mission branching.
int completed; // has the player completed this mission
SCP_vector<mgoal> goals; // vector of mgoals which has the goal completion status
SCP_vector<mevent> events; // vector of mevents which has the event completion status
SCP_vector<sexp_variable> variables; // vector of sexp_variables (of num_variables size) containing mission-persistent variables - Goober5000
int mission_loop_formula; // formula to determine whether to allow a side loop
char *mission_branch_desc; // message in popup
char *mission_branch_brief_anim;
char *mission_branch_brief_sound;
int level; // what level of the tree it's on (Fred)
int pos; // what x position on level it's on (Fred)
int flags;
SCP_string main_hall; // which main hall the player is in - converted to SCP_string by CommanderDJ
ubyte debrief_persona_index; // which persona is used for ranks/badges - Goober5000
scoring_struct stats;
};
class campaign
{
public:
char name[NAME_LENGTH]; // name of the campaign
char filename[CF_MAX_PATHNAME_LENGTH]; // filename the campaign info is in
char *desc; // description of campaign
int type; // type of campaign
int flags; // flags - Goober5000
int num_missions; // number of missions in the campaign
int num_missions_completed; // number of missions in the campaign that have been flown
int current_mission; // the current mission that the player is playing. Only valid during the mission
int next_mission; // number of the next mission to fly when comtinuing the campaign. Always valid
int prev_mission; // mission that we just came from. Always valid
int loop_enabled; // whether mission loop is chosen - true during a loop, false otherwise
int loop_mission; // mission number of misssion loop (if any)
int loop_reentry; // mission number to return to after loop is finished
int realign_required; // are any missions missing alignment info? (Fred)
int num_players; // valid in multiplayer campaigns -- number of players campaign supports.
ubyte ships_allowed[MAX_SHIP_CLASSES]; // which ships the player can use
ubyte weapons_allowed[MAX_WEAPON_TYPES]; // which weapons the player can use
cmission missions[MAX_CAMPAIGN_MISSIONS]; // decription of the missions
SCP_vector<sexp_variable> persistent_variables; // These variables will be saved at the end of a mission
SCP_vector<sexp_variable> red_alert_variables; // state of the variables in the previous mission of a Red Alert scenario.
SCP_vector<sexp_container> persistent_containers; // These containers will be saved at the end of a mission
SCP_vector<sexp_container> red_alert_containers; // state of the containers in the previous mission of a Red Alert scenario.
campaign()
: desc(nullptr), num_missions(0)
{
name[0] = 0;
filename[0] = 0;
}
};
extern campaign Campaign;
// campaign wasn't ended
extern int Campaign_ending_via_supernova;
// extern'ed so the mission loading can get a list of campains. Only use this
// data after mission_campaign_build_list() is called
#define MAX_CAMPAIGNS 128
extern char *Campaign_names[MAX_CAMPAIGNS];
extern char *Campaign_file_names[MAX_CAMPAIGNS];
extern char *Campaign_descs[MAX_CAMPAIGNS];
extern int Num_campaigns;
extern int Campaign_names_inited;
extern SCP_vector<SCP_string> Ignored_campaigns;
extern char Default_campaign_file_name[MAX_FILENAME_LEN - 4];
extern bool Campaign_file_missing; // if the campaign file is missing this will get set for us to check against
extern int Campaign_load_failure;
/*
* initialise Player_loadout with default values
*/
void player_loadout_init();
// called at game startup time to load the default single player campaign
void mission_campaign_init( void );
// load up and initialize a new campaign
int mission_campaign_load(const char* filename, const char* full_path = nullptr, player* pl = nullptr, int load_savefile = 1);
bool campaign_is_ignored(const char *filename);
// declaration for local campaign save game load function
extern void mission_campaign_savefile_delete(const char* cfilename);
extern void mission_campaign_delete_all_savefiles( char *pilot_name );
// if a given campaign is a multiplayer campaign, we can load and save the multiplayer info portion with these functions
extern int mission_campaign_parse_is_multi(const char *filename, char *name);
// function which sets up internal variable for player to play next mission in the campaign
extern int mission_campaign_next_mission( void );
// function which is called with the current mission in this campaign is over
extern void mission_campaign_mission_over( bool do_next_mission = true );
// frees all memory at game close time
extern void mission_campaign_clear( void );
// used by Fred to get a mission's list of goals.
void read_mission_goal_list(int num);
void mission_campaign_build_list(bool desc = false, bool sort = true, bool multiplayer = false);
void mission_campaign_free_list();
// returns index of mission with passed name
extern int mission_campaign_find_mission( const char *name );
// maybe play a movie. type indicates before or after mission
extern void mission_campaign_maybe_play_movie(int type);
// save persistent information
extern void mission_campaign_save_persistent( int type, int index );
// The following are functions I added to set up the globals and then
// execute the corresponding mission_campaign_savefile functions.
// get name and type of specified campaign file
int mission_campaign_get_info(const char *filename, char *name, int *type, int *max_players, char **desc = nullptr, char **first_mission = nullptr);
// get a listing of missions in a campaign
int mission_campaign_get_mission_list(const char *filename, char **list, int max);
// load up a campaign for the current player.
int mission_load_up_campaign(bool fall_back_from_current = false);
// stores mission goals and events in Campaign struct
void mission_campaign_store_goals_and_events();
// stores variables which will be saved only on mission progression
void mission_campaign_store_variables(int persistence_type, bool store_red_alert = true);
// stores containers which will be saved only on mission progression
void mission_campaign_store_containers(ContainerType persistence_type, bool store_red_alert = true);
// does all three of the above
void mission_campaign_store_goals_and_events_and_variables();
// evaluates next mission and possible loop mission
void mission_campaign_eval_next_mission();
// returns to the beginning of the previous mission
int mission_campaign_previous_mission();
// proceeds to next mission in campaign
void mission_campaign_skip_to_next();
// break out of loop
void mission_campaign_exit_loop();
// jump to specified mission
void mission_campaign_jump_to_mission(const char* name, bool no_skip = false);
// stuff for the end of the campaign of the single player game
void mission_campaign_end_init();
void mission_campaign_end_close();
void mission_campaign_end_do();
// save eternal variables
extern void mission_campaign_save_on_close_variables();
// save eternal containers
extern void mission_campaign_save_on_close_containers();
extern void mission_campaign_load_failure_popup();
SCP_string mission_campaign_get_name(const char* filename);
// End CSFE stuff
#endif
|