14 #include "MissionSave.h"
18 #include "FredRender.h"
25 #include "CampaignTreeWnd.h"
26 #include "CampaignTreeView.h"
27 #include "CampaignEditorDlg.h"
30 #include "Management.h"
52 void CFred_mission_save::convert_special_tags_to_retail(
char *text,
int max_len)
58 void CFred_mission_save::convert_special_tags_to_retail(
SCP_string &text)
65 void CFred_mission_save::convert_special_tags_to_retail()
77 convert_special_tags_to_retail(
Cmd_briefs[team].stage[stage].text);
99 void CFred_mission_save::save_mission_internal(
const char *pathname)
103 t = CTime::GetCurrentTime();
110 nprintf((
"Error",
"Can't open mission file to save.\n"));
116 convert_special_tags_to_retail();
118 if (save_mission_info())
120 else if (save_plot_info())
122 else if (save_variables())
126 else if (save_cutscenes())
128 else if (save_fiction())
130 else if (save_cmd_briefs())
132 else if (save_briefing())
134 else if (save_debriefing())
136 else if (save_players())
138 else if (save_objects())
140 else if (save_wings())
142 else if (save_events())
144 else if (save_goals())
146 else if (save_waypoints())
148 else if (save_messages())
154 else if (save_asteroid_fields())
156 else if (save_music())
168 mprintf((
"Mission saving error code #%d\n", err));
176 p = strrchr(pathname,
'\\');
185 save_mission_internal(savepath);
189 if (backup_name[strlen(backup_name) - 4] ==
'.')
190 backup_name[strlen(backup_name) - 4] = 0;
204 char backup_name[256], name2[256];
207 len = strlen(pathname);
213 sprintf(backup_name + len,
".%.3d", i - 1);
214 sprintf(name2 + len,
".%.3d", i);
218 strcpy(backup_name + len,
".001");
220 save_mission_internal(backup_name);
225 int CFred_mission_save::save_mission_info()
271 fout(
"\n\n+Game Type:");
278 fout(
"\n+Game Type Flags:");
318 fout(
"\n+Num Players:");
325 fout(
"\n+Num Respawns:");
350 fout(
"\n+Red Alert:");
360 fout(
"\n+Scramble:");
368 fout(
"\n+Disallow Support:");
379 fout(
"\n+Hull Repair Ceiling:");
386 fout(
"\n+Subsystem Repair Ceiling:");
395 fout(
"\n+All Teams Attack");
403 fout(
"\n\n+Player Entry Delay:");
411 fout(
"\n\n+Viewer pos:");
419 fout(
"\n+Viewer orient:");
444 fout(
"\n$Starting wing names: ( ");
457 fout(
"\n$Squadron wing names: ( ");
470 fout(
"\n$Team-versus-team wing names: ( ");
491 period = strrchr(out_str,
'.');
498 fout(
" %s.pof", out_str);
577 int CFred_mission_save::save_plot_info()
612 fout(
"\n\n#Plot Info\n\n");
617 fout(
"$Pre-Briefing Cutscene: Blah\n");
618 fout(
"$Pre-Mission Cutscene: Blah\n");
619 fout(
"$Next Mission Success: Blah\n");
620 fout(
"$Next Mission Partial: Blah\n");
621 fout(
"$Next Mission Failure: Blah\n");
632 int CFred_mission_save::save_cutscenes()
652 strcpy_s(type,
"$Fiction Viewer Cutscene:");
655 strcpy_s(type,
"$Command Brief Cutscene:");
658 strcpy_s(type,
"$Briefing Cutscene:");
661 strcpy_s(type,
"$Pre-game Cutscene:");
664 strcpy_s(type,
"$Debriefing Cutscene:");
667 strcpy_s(type,
"$Campaign End Cutscene:");
685 fout(
" %s", sexp_out.c_str());
692 MessageBox(NULL,
"Warning: This mission contains cutscene data, but you are saving in the retail mission format. This information will be lost",
"Incompatibility with retail mission format",
MB_OK);
700 int CFred_mission_save::save_fiction()
709 fout(
"\n\n#Fiction Viewer");
719 fout(
" %s", stage->story_filename);
722 if (strlen(stage->font_filename) > 0)
728 fout(
" %s", stage->font_filename);
734 if (strlen(stage->voice_filename) > 0)
740 fout(
" %s", stage->voice_filename);
746 if (strlen(stage->ui_name) > 0)
752 fout(
" %s", stage->ui_name);
758 save_custom_bitmap(
"$Background 640:",
"$Background 1024:", stage->background[
GR_640], stage->background[
GR_1024]);
770 fout(
" %s", sexp_out.c_str());
778 MessageBox(NULL,
"Warning: This mission contains fiction viewer data, but you are saving in the retail mission format.",
"Incompatibility with retail mission format",
MB_OK);
787 int CFred_mission_save::save_cmd_brief()
826 int CFred_mission_save::save_cmd_briefs()
838 int CFred_mission_save::save_briefing()
854 save_custom_bitmap(
"$ship_select_background_640:",
"$ship_select_background_1024:",
Briefings[nb].ship_select_background[
GR_640],
Briefings[nb].ship_select_background[
GR_1024]);
855 save_custom_bitmap(
"$weapon_select_background_640:",
"$weapon_select_background_1024:",
Briefings[nb].weapon_select_background[
GR_640],
Briefings[nb].weapon_select_background[
GR_1024]);
925 fout(
" %s", sexp_out.c_str());
950 save_vector(bi->
pos);
1017 int CFred_mission_save::save_debriefing()
1039 fout(
" %s", sexp_out.c_str());
1076 int CFred_mission_save::save_variables()
1079 char number[] =
"number";
1080 char string[] =
"string";
1081 char block[] =
"block";
1083 int num_block_vars = 0;
1095 int total_variables = num_variables + num_block_vars;
1097 if (total_variables > 0) {
1109 for (i=0; i<num_variables; i++) {
1123 fout(
"\t\t\"%s\"",
"network-variable");
1128 fout(
"\t\t\"%s\"",
"player-persistent");
1131 fout(
"\t\t\"%s\"",
"campaign-persistent");
1154 int CFred_mission_save::save_players()
1169 fout(
"\n\n#Alternate Types:\n");
1182 fout(
"\n\n#Callsigns:\n");
1209 if (strlen(
Team_data[i].ship_list_variables[j])) {
1220 if (strlen(
Team_data[i].ship_count_variables[j])) {
1236 fout(
"\n\n+Weaponry Pool:");
1243 if (strlen(
Team_data[i].weaponry_pool_variable[j])) {
1256 if (strlen(
Team_data[i].weaponry_amount_variable[j])) {
1263 if (strlen(
Team_data[i].weaponry_pool_variable[j])) {
1275 if (used_pool[j] > 0){
1283 bool uses_required_weapon =
false;
1288 uses_required_weapon =
true;
1292 if (uses_required_weapon)
1297 fout(
"\n+Required for mission:");
1319 Assert(shipp && dock_ptr);
1331 fout(
"\n+Docked With:");
1350 int CFred_mission_save::save_objects()
1364 if (
Ships[i].objnum < 0){
1389 if (ii->variable_index != -1) {
1393 fout(
"\n$Alt Ship Class: \"%s\"",
Ship_info[ii->ship_class].name);
1397 if (ii->default_to_this_class) {
1398 fout(
"\n+Default Class:");
1435 fout(
" %s",
"IFF 1");
1449 fout(
"\n+AI Class:");
1476 fout(
"\n+Arrival Distance:");
1483 fout(
"\n$Arrival Anchor:");
1511 int j, anchor_shipnum;
1515 Assert(anchor_shipnum >= 0 && anchor_shipnum < MAX_SHIPS);
1517 fout(
"\n+Arrival Paths: ( ");
1537 fout(
"\n+Arrival Delay:");
1545 fout(
" %s", sexp_out.c_str());
1567 int j, anchor_shipnum;
1571 Assert(anchor_shipnum >= 0 && anchor_shipnum < MAX_SHIPS);
1573 fout(
"\n+Departure Paths: ( ");
1593 fout(
"\n+Departure delay:");
1601 fout(
" %s", sexp_out.c_str());
1611 fout(
"\n+Flags: (");
1614 fout(
" \"cargo-known\"");
1616 fout(
" \"ignore-count\"");
1618 fout(
" \"protect-ship\"");
1620 fout(
" \"reinforcement\"");
1622 fout(
" \"no-shields\"");
1624 fout(
" \"escort\"");
1626 fout(
" \"player-start\"");
1628 fout(
" \"no-arrival-music\"");
1630 fout(
" \"no-arrival-warp\"");
1632 fout(
" \"no-departure-warp\"");
1634 fout(
" \"invulnerable\"");
1636 fout(
" \"hidden-from-sensors\"");
1638 fout(
" \"scannable\"");
1640 fout(
" \"kamikaze\"");
1642 fout(
" \"no-dynamic\"");
1644 fout(
" \"red-alert-carry\"");
1646 fout(
" \"beam-protect-ship\"");
1648 fout(
" \"flak-protect-ship\"");
1650 fout(
" \"laser-protect-ship\"");
1652 fout(
" \"missile-protect-ship\"");
1654 fout(
" \"guardian\"");
1656 fout(
" \"special-warp\"");
1658 fout(
" \"vaporize\"");
1660 fout(
" \"stealth\"");
1662 fout(
" \"friendly-stealth-invisible\"");
1664 fout(
" \"don't-collide-invisible\"");
1667 fout(
" \"locked\"");
1677 fout(
"\n+Flags2: (");
1680 fout(
" \"primitive-sensors\"");
1682 fout(
" \"no-subspace-drive\"");
1684 fout(
" \"nav-carry-status\"");
1686 fout(
" \"affected-by-gravity\"");
1688 fout(
" \"toggle-subsystem-scanning\"");
1690 fout(
" \"targetable-as-bomb\"");
1692 fout(
" \"no-builtin-messages\"");
1694 fout(
" \"primaries-locked\"");
1696 fout(
" \"secondaries-locked\"");
1698 fout(
" \"no-death-scream\"");
1700 fout(
" \"always-death-scream\"");
1702 fout(
" \"nav-needslink\"");
1704 fout(
" \"hide-ship-name\"");
1706 fout(
" \"set-class-dynamically\"");
1708 fout(
" \"lock-all-turrets\"");
1710 fout(
" \"afterburners-locked\"");
1712 fout(
" \"force-shields-on\"");
1714 fout(
" \"immobile\"");
1716 fout(
" \"no-ets\"");
1718 fout(
" \"cloaked\"");
1720 fout(
" \"ship-locked\"");
1722 fout(
" \"weapons-locked\"");
1724 fout(
" \"scramble-messages\"");
1726 fout(
" \"no-collide\"");
1728 fout(
" \"no-disabled-self-destruct\"");
1739 fout(
"\n+Escort priority:");
1774 bypass_comment(
";;FSO 3.6.13;; +Special Exp Shockwave Speed:",
"$Name:");
1783 bypass_comment(
";;FSO 3.6.13;; +Special Exp Death Roll Time:",
"$Name:");
1815 bypass_comment(
";;FSO 3.6.13;; +Special Exp Shockwave Speed:",
"$Name:");
1816 bypass_comment(
";;FSO 3.6.13;; +Special Exp Death Roll Time:",
"$Name:");
1822 int special_exp_index;
1825 fout(
"\n+Special Exp index:");
1826 fout(
" %d", special_exp_index);
1829 CString text =
"You are saving in the retail mission format, but ";
1830 text +=
"the mission has too many special explosions defined. \"";
1832 text +=
"\" has therefore lost any special explosion data that was defined for it. ";
1833 text +=
"\" Either remove special explosions or SEXP variables if you need it to have one ";
1870 bypass_comment(
";;FSO 3.6.13;; +Special Shield Points:",
"$Name:");
1879 fout(
"\n+Kamikaze Damage:");
1885 if (shipp->
hotkey != -1) {
1902 static bool warned =
false;
1905 CString text =
"You are saving in the retail mission format, but \"";
1907 text +=
"\" is docked to more than one ship. If you wish to run this mission in retail, ";
1908 text +=
"you should remove the additional ships and save the mission again.";
1909 MessageBox(NULL, text,
"Incompatibility with retail mission format",
MB_OK);
1930 save_single_dock_instance(&
Ships[i], dock_ptr);
1941 fout(
"\n+Destroy At: ");
1952 fout(
"\n+Orders Accepted:");
1957 if (shipp->
group >= 0) {
2001 bypass_comment(
";;FSO 3.6.10;; +Assist Score Percentage:",
"$Name:");
2009 fout(
"\n+Persona Index:");
2016 bool needs_header =
true;
2028 needs_header =
false;
2034 fout(
" %s", ii->old_texture);
2041 fout(
" %s", ii->new_texture);
2065 int CFred_mission_save::save_common_object_data(
object *objp,
ship *shipp)
2071 float temp_max_hull_strength;
2079 fout(
"\n+Initial Velocity:");
2098 fout(
"\n+Initial Hull:");
2107 fout(
"\n+Initial Shields:");
2120 while (j-- && (j >= 0))
2128 fout(
"\n+Primary Banks:");
2144 while (j-- && (j >= 0))
2152 fout(
"\n+Secondary Banks:");
2168 while (j-- && (j >= 0))
2176 fout(
"\n+Sbank Ammo:");
2194 fout(
"\n+Subsystem:");
2212 fout(
"\n+Cargo Name:");
2244 int CFred_mission_save::save_wings()
2255 if (!
Wings[i].wave_count)
2267 if (strlen(
Wings[i].wing_squad_filename) > 0)
2272 fout(
"\n+Squad Logo:");
2274 fout(
" %s",
Wings[i].wing_squad_filename);
2288 fout(
" %d\t\t;! %s\n",
Wings[i].special_ship,
2300 fout(
"\n+Arrival Distance:");
2306 fout(
"\n$Arrival Anchor:");
2309 if (z & SPECIAL_ARRIVAL_ANCHOR_FLAG)
2333 int j, anchor_shipnum;
2337 Assert(anchor_shipnum >= 0 && anchor_shipnum < MAX_SHIPS);
2339 fout(
"\n+Arrival Paths: ( ");
2344 if (
Wings[i].arrival_path_mask & (1 << j))
2354 if (
Wings[i].arrival_delay)
2359 fout(
"\n+Arrival delay:");
2367 fout(
" %s", sexp_out.c_str());
2378 if (
Wings[i].departure_anchor >= 0 )
2389 int j, anchor_shipnum;
2393 Assert(anchor_shipnum >= 0 && anchor_shipnum < MAX_SHIPS);
2395 fout(
"\n+Departure Paths: ( ");
2400 if (
Wings[i].departure_path_mask & (1 << j))
2410 if (
Wings[i].departure_delay)
2415 fout(
"\n+Departure delay:");
2423 fout(
" %s", sexp_out.c_str());
2427 fout(
" (\t\t;! %d total\n",
Wings[i].wave_count);
2441 if (
Wings[i].hotkey != -1) {
2454 fout(
"\n+Flags: (");
2457 fout(
" \"ignore-count\"");
2459 fout(
" \"reinforcement\"");
2461 fout(
" \"no-arrival-music\"");
2463 fout(
" \"no-arrival-message\"");
2465 fout(
" \"no-arrival-warp\"");
2467 fout(
" \"no-departure-warp\"");
2469 fout(
" \"no-dynamic\"" );
2473 if (
Wings[i].wave_delay_min) {
2477 fout(
"\n+Wave Delay Min:");
2482 if (
Wings[i].wave_delay_max) {
2486 fout(
"\n+Wave Delay Max:");
2500 int CFred_mission_save::save_goals()
2540 fout(
" %s", sexp_out.c_str());
2553 fout(
"\n+No music");
2580 int CFred_mission_save::save_waypoints()
2594 save_vector(jnp->GetSCPObject()->pos);
2598 fout(
" %s", jnp->GetName());
2600 if(jnp->IsSpecialModel())
2605 fout(
"\n+Model File:");
2607 int model = jnp->GetModelNumber();
2612 if(jnp->IsColored())
2617 fout(
"\n+Alphacolor:");
2619 color jn_color = jnp->GetColor();
2627 if(hidden_is_there || jnp->IsHidden())
2629 if(!hidden_is_there)
2633 fout(
" %s",
"true");
2635 fout(
" %s",
"false");
2647 fout(
" %s", ii->get_name());
2651 fout(
" (\t\t;! %d points in list\n", ii->get_waypoints().size());
2653 save_waypoint_list(&(*ii));
2664 int CFred_mission_save::save_waypoint_list(
waypoint_list *wp_list)
2672 fout(
"\t( %f, %f, %f )\n", pos->
xyz.x, pos->
xyz.y, pos->
xyz.z);
2678 int CFred_mission_save::save_messages()
2720 if (
Messages[i].persona_index != -1 ) {
2724 fout(
"\n+Persona:");
2733 fout(
"\n+AVI Name:");
2742 fout(
"\n+Wave Name:");
2755 int CFred_mission_save::save_vector(
vec3d &
v)
2761 int CFred_mission_save::save_matrix(
matrix &
m)
2763 fout(
"\n\t%f, %f, %f,\n", m.
vec.rvec.xyz.x, m.
vec.rvec.xyz.y, m.
vec.rvec.xyz.z);
2764 fout(
"\t%f, %f, %f,\n", m.
vec.uvec.xyz.x, m.
vec.uvec.xyz.y, m.
vec.uvec.xyz.z);
2765 fout(
"\t%f, %f, %f", m.
vec.fvec.xyz.x, m.
vec.fvec.xyz.y, m.
vec.fvec.xyz.z);
2773 char *ch = strstr(raw_ptr, comment);
2777 char *ep = strstr(raw_ptr, end);
2778 if (ep != NULL && ep < ch)
2782 char *readp = strchr(writep,
'\n');
2785 while (*readp !=
'\0')
2800 char *comment_start = NULL;
2801 int state = 0, same_line = 0, first_comment = 1, tab = 0, flag = 0;
2802 bool version_added =
false;
2805 newlines = -newlines;
2813 while (newlines-- > 0)
2835 same_line = newlines - 1 + same_line;
2836 while (same_line-- > 0)
2856 if ((*raw_ptr ==
'/') && (raw_ptr[1] ==
'*')) {
2857 comment_start = raw_ptr;
2861 if ((*raw_ptr ==
';') && (raw_ptr[1] !=
'!')) {
2862 comment_start = raw_ptr;
2867 if ( (raw_ptr[1] ==
';') && (raw_ptr[2] ==
'F') && (raw_ptr[3] ==
'S') && (raw_ptr[4] ==
'O') ) {
2868 int major, minor, build, revis;
2886 if (*raw_ptr ==
'\n')
2889 if (flag && state && !(state == 3) )
2893 if (*raw_ptr ==
'\n') {
2895 if (first_comment && !flag)
2899 fout(
"%s\n", comment_start);
2901 state = first_comment = same_line = flag = 0;
2902 }
else if (state == 4) {
2903 same_line = newlines - 2 + same_line;
2904 while (same_line-- > 0)
2907 if (*(raw_ptr-1) ==
'\r') {
2908 *(raw_ptr-1) =
'\0';
2913 fout(
"%s\n", comment_start);
2915 if (*(raw_ptr-1) ==
'\0') {
2916 *(raw_ptr-1) =
'\r';
2921 state = first_comment = same_line = flag = 0;
2925 if ((*raw_ptr ==
'*') && (raw_ptr[1] ==
'/') && (state == 1)) {
2926 if (first_comment && !flag)
2929 const char tmp = raw_ptr[2];
2931 fout(
"%s", comment_start);
2933 state = first_comment = flag = 0;
2936 if ( (*raw_ptr ==
';') && (raw_ptr[1] ==
';') && (state == 3) ) {
2937 const char tmp = raw_ptr[2];
2942 version_added =
true;
2945 state = first_comment = flag = 0;
2972 while (*format ==
'\n') {
2973 str_scp.append(1, *format);
2977 str_scp.append(fso_ver_comment.back().c_str());
2978 str_scp.append(
" ");
2980 cfputs(str_scp.c_str(), fp);
2985 va_start(args, format);
2989 char *str_c =
vm_strdup(str_scp.c_str());
2993 bool first_line =
true;
2994 char *str_p = str_c;
2996 ch = strchr(str_c,
'\n');
2999 if ( (ch != NULL) && (*(ch+1) !=
'\0') ) {
3001 if ( *(ch+1) !=
'\0' ) {
3007 cfputs(fso_ver_comment.back().c_str(), fp);
3019 cfputs(fso_ver_comment.back().c_str(), fp);
3029 }
while ( (ch = strchr(str_p,
'\n')) != NULL );
3032 if ( strlen(str_p) ) {
3033 cfputs(fso_ver_comment.back().c_str(), fp);
3058 va_start(args, format);
3077 va_start(args, format);
3082 str_out_scp = pre_str;
3090 str_out_scp +=
" XSTR(\"";
3091 str_out_scp += str_scp;
3092 str_out_scp +=
"\", -1)";
3102 str_out_scp +=
" XSTR(\"";
3103 str_out_scp += str_scp;
3104 str_out_scp +=
"\", ";
3109 char *str_out_c =
vm_strdup(str_out_scp.c_str());
3112 if ( !fso_ver_comment.empty() ) {
3113 bool first_line =
true;
3114 char *str_p = str_out_c;
3116 char *ch = strchr(str_out_c,
'\n');
3119 if ( (ch != NULL) && (*(ch+1) !=
'\0') ) {
3121 if ( *(ch+1) !=
'\0' ) {
3127 cfputs(fso_ver_comment.back().c_str(), fp);
3139 cfputs(fso_ver_comment.back().c_str(), fp);
3149 }
while ( (ch = strchr(str_p,
'\n')) != NULL );
3152 if ( strlen(str_p) ) {
3153 cfputs(fso_ver_comment.back().c_str(), fp);
3171 char *str = NULL,
buf[80];
3172 int i, valid, flag = 1;
3182 fout(
"\n$AI Goals:");
3189 fout(
"( ai-chase-any %d ) ", goalp[i].priority);
3192 fout(
"( ai-undock %d ) ", goalp[i].priority);
3195 fout(
"( ai-keep-safe-distance %d ) ", goalp[i].priority);
3198 fout(
"( ai-play-dead %d ) ", goalp[i].priority);
3201 fout(
"( ai-warp-out %d ) ", goalp[i].priority);
3205 if (!goalp[i].target_name) {
3209 sprintf(buf,
"\"%s\"", goalp[i].target_name);
3210 switch (goalp[i].ai_mode) {
3212 str =
"ai-waypoints";
3216 str =
"ai-waypoints-once";
3222 Warning(
LOCATION,
"AI destroy subsystem goal invalid subsystem name\n");
3225 sprintf(buf,
"\"%s\" \"%s\"", goalp[i].target_name, goalp[i].
docker.name);
3226 str =
"ai-destroy-subsystem";
3239 "(docking with \"%s\")\n",
Ships[ship].ship_name, goalp[i].target_name);
3244 "(docking with \"%s\")\n",
Ships[ship].ship_name, goalp[i].target_name);
3247 sprintf(buf,
"\"%s\" \"%s\" \"%s\"", goalp[i].target_name,
3259 str =
"ai-chase-wing";
3267 str =
"ai-guard-wing";
3271 str =
"ai-disable-ship";
3275 str =
"ai-disarm-ship";
3283 str =
"ai-ignore-new";
3287 str =
"ai-evade-ship";
3291 str =
"ai-stay-near-ship";
3295 str =
"ai-stay-still";
3303 fout(
"( %s %s %d ) ", str, buf, goalp[i].priority);
3316 int CFred_mission_save::save_events()
3331 fout(
" %s", sexp_out.c_str());
3346 fout(
"\n+Repeat Count:");
3372 fout(
"\n+Interval:");
3390 fout(
"\n+Chained:");
3401 fout(
"\n+Objective:");
3412 fout(
"\n+Objective key:");
3488 fout(
"\n+Arrival Delay:");
3494 fout(
"\n+No Messages:");
3505 fout(
"\n+Yes Messages:");
3582 bool tag = (i < Num_backgrounds - 1);
3597 for (j = 0; j < background->
suns.size(); j++)
3618 for (j = 0; j < background->
bitmaps.size(); j++)
3671 int CFred_mission_save::save_asteroid_fields()
3679 for (i=0; i<1 ; i++) {
3691 fout(
"\n+Field Type:");
3699 fout(
"\n+Debris Genre:");
3705 for (
int idx=0; idx<3; idx++) {
3710 fout(
"\n+Field Debris Type:");
3717 for (idx=0; idx<3; idx++) {
3722 fout(
"\n+Field Debris Type:");
3746 fout(
"\n+Inner Bound:");
3766 int CFred_mission_save::save_music()
3821 fout(
"\n$Debriefing Success Music:");
3829 fout(
"\n$Debriefing Average Music:");
3837 fout(
"\n$Debriefing Fail Music:");
3861 void CFred_mission_save::save_custom_bitmap(
const char *expected_string_640,
const char *expected_string_1024,
const char *string_field_640,
const char *string_field_1024,
int blank_lines)
3865 if ((*string_field_640 !=
'\0') || (*string_field_1024 !=
'\0'))
3867 while (blank_lines-- > 0)
3871 if (*string_field_640 !=
'\0')
3873 fout(
"\n%s %s", expected_string_640, string_field_640);
3876 if (*string_field_1024 !=
'\0')
3878 fout(
"\n%s %s", expected_string_1024, string_field_1024);
3892 fout(
"\n+AI Class:");
3907 fout(
"\n+Primary Banks:");
3930 fout(
"\n+Secondary Banks:");
3953 fout(
"\n+Sbank Ammo:");
3977 nprintf((
"Error",
"Can't open campaign file to save.\n"));
3995 fout(
"\n$end_multi_text");
4041 fout(
"\n+Briefing Cutscene:");
4059 fout(
"\n+Main Hall:");
4083 bool mission_loop =
false;
4084 bool mission_fork =
false;
4087 if (
Links[j].from == m) {
4092 fout(
"\n+Formula:");
4099 if (
Links[j].is_mission_loop) {
4100 mission_loop =
true;
4101 }
else if (
Links[j].is_mission_fork) {
4102 mission_fork =
true;
4114 if (mission_loop || mission_fork) {
4121 int num_mission_special = 0;
4123 if ( (
Links[j].from == m) && (
Links[j].is_mission_loop ||
Links[j].is_mission_fork) ) {
4125 num_mission_special++;
4127 if ((num_mission_special == 1) &&
Links[j].mission_branch_txt) {
4134 fout(
"\n$end_multi_text");
4137 if ((num_mission_special == 1) &&
Links[j].mission_branch_brief_anim) {
4144 fout(
"\n$end_multi_text");
4147 if ((num_mission_special == 1) &&
Links[j].mission_branch_brief_sound) {
4154 fout(
"\n$end_multi_text");
4157 if (num_mission_special == 1) {
4159 fout(
"\n+Formula:");
4169 if (mission_loop && num_mission_special > 1) {
4171 sprintf(buffer,
"Multiple branching loop error from mission %s\nEdit campaign for *at most* 1 loop from each mission.",
Campaign.
missions[m].
name);
4179 fout(
"\n\n+Level:");
4187 fout(
"\n+Position:");
4203 mprintf((
"Campaign saving error code #%d\n", err));
4212 void CFred_mission_save::save_campaign_sexp(
int node,
int link_num)
4218 if ( link_num != -1 ) {
4226 fout(
" (\n %s\n ( end-of-campaign )\n )\n", sexp_out.c_str());
4228 fout(
" ( %s( end-of-campaign ) )\n", sexp_out.c_str());
4235 if ( fso_ver_comment.empty() ) {
4236 fso_ver_comment.push_back(
SCP_string(ver) );
4242 int major, minor, build, revis;
4243 int in_major, in_minor, in_build, in_revis;
4250 if (elem1 == 3 && elem2 == 4 || elem1 == 4 && elem2 == 3) {
4252 }
else if ((elem1 >= 3 && elem2 >= 3) && (revis < 1000 || in_revis < 1000)) {
4256 if ( (elem1 == 3) && ((major > in_major) || ((major == in_major) && ((minor > in_minor) || ((minor == in_minor) && (build > in_build))))) ) {
4258 fso_ver_comment.push_back( before );
4259 }
else if ( (elem1 == 4) && ((major > in_major) || ((major == in_major) && ((minor > in_minor) || ((minor == in_minor) && ((build > in_build) || ((build == in_build) || (revis > in_revis))))))) ) {
4261 fso_ver_comment.push_back( before );
4263 fso_ver_comment.push_back(
SCP_string(ver) );
4269 if ( fso_ver_comment.empty() ) {
4274 fso_ver_comment.clear();
4278 fso_ver_comment.pop_back();
#define SF2_TOGGLE_SUBSYSTEM_SCANNING
#define SF2_WEAPONS_LOCKED
GLenum GLsizei GLenum format
matrix skybox_orientation
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
char Neb2_texture_name[MAX_FILENAME_LEN]
#define CAMPAIGN_TYPE_SINGLE
SCP_vector< starfield_list_entry > suns
model_subsystem * system_info
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
int cf_delete(const char *filename, int path_type)
Delete the specified file.
void generate_weaponry_usage_list(int *arr, int wing)
#define SEXP_VARIABLE_NETWORK
#define DEPART_AT_LOCATION
char Mission_callsigns[MAX_CALLSIGNS][NAME_LENGTH]
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
void sexp_variable_sort()
int Mission_music[NUM_SCORES]
#define OF_LASER_PROTECTED
#define MISSION_FLAG_FULLNEB
int Current_soundtrack_num
void fso_comment_pop(bool pop_all=false)
polymodel * model_get(int model_num)
weapon_info Weapon_info[MAX_WEAPON_TYPES]
float shield_get_strength(object *objp)
SCP_string recommendation_text
#define MAX_CAMPAIGN_TYPES
#define MISSION_FLAG_SCRAMBLE
float vm_vec_mag(const vec3d *v)
int scan_fso_version_string(const char *text, int *major, int *minor, int *build, int *revis)
#define SF2_NO_DISABLED_SELF_DESTRUCT
background_t Backgrounds[MAX_BACKGROUNDS]
#define SF2_NO_SUBSPACE_DRIVE
void cf_attrib(const char *name, int set, int clear, int type)
#define AI_GOAL_CHASE_WING
void save_tree(int clear=1)
int sexp_variable_block_count()
char * model_get_dock_name(int modelnum, int index)
campaign_editor * Campaign_tree_formp
#define AI_GOAL_WAYPOINTS
int save_campaign_file(char *pathname)
int replace_all(char *str, char *oldstr, char *newstr, uint max_len, int range)
#define DEFAULT_NMODEL_FLAGS
brief_stage stages[MAX_BRIEF_STAGES]
#define SF2_FORCE_SHIELDS_ON
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
int vm_matrix_same(matrix *m1, matrix *m2)
void stuff_special_arrival_anchor_name(char *buf, int iff_index, int restrict_to_players, int retail_format)
char Fred_alt_names[MAX_SHIPS][NAME_LENGTH+1]
SCP_vector< fiction_viewer_stage > Fiction_viewer_stages
int fhash_string_exists(const char *str)
ubyte debrief_persona_index
#define AI_GOAL_STAY_NEAR_SHIP
char * drop_white_space(char *str)
#define AI_GOAL_CHASE_ANY
struct vec3d::@225::@227 xyz
#define SF2_DONT_COLLIDE_INVIS
int num_block_variables()
char briefing_cutscene[NAME_LENGTH]
#define WF_NO_ARRIVAL_MUSIC
#define MISSION_TYPE_MULTI
#define SF2_FRIENDLY_STEALTH_INVIS
#define SF2_AFFECTED_BY_GRAVITY
ai_info Ai_info[MAX_AI_INFO]
int dock_find_dockpoint_used_by_object(object *objp, object *other_objp)
#define END_OF_LIST(head)
#define SF2_NAVPOINT_CARRY
#define OF_SPECIAL_WARPIN
#define SF2_SET_CLASS_DYNAMICALLY
char ani_filename[MAX_FILENAME_LEN]
#define AI_GOAL_DISARM_SHIP
#define SCORE_FICTION_VIEWER
sexp_variable Sexp_variables[MAX_SEXP_VARIABLES]
GLenum GLuint GLenum GLsizei const GLchar * message
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
#define MAX_MISSION_EVENT_LOG_FLAGS
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
#define CMISSION_FLAG_BASTION
cmd_brief Cmd_briefs[MAX_TVT_TEAMS]
ubyte ships_allowed[MAX_SHIP_CLASSES]
int get_index_sexp_variable_name(const char *text)
SOUNDTRACK_INFO Soundtracks[MAX_SOUNDTRACKS]
void convert_sexp_to_string(SCP_string &dest, int cur_node, int mode)
briefing Briefings[MAX_TVT_TEAMS]
#define MAX_SQUADRON_WINGS
GLenum GLuint GLenum GLsizei const GLchar * buf
#define MAX_REINFORCEMENT_MESSAGES
mission_goal Mission_goals[MAX_GOALS]
#define CONTRAIL_THRESHOLD_DEFAULT
SCP_list< waypoint_list > Waypoint_lists
#define SPECIAL_ARRIVAL_ANCHOR_FLAG
SCP_list< CJumpNode > Jump_nodes
int primary_banks[MAX_SHIP_PRIMARY_BANKS]
iff_info Iff_info[MAX_IFFS]
int Sorted[MAX_CAMPAIGN_MISSIONS]
#define SF2_SCRAMBLE_MESSAGES
char * Reinforcement_type_names[]
reinforcements Reinforcements[MAX_REINFORCEMENTS]
SCP_vector< waypoint > & get_waypoints()
int num_initial_asteroids
#define OF_TARGETABLE_AS_BOMB
campaign_tree_view * Campaign_tree_viewp
sound_env sound_environment
#define SCORE_DEBRIEF_FAIL
#define FS_CAMPAIGN_FILE_EXT
int object_is_docked(object *objp)
SCP_vector< MMessage > Messages
bool use_special_explosion
#define SCORE_DEBRIEF_AVERAGE
#define DEPART_AT_DOCK_BAY
char squad_filename[MAX_FILENAME_LEN]
char voice[MAX_FILENAME_LEN]
char * Departure_location_names[MAX_DEPARTURE_NAMES]
dock_instance * dock_list
bool dock_check_docked_one_on_one(object *objp)
SCP_vector< alt_class > s_alt_classes
struct matrix::@228::@230 vec
#define WF_NO_DEPARTURE_WARP
char created[DATE_TIME_LENGTH]
void vsprintf(SCP_string &dest, const char *format, va_list ap)
int optional_string_fred(char *pstr, char *end, char *end2)
void save_turret_info(ship_subsys *ptr, int ship)
ubyte weapons_allowed[MAX_WEAPON_TYPES]
int build_sexp_string(SCP_string &accumulator, int cur_node, int level, int mode)
char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH]
#define SF2_NO_DEATH_SCREAM
char * Nebula_filenames[NUM_NEBULAS]
ai_profile_t * ai_profile
#define MISSION_FLAG_RED_ALERT
#define strnicmp(s1, s2, n)
char Squadron_wing_names[MAX_SQUADRON_WINGS][NAME_LENGTH]
float max_hull_repair_val
#define MAX_STARTING_WINGS
ai_goal goals[MAX_AI_GOALS]
mission_event Mission_events[MAX_MISSION_EVENTS]
#define SF2_HIDE_SHIP_NAME
#define FRED_MISSION_VERSION
int Mission_callsign_count
int secondary_banks[MAX_SHIP_SECONDARY_BANKS]
ai_profile_t Ai_profiles[MAX_AI_PROFILES]
char * Mission_event_log_flags[MAX_MISSION_EVENT_LOG_FLAGS]
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
char * Goal_type_names[MAX_GOAL_TYPE_NAMES]
#define WF_NO_ARRIVAL_WARP
int weaponry_pool[MAX_WEAPON_TYPES]
#define SF_HIDDEN_FROM_SENSORS
bool generate_special_explosion_block_variables()
char squad_name[NAME_LENGTH]
int special_exp_deathroll_time
int save_reinforcements()
int fout_ext(char *pre_str, char *format,...)
int autosave_mission_file(char *pathname)
#define AI_GOAL_STAY_STILL
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
int cfputc(int c, CFILE *cfile)
int cf_rename(const char *old_name, const char *name, int dir_type)
GLsizei const GLchar ** string
char skybox_model[MAX_FILENAME_LEN]
char * Ai_behavior_names[MAX_AI_BEHAVIORS]
#define WF_NO_ARRIVAL_MESSAGE
#define AI_GOAL_EVADE_SHIP
cmd_brief_stage stage[CMD_BRIEF_STAGES_MAX]
#define ARRIVE_AT_LOCATION
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
#define SF_NO_DEPARTURE_WARP
char loading_screen[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
char profile_name[NAME_LENGTH]
char voice[MAX_FILENAME_LEN]
#define AI_GOAL_IGNORE_NEW
campaign_tree_wnd * Campaign_wnd
object Objects[MAX_OBJECTS]
#define AI_GOAL_PLAY_DEAD
#define stars_get_num_bitmaps()
int sexp_variable_count()
SCP_vector< mission_cutscene > cutscenes
#define AI_GOAL_WAYPOINTS_ONCE
#define SF_NO_ARRIVAL_WARP
bool mission_has_fiction()
char modified[DATE_TIME_LENGTH]
int ship_guardian_threshold
sexp_variable Block_variables[MAX_SEXP_VARIABLES]
#define AI_GOAL_GUARD_WING
menu_music Spooled_music[MAX_SPOOLED_MUSIC]
#define SF2_NO_BUILTIN_MESSAGES
void reset_parse(char *text)
#define OF_MISSILE_PROTECTED
GLuint const GLchar * name
char background[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
char background[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
#define SF_RED_ALERT_STORE_STATUS
char * cf_add_ext(const char *filename, const char *ext)
char command_sender[NAME_LENGTH]
#define SF2_PRIMARIES_LOCKED
int required_string_fred(char *pstr, char *end)
debrief_stage stages[MAX_DEBRIEF_STAGES]
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
int fout(char *format,...)
#define SF_KILL_BEFORE_MISSION
int cfputs(const char *str, CFILE *cfile)
#define AI_GOAL_KEEP_SAFE_DISTANCE
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]
#define AI_GOAL_DISABLE_SHIP
char Mission_parse_storm_name[NAME_LENGTH]
bool has_special_explosion_block_index(ship *shipp, int *index)
#define SF2_LOCK_ALL_TURRETS_INITIALLY
int save_mission_file(char *pathname)
#define SEXP_VARIABLE_CAMPAIGN_PERSISTENT
char subobj_name[MAX_NAME_LEN]
#define MOVIE_PRE_FICTION
int fout_version(char *format,...)
char substitute_briefing_music_name[NAME_LENGTH]
SCP_vector< EFXREVERBPROPERTIES > EFX_presets
SCP_vector< ship_info > Ship_info
#define OF_FLAK_PROTECTED
#define SF_NO_ARRIVAL_MUSIC
#define SF2_AFTERBURNER_LOCKED
int MessageBox(HWND h, const char *s1, const char *s2, int i)
void fhash_add_str(const char *str, int id)
char TVT_wing_names[MAX_TVT_WINGS][NAME_LENGTH]
SCP_vector< float > shield_quadrant
char wave_filename[MAX_FILENAME_LEN]
char mission_desc[MISSION_DESC_LENGTH]
int ship_get_default_orders_accepted(ship_info *sip)
#define MOVIE_PRE_DEBRIEF
#define SF2_ALWAYS_DEATH_SCREAM
debriefing Debriefings[MAX_TVT_TEAMS]
void parse_comments(int=1)
debris_genre_t debris_genre
team_data Team_data[MAX_TVT_TEAMS]
cmd_brief * Cur_cmd_brief
#define SCORE_DEBRIEF_SUCCESS
#define SEXP_VARIABLE_NUMBER
int Default_command_persona
#define SF_CARGO_REVEALED
char variable_name[TOKEN_LENGTH]
int event_music_get_spooled_music_index(const char *name)
void bypass_comment(const char *comment, const char *end=NULL)
SCP_vector< starfield_list_entry > bitmaps
int ship_index[MAX_SHIPS_PER_WING]
#define SF2_PRIMITIVE_SENSORS
asteroid_field Asteroid_field
SCP_vector< texture_replace > Fred_texture_replacements
char envmap_name[MAX_FILENAME_LEN]
char filename[MAX_FILENAME_LEN]
#define TYPE_ATTACK_PROTECT
char Fred_callsigns[MAX_SHIPS][NAME_LENGTH+1]
void fso_comment_push(char *ver)
#define AI_GOAL_DESTROY_SUBSYSTEM
#define ARRIVE_FROM_DOCK_BAY
#define SF2_NAVPOINT_NEEDSLINK
int cfclose(CFILE *cfile)
#define TYPE_REPAIR_REARM
support_ship_info support_ships
#define MOVIE_PRE_CMD_BRIEF
char filename[FILESPEC_LENGTH]
char label[MAX_LABEL_LEN]
#define SF2_SECONDARIES_LOCKED
char * Nebula_colors[NUM_NEBULA_COLORS]
char iff_name[NAME_LENGTH]
char * campaign_types[MAX_CAMPAIGN_TYPES]
matrix vmd_identity_matrix
int Mission_alt_type_count
float max_subsys_repair_val
void save_ai_goals(ai_goal *goalp, int ship)
char ship_name[NAME_LENGTH]
int special_exp_shockwave_speed
int required_string_either_fred(char *str1, char *str2)
cmission missions[MAX_CAMPAIGN_MISSIONS]
#define MAX_SEXP_VARIABLES
int path_indexes[MAX_SHIP_BAY_PATHS]
#define OF_BEAM_PROTECTED
char substitute_event_music_name[NAME_LENGTH]
#define SEXP_VARIABLE_PLAYER_PERSISTENT
campaign_tree_link Links[MAX_CAMPAIGN_TREE_LINKS]
#define MISSION_TYPE_MULTI_TEAMS
#define MOVIE_END_CAMPAIGN
char * Arrival_location_names[MAX_ARRIVAL_NAMES]