Author Topic: FS2_Open Events & SEXPs Log.  (Read 3165 times)

0 Members and 1 Guest are viewing this topic.

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
FS2_Open Events & SEXPs Log.
Okay, here's an idea I'd been toying with the idea of writing for a while. It's called the Event Log and basically it allows you to flag certain events and write to a log whether they are working or not working. Those of us who FRED will all have been in this situation, we have an event like this

Do something cool
When
-and
--Condition A
--Condition B
--Condition C

which isn't working when we think it should. But what is going wrong? Which of the conditions isn't working? Well this is the beauty of the event log. By adding some flags to your mission file (manually for now, but FRED will support them in the future) you can tell FS2_Open to keep an eye on this event and write out what is going on with it. The result is a log that looks something like this

Code: [Select]
09/25 18:41:20~   FS2_Open Mission Log - Opened


Mission Rebels & Renegades loaded.

09/25 18:41:48~   Hinton Run
is-destroyed-delay returned value CAN'T EVALUATE
distance returned value 1214
< returned value TRUE
and returned value FALSE
when returned value FALSE

As you can see the log shows me that the event Hinton Run isn't triggering because although the distance is close enough, the is-destroyed-delay SEXP can't evaluate (in this case because the ship in question hasn't jumped in yet). The events.log file is written to the data folder of the mod you are running, NOT the main Data folder! This cause it is basically code I altered from the multi.log and not the fs2_Open log. As an aside I made the code for multi.log generic. That means if other coders want to create a log for something, it shouldn't take more than a few minutes now.

Okay, so now you can see what to do with it, how do you set it up? Well first you'll need these builds. Then you'll need to alter the mission file for the event in question.

Code: [Select]
$Formula: ( when
   ( and
      ( is-destroyed-delay 0 "GVC Yaaru" )
      ( <
         ( distance "NTF Iceni" "NTSC Hinton" )
         2000
      )
   )
   ( add-goal
      "NTSC Hinton"
      ( ai-waypoints-once
         "Waypoint path 1"
         89
      )
   )
)
+Name: Hinton Run
+Repeat Count: 1
+Interval: 1
+Event Log Flags: ( "True" "False" )

The last line is the new one. At the moment only two flags are supported, corresponding to the event evaluating to true or false. I intend to add other flags that will be triggered on the 1st repetition of an event, or immediately after the first triggering. I suspect the handling of arguments and variables could also use improving.

Anyway, give me some feedback on which event properties you'd like me to expose in the log and I'll see what I can do. Remember that this only works at the event level, but I might see what I can do to have it also trigger on SEXP errors (trying to do things to ships which aren't there,  etc).
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline CooperHawkes

  • 28
  • NippleNeck (at least i got something to play with)
Re: FS2_Open Events & SEXPs Log.
great, this is a very good idea. it certainly beats my approach of having "show-subtitle-text"-sexps in every event/part of event and for every variable and stuff, to see if something gets triggered or not.
take me out to the black,
tell 'em i ain't coming back,
i don't care, i'm still free,
you can't take the sky from me

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: FS2_Open Events & SEXPs Log.
A flag for writing the contents of variables in the event when it triggers would be helpful.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: FS2_Open Events & SEXPs Log.
That shouldn't be too hard I hope. I'll give that and arguments a try tomorrow.
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline Crybertrance

  • 29
  • Conventional warheads only, no funny business
Re: FS2_Open Events & SEXPs Log.
Thanks man, really awesome work. :yes: I always hoped that something like this would come out, 'coz I've been in many situations where something should be triggering and it doesn't and I'm like "Y U NO TRIGGERING" (or something like that).
<21:08:30>   Hartzaden fires a slammer at Cybertrance
<21:09:13>   Crybertrance pops flares, but wonders how Hartzaden acquired aspect lock on a stealth fighter... :\
<21:11:58>   *** The_E joined #bp [email protected]
21:11:58   +++ ChanServ has given op to The_E
<21:12:58>   Hartzaden continues to paint crybertrance and feeding the info to a wing of gunships
<21:14:07>   Crybertrance sends emergency "IM GETING MY ASS KICKED HERE!!!!eleventy NEED HELPZZZZ" to 3rd fleet command
<21:14:50>   Hartzaden jamms the transmission.
<21:14:51>   The_E explodes the sun

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: FS2_Open Events & SEXPs Log.
Okay, I worked on this and I've now added some new features.

1) The values of variables and Arguments used in the event are now written to the log.
2) The log now supports 4 new options. The 1st time a repeating event triggers, the last time, and the same 2 for trigger count.
3) FRED is now supported via the events edit. Missions should save and load event log settings for events.
4) While I was using FRED I decided to add the extended size events list back again. I forgot to keep that in Diaspora builds so I'll just have to make sure I add it to trunk when I commit this feature.

At the moment I consider the feature complete. So if anyone has an idea what else I should add, now is the best time to suggest it, while it's all fresh in my mind. You can find the build here.

Code: [Select]
Index: code/fred2/eventeditor.cpp
===================================================================
--- code/fred2/eventeditor.cpp (revision 9227)
+++ code/fred2/eventeditor.cpp (working copy)
@@ -59,6 +59,12 @@
  modified = 0;
  select_sexp_node = -1;
  m_wave_id = -1;
+ m_log_true = 0;
+ m_log_false = 0;
+ m_log_1st_repeat = 0;
+ m_log_last_repeat = 0;
+ m_log_1st_trigger = 0;
+ m_log_last_trigger = 0;
 }
 
 void event_editor::DoDataExchange(CDataExchange* pDX)
@@ -80,6 +86,12 @@
  DDX_CBIndex(pDX, IDC_PERSONA_NAME, m_persona);
  DDX_CBString(pDX, IDC_WAVE_FILENAME, m_wave_filename);
  DDX_LBIndex(pDX, IDC_MESSAGE_LIST, m_cur_msg);
+ DDX_Check(pDX, IDC_MISSION_LOG_TRUE, m_log_true);
+ DDX_Check(pDX, IDC_MISSION_LOG_FALSE, m_log_false);
+ DDX_Check(pDX, IDC_MISSION_LOG_1ST_REPEAT, m_log_1st_repeat);
+ DDX_Check(pDX, IDC_MISSION_LOG_LAST_REPEAT, m_log_last_repeat);
+ DDX_Check(pDX, IDC_MISSION_LOG_1ST_TRIGGER, m_log_1st_trigger);
+ DDX_Check(pDX, IDC_MISSION_LOG_LAST_TRIGGER, m_log_last_trigger);
 
 
  // m_team == -1 maps to 2
@@ -419,6 +431,8 @@
  return 1;
  if (advanced_stricmp(m_events[i].objective_key_text, Mission_events[i].objective_key_text))
  return 1;
+ if (m_events[i].mission_log_flags != Mission_events[i].mission_log_flags)
+ return 1;
  }
 
  if (m_cur_msg < 0)
@@ -510,6 +524,7 @@
  Mission_events[i].formula = m_event_tree.save_tree(m_events[i].formula);
  Mission_events[i].objective_text = m_events[i].objective_text;
  Mission_events[i].objective_key_text = m_events[i].objective_key_text;
+ Mission_events[i].mission_log_flags = m_events[i].mission_log_flags;
  }
 
  // now update all sexp references
@@ -717,6 +732,7 @@
  m_events[num].objective_text = NULL;
  m_events[num].objective_key_text = NULL;
  m_events[num].team = -1;
+ m_events[num].mission_log_flags = 0;
  m_sig[num] = -1;
 
  m_event_tree.item_index = -1;
@@ -874,6 +890,22 @@
  }
  }
 
+ // handle event log flags
+ m_events[e].mission_log_flags = 0;
+ if (m_log_true)
+ m_events[e].mission_log_flags |= MLF_SEXP_TRUE;
+ if (m_log_false)
+ m_events[e].mission_log_flags |= MLF_SEXP_FALSE;
+ if (m_log_1st_repeat)
+ m_events[e].mission_log_flags |= MLF_FIRST_REPEAT_ONLY;
+ if (m_log_last_repeat)
+ m_events[e].mission_log_flags |= MLF_LAST_REPEAT_ONLY;
+ if (m_log_1st_trigger)
+ m_events[e].mission_log_flags |= MLF_FIRST_TRIGGER_ONLY;
+ if (m_log_last_trigger)
+ m_events[e].mission_log_flags |= MLF_LAST_TRIGGER_ONLY;
+
+
  // Search for item to update
  HTREEITEM h = m_event_tree.GetRootItem();
  while (h) {
@@ -995,6 +1027,38 @@
  GetDlgItem(IDC_EVENT_TEAM)->EnableWindow(TRUE);
  }
 
+ // handle event log flags
+ if (m_events[cur_event].mission_log_flags & MLF_SEXP_TRUE) {
+ m_log_true  = TRUE;
+ }else {
+ m_log_true  = FALSE;
+ }
+ if (m_events[cur_event].mission_log_flags & MLF_SEXP_FALSE) {
+ m_log_false  = TRUE;
+ }else {
+ m_log_false  = FALSE;
+ }
+ if (m_events[cur_event].mission_log_flags & MLF_FIRST_REPEAT_ONLY) {
+ m_log_1st_repeat  = TRUE;
+ }else {
+ m_log_1st_repeat  = FALSE;
+ }
+ if (m_events[cur_event].mission_log_flags & MLF_LAST_REPEAT_ONLY) {
+ m_log_last_repeat  = TRUE;
+ }else {
+ m_log_last_repeat  = FALSE;
+ }
+ if (m_events[cur_event].mission_log_flags & MLF_FIRST_TRIGGER_ONLY) {
+ m_log_1st_trigger  = TRUE;
+ }else {
+ m_log_1st_trigger  = FALSE;
+ }
+ if (m_events[cur_event].mission_log_flags & MLF_LAST_TRIGGER_ONLY) {
+ m_log_last_trigger  = TRUE;
+ }else {
+ m_log_last_trigger  = FALSE;
+ }
+
  UpdateData(FALSE);
 }
 
Index: code/fred2/eventeditor.h
===================================================================
--- code/fred2/eventeditor.h (revision 9227)
+++ code/fred2/eventeditor.h (working copy)
@@ -71,6 +71,12 @@
  int m_team;
  int m_message_team;
  int m_last_message_node;
+ int m_log_true;
+ int m_log_false;
+ int m_log_1st_repeat;
+ int m_log_last_repeat;
+ int m_log_1st_trigger;
+ int m_log_last_trigger;
  //}}AFX_DATA
 
  CBitmap m_play_bm;
Index: code/fred2/fred.rc
===================================================================
--- code/fred2/fred.rc (revision 9227)
+++ code/fred2/fred.rc (working copy)
@@ -116,7 +116,7 @@
 // Toolbar
 //
 
-IDR_MAINFRAME TOOLBAR 23, 23
+IDR_MAINFRAME TOOLBAR  23, 23
 BEGIN
     BUTTON      ID_SELECT
     BUTTON      ID_SELECT_AND_MOVE
@@ -152,7 +152,7 @@
 // Menu
 //
 
-IDR_MAINMENU MENU
+IDR_MAINMENU MENU
 BEGIN
     POPUP "&File"
     BEGIN
@@ -335,7 +335,7 @@
     END
 END
 
-IDR_MENU_SHIP_POPUP MENU
+IDR_MENU_SHIP_POPUP MENU
 BEGIN
     POPUP "Properties"
     BEGIN
@@ -345,7 +345,7 @@
     END
 END
 
-IDR_MENU_EDIT_POPUP MENU
+IDR_MENU_EDIT_POPUP MENU
 BEGIN
     POPUP "EDIT"
     BEGIN
@@ -370,7 +370,7 @@
     END
 END
 
-IDR_MENU_CAMPAIGN MENU
+IDR_MENU_CAMPAIGN MENU
 BEGIN
     POPUP "&File"
     BEGIN
@@ -392,7 +392,7 @@
     END
 END
 
-IDR_MENU_EDIT_SEXP_TREE MENU
+IDR_MENU_EDIT_SEXP_TREE MENU
 BEGIN
     POPUP "Edit sexp tree"
     BEGIN
@@ -442,7 +442,7 @@
     END
 END
 
-IDR_WING_EDIT_MENU MENU
+IDR_WING_EDIT_MENU MENU
 BEGIN
     POPUP "&Select Wing"
     BEGIN
@@ -450,7 +450,7 @@
     END
 END
 
-IDR_SHIP_EDIT_MENU MENU
+IDR_SHIP_EDIT_MENU MENU
 BEGIN
     POPUP "&Select Ship"
     BEGIN
@@ -458,7 +458,7 @@
     END
 END
 
-IDR_PLAYER_EDIT_MENU MENU
+IDR_PLAYER_EDIT_MENU MENU
 BEGIN
     POPUP "Select Team"
     BEGIN
@@ -471,7 +471,7 @@
     END
 END
 
-IDR_WAYPOINT_PATH_EDIT_MENU MENU
+IDR_WAYPOINT_PATH_EDIT_MENU MENU
 BEGIN
     POPUP "&Select Waypoint Path"
     BEGIN
@@ -479,7 +479,7 @@
     END
 END
 
-IDR_ASTEROID_FIELD_MENU MENU
+IDR_ASTEROID_FIELD_MENU MENU
 BEGIN
     POPUP "Select Field"
     BEGIN
@@ -487,7 +487,7 @@
     END
 END
 
-IDR_CPGN_VIEW_OFF MENU
+IDR_CPGN_VIEW_OFF MENU
 BEGIN
     POPUP "Blah"
     BEGIN
@@ -496,7 +496,7 @@
     END
 END
 
-IDR_CPGN_VIEW_ON MENU
+IDR_CPGN_VIEW_ON MENU
 BEGIN
     POPUP "Blah"
     BEGIN
@@ -512,7 +512,7 @@
 // Accelerator
 //
 
-IDR_MAINFRAME ACCELERATORS
+IDR_MAINFRAME ACCELERATORS
 BEGIN
     "1",            ID_SPEED1,              VIRTKEY, NOINVERT
     "1",            ID_GROUP1,              VIRTKEY, CONTROL, NOINVERT
@@ -603,7 +603,7 @@
     "Z",            ID_ZOOM_EXTENTS,        VIRTKEY, SHIFT, NOINVERT
 END
 
-IDR_ACC_CAMPAIGN ACCELERATORS
+IDR_ACC_CAMPAIGN ACCELERATORS
 BEGIN
     "H",            ID_ERROR_CHECKER,       VIRTKEY, ALT, NOINVERT
     "N",            ID_CPGN_FILE_NEW,       VIRTKEY, CONTROL, NOINVERT
@@ -618,7 +618,7 @@
 // Dialog
 //
 
-IDD_ABOUTBOX DIALOG 0, 0, 284, 89
+IDD_ABOUTBOX DIALOG  0, 0, 284, 89
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "About FRED2"
 FONT 8, "MS Sans Serif"
@@ -699,7 +699,7 @@
     GROUPBOX        "Message Properties",IDC_STATIC,7,184,184,60
 END
 
-IDD_SHIP_GOALS_EDITOR DIALOG 0, 0, 412, 221
+IDD_SHIP_GOALS_EDITOR DIALOG  0, 0, 412, 221
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Initial Orders"
 FONT 8, "MS Sans Serif"
@@ -784,7 +784,7 @@
     LTEXT           "Warning : Orders with a priority above 89 may be higher priority than those given by the player.",IDC_STATIC,60,183,307,11
 END
 
-IDD_MISSION_NOTES DIALOG 0, 0, 479, 349
+IDD_MISSION_NOTES DIALOG  0, 0, 479, 349
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Mission Specs"
 FONT 8, "MS Sans Serif"
@@ -880,7 +880,7 @@
     PUSHBUTTON      "Sound Environment",IDC_SOUND_ENVIRONMENT_BUTTON,158,244,140,15
 END
 
-IDD_PREFERENCES DIALOG 0, 0, 333, 81
+IDD_PREFERENCES DIALOG  0, 0, 333, 81
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Preferences"
 FONT 8, "MS Sans Serif"
@@ -1015,7 +1015,7 @@
     LTEXT           "Missile bank 4",IDC_STATIC,232,64,46,8
 END
 
-IDD_SHIP_MARKINGS DIALOG 0, 0, 252, 140
+IDD_SHIP_MARKINGS DIALOG  0, 0, 252, 140
 STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION
 CAPTION "Ship Markings"
 FONT 8, "MS Sans Serif"
@@ -1148,7 +1148,7 @@
     PUSHBUTTON      "Restrict Departure Paths",IDC_RESTRICT_DEPARTURE,160,223,121,14,0,WS_EX_STATICEDGE
 END
 
-IDD_OPERATOR_ARGUMENT_TYPES DIALOG 0, 0, 235, 50
+IDD_OPERATOR_ARGUMENT_TYPES DIALOG  0, 0, 235, 50
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Select Argument Types"
 FONT 8, "MS Sans Serif"
@@ -1197,7 +1197,7 @@
     LTEXT           "Set Amount From Variable",IDC_STATIC,179,234,93,10
 END
 
-IDD_ORIENT_EDITOR DIALOG 0, 0, 229, 119
+IDD_ORIENT_EDITOR DIALOG  0, 0, 229, 119
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Object Orientation Editor"
 FONT 8, "MS Sans Serif"
@@ -1234,7 +1234,7 @@
 CAPTION "Mission Event Edit"
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    CONTROL         "Tree1",IDC_EVENT_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,196,236,WS_EX_CLIENTEDGE
+    CONTROL         "Tree1",IDC_EVENT_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,196,343,WS_EX_CLIENTEDGE
     PUSHBUTTON      "New Event",IDC_BUTTON_NEW_EVENT,207,7,50,14,0,WS_EX_STATICEDGE,HIDC_BUTTON_NEW_EVENT
     PUSHBUTTON      "Insert Event",IDC_INSERT,207,24,50,14,0,WS_EX_STATICEDGE
     PUSHBUTTON      "Delete Event",IDC_DELETE,207,41,50,14,0,WS_EX_STATICEDGE
@@ -1245,9 +1245,9 @@
     CONTROL         "Chained",IDC_CHAINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,210,231,42,10
     LTEXT           "Chain Delay",IDC_STATIC,210,244,39,8
     EDITTEXT        IDC_CHAIN_DELAY,210,255,45,14,ES_AUTOHSCROLL | ES_NUMBER
-    EDITTEXT        IDC_OBJ_TEXT,86,246,117,14,ES_AUTOHSCROLL
-    EDITTEXT        IDC_OBJ_KEY_TEXT,86,262,117,14,ES_AUTOHSCROLL
-    EDITTEXT        IDC_HELP_BOX,7,298,423,126,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL,WS_EX_TRANSPARENT
+    EDITTEXT        IDC_OBJ_TEXT,86,354,117,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_OBJ_KEY_TEXT,86,370,117,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_HELP_BOX,211,298,219,126,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL,WS_EX_TRANSPARENT
     PUSHBUTTON      "New Msg",IDC_NEW_MSG,229,59,50,14,0,WS_EX_STATICEDGE
     PUSHBUTTON      "Delete Msg",IDC_DELETE_MSG,229,77,50,14,0,WS_EX_STATICEDGE
     LISTBOX         IDC_MESSAGE_LIST,285,17,145,74,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
@@ -1266,8 +1266,8 @@
     LTEXT           "Repeat Count",IDC_STATIC,210,98,45,8
     LTEXT           "Interval time",IDC_STATIC,210,154,45,8
     LTEXT           "Score",IDC_STATIC,210,186,45,8
-    LTEXT           "Directive text",IDC_STATIC,37,249,44,8
-    LTEXT           "Directive keypress text",IDC_STATIC,7,265,74,8
+    LTEXT           "Directive text",IDC_STATIC,37,356,44,8
+    LTEXT           "Directive keypress text",IDC_STATIC,7,372,74,8
     LTEXT           "Message Text",IDC_STATIC,261,114,48,8
     LTEXT           "Name",IDC_STATIC,261,97,20,8
     LTEXT           "Messages",IDC_STATIC,335,7,35,8
@@ -1277,9 +1277,16 @@
     GROUPBOX        "Message Properties",IDC_STATIC,261,183,169,80
     LTEXT           "Team",IDC_STATIC,279,245,20,8
     LTEXT           "(multiplayer TvT only)",IDC_STATIC,353,246,68,8
-    EDITTEXT        IDC_MINI_HELP_BOX,7,283,423,14,ES_MULTILINE | ES_READONLY,WS_EX_DLGMODALFRAME | WS_EX_TRANSPARENT
+    EDITTEXT        IDC_MINI_HELP_BOX,209,283,221,14,ES_MULTILINE | ES_READONLY,WS_EX_DLGMODALFRAME | WS_EX_TRANSPARENT
     EDITTEXT        IDC_TRIGGER_COUNT,210,137,45,14,ES_AUTOHSCROLL | ES_NUMBER
     LTEXT           "Trigger Count",IDC_STATIC,210,126,44,8
+    GROUPBOX        "Log These States",IDC_STATIC,7,389,201,35
+    CONTROL         "True",IDC_MISSION_LOG_TRUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,402,31,10
+    CONTROL         "False",IDC_MISSION_LOG_FALSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,414,33,10
+    CONTROL         "First Repeat",IDC_MISSION_LOG_1ST_REPEAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,402,54,10
+    CONTROL         "Last Repeat",IDC_MISSION_LOG_LAST_REPEAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,402,55,10
+    CONTROL         "First Trigger",IDC_MISSION_LOG_1ST_TRIGGER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,414,53,10
+    CONTROL         "Last Trigger",IDC_MISSION_LOG_LAST_TRIGGER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,414,53,10
 END
 
 IDD_BG_BITMAP DIALOGEX 0, 0, 431, 402
@@ -1410,7 +1417,7 @@
     LTEXT           "Delay After Arrival",IDC_STATIC,7,99,57,8
 END
 
-IDD_REINFORCEMENT_SELECT DIALOG 0, 0, 156, 132
+IDD_REINFORCEMENT_SELECT DIALOG  0, 0, 156, 132
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Select Reinforcement Unit"
 FONT 8, "MS Sans Serif"
@@ -1420,7 +1427,7 @@
     PUSHBUTTON      "Cancel",IDCANCEL,99,111,50,14
 END
 
-IDD_WAYPOINT_PATH_EDITOR DIALOG 0, 0, 145, 29
+IDD_WAYPOINT_PATH_EDITOR DIALOG  0, 0, 145, 29
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Waypoint Path/Jump Node Editor"
 MENU IDR_WAYPOINT_PATH_EDIT_MENU
@@ -1430,7 +1437,7 @@
     EDITTEXT        IDC_NAME,32,7,106,14,ES_AUTOHSCROLL
 END
 
-IDD_WING_CREATE DIALOG 0, 0, 119, 68
+IDD_WING_CREATE DIALOG  0, 0, 119, 68
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Create Wing"
 FONT 8, "MS Sans Serif"
@@ -1481,7 +1488,7 @@
     LTEXT           "Team Color Setting:",IDC_STATIC,16,308,66,8
 END
 
-IDD_ASTEROID_EDITOR DIALOG 0, 0, 376, 210
+IDD_ASTEROID_EDITOR DIALOG  0, 0, 376, 210
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Debris Field Editor"
 FONT 8, "MS Sans Serif"
@@ -1642,7 +1649,7 @@
     GROUPBOX        "Briefing Music",IDC_STATIC,7,132,150,44
 END
 
-IDD_IGNORE_ORDERS DIALOG 0, 0, 120, 217
+IDD_IGNORE_ORDERS DIALOG  0, 0, 120, 217
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Ignore Orders"
 FONT 8, "MS Sans Serif"
@@ -1692,7 +1699,7 @@
     COMBOBOX        IDC_FAILED_MISSION_TRACK,182,195,80,180,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 END
 
-IDD_ADJUST_GRID DIALOG 0, 0, 153, 94
+IDD_ADJUST_GRID DIALOG  0, 0, 153, 94
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Adjust Grid"
 FONT 8, "MS Sans Serif"
@@ -1714,7 +1721,7 @@
     LTEXT           "X Level",IDC_STATIC,69,50,25,8
 END
 
-IDD_SHIELD_SYS DIALOG 0, 0, 192, 106
+IDD_SHIELD_SYS DIALOG  0, 0, 192, 106
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Shield System Editor"
 FONT 8, "MS Sans Serif"
@@ -1731,7 +1738,7 @@
     PUSHBUTTON      "Cancel",IDCANCEL,134,86,50,14
 END
 
-IDD_INITIAL_SHIPS DIALOG 0, 0, 127, 210
+IDD_INITIAL_SHIPS DIALOG  0, 0, 127, 210
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Initial Ships Allowed"
 FONT 8, "MS Sans Serif"
@@ -1825,7 +1832,7 @@
     CONTROL         "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
 END
 
-IDD_ADD_VARIABLE DIALOG 0, 0, 422, 102
+IDD_ADD_VARIABLE DIALOG  0, 0, 422, 102
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Add Variable"
 FONT 8, "MS Sans Serif"
@@ -1845,7 +1852,7 @@
     CONTROL         "Network-Variable",IDC_TYPE_NETWORK_VARIABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,71,84,11
 END
 
-IDD_MODIFY_VARIABLE DIALOG 0, 0, 422, 102
+IDD_MODIFY_VARIABLE DIALOG  0, 0, 422, 102
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Modify Variable"
 FONT 8, "MS Sans Serif"
@@ -1867,7 +1874,7 @@
     CONTROL         "Network-Variable",IDC_TYPE_NETWORK_VARIABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,138,72,84,11
 END
 
-IDD_SPECIAL_DAMAGE DIALOG 0, 0, 234, 129
+IDD_SPECIAL_DAMAGE DIALOG  0, 0, 234, 129
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Special Explosion"
 FONT 8, "MS Sans Serif"
@@ -1893,7 +1900,7 @@
     LTEXT           "Duration (msecs):",IDC_STATIC,30,111,56,8
 END
 
-IDD_DUMP_STATS DIALOG 0, 0, 577, 375
+IDD_DUMP_STATS DIALOG  0, 0, 577, 375
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Mission Stats"
 FONT 8, "MS Sans Serif"
@@ -1903,7 +1910,7 @@
     EDITTEXT        IDC_STATS_TEXT,7,7,563,333,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN | ES_NUMBER | WS_VSCROLL
 END
 
-IDD_SHIP_TEXTURES DIALOG 0, 0, 296, 56
+IDD_SHIP_TEXTURES DIALOG  0, 0, 296, 56
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Ship Texture Replace"
 FONT 8, "MS Sans Serif"
@@ -1916,7 +1923,7 @@
     COMBOBOX        IDC_OLD_TEXTURE_LIST,7,16,137,85,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
 END
 
-IDD_SPECIAL_HITPOINTS DIALOG 0, 0, 234, 85
+IDD_SPECIAL_HITPOINTS DIALOG  0, 0, 234, 85
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Special Hitpoints"
 FONT 8, "MS Sans Serif"
@@ -1933,7 +1940,7 @@
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,106,10
 END
 
-IDD_SET_GLOBAL_SHIP_FLAGS DIALOG 0, 0, 114, 79
+IDD_SET_GLOBAL_SHIP_FLAGS DIALOG  0, 0, 114, 79
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Set Global Ship Flags"
 FONT 8, "MS Sans Serif"
@@ -1944,7 +1951,7 @@
     PUSHBUTTON      "Global Affected-By-Gravity",IDC_AFFECTED_BY_GRAVITY,7,58,100,14
 END
 
-IDD_VOICE_MANAGER DIALOG 0, 0, 407, 218
+IDD_VOICE_MANAGER DIALOG  0, 0, 407, 218
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Voice Acting Manager"
 FONT 8, "MS Sans Serif"
@@ -1989,7 +1996,7 @@
                     "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,166,159,100,19
 END
 
-IDD_BRIEFING_PERSONAS DIALOG 0, 0, 320, 201
+IDD_BRIEFING_PERSONAS DIALOG  0, 0, 320, 201
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Dialog"
 FONT 8, "MS Sans Serif"
@@ -1998,7 +2005,7 @@
     PUSHBUTTON      "Cancel",IDCANCEL,263,24,50,14
 END
 
-IDD_CUSTOM_WING_NAMES DIALOG 0, 0, 390, 54
+IDD_CUSTOM_WING_NAMES DIALOG  0, 0, 390, 54
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Custom Wing Names"
 FONT 8, "MS Sans Serif"
@@ -2020,7 +2027,7 @@
     PUSHBUTTON      "Cancel",IDCANCEL,333,24,50,14
 END
 
-IDD_RESTRICT_PATHS DIALOG 0, 0, 141, 87
+IDD_RESTRICT_PATHS DIALOG  0, 0, 141, 87
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Restrict Paths"
 FONT 8, "MS Sans Serif"
@@ -2031,7 +2038,7 @@
     LTEXT           "Restrict departure paths to the following:",IDC_RESTRICT_PATHS_LABEL,7,7,127,11
 END
 
-IDD_BACKGROUND_CHOOSER DIALOG 0, 0, 152, 45
+IDD_BACKGROUND_CHOOSER DIALOG  0, 0, 152, 45
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Choose a background"
 FONT 8, "MS Sans Serif"
@@ -2041,7 +2048,7 @@
     COMBOBOX        IDC_BACKGROUND,7,16,83,265,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
 END
 
-IDD_FICTION_VIEWER DIALOG 0, 0, 205, 66
+IDD_FICTION_VIEWER DIALOG  0, 0, 205, 66
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Fiction Viewer Editor"
 FONT 8, "MS Sans Serif"
@@ -2125,7 +2132,7 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+GUIDELINES DESIGNINFO
 BEGIN
     IDD_ABOUTBOX, DIALOG
     BEGIN
@@ -2678,19 +2685,19 @@
 // String Table
 //
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     IDR_MAINFRAME           "FRED2_OPEN 3.6.13 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     AFX_IDS_APP_TITLE       "FRED2"
     AFX_IDS_IDLEMESSAGE     "For Help, press F1"
     AFX_IDS_HELPMODEMESSAGE "Select an object on which to get Help"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_FILE_NEW             "Create a new campaign\nNew"
     ID_FILE_OPEN            "Open an existing campaign\nOpen"
@@ -2703,7 +2710,7 @@
     ID_FILE_PRINT_PREVIEW   "Display full pages\nPrint Preview"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_APP_ABOUT            "Display program information, version number and copyright\nAbout"
     ID_APP_EXIT             "Exit the campaign editor\nExit"
@@ -2714,7 +2721,7 @@
     ID_HELP                 "Display help for current task or command\nHelp"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_FILE_MRU_FILE1       "Open this document"
     ID_FILE_MRU_FILE2       "Open this document"
@@ -2734,18 +2741,18 @@
     ID_FILE_MRU_FILE16      "Open this document"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_NEXT_PANE            "Switch to the next window pane\nNext Pane"
     ID_PREV_PANE            "Switch back to the previous window pane\nPrevious Pane"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_WINDOW_SPLIT         "Split the active window into panes\nSplit"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_EDIT_CLEAR           "Erase the selection\nErase"
     ID_EDIT_CLEAR_ALL       "Erase everything\nErase All"
@@ -2760,13 +2767,13 @@
     ID_EDIT_REDO            "Redo the previously undone action\nRedo"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_VIEW_TOOLBAR         "Show or hide the toolbar\nToggle ToolBar"
     ID_VIEW_STATUS_BAR      "Show or hide the status bar\nToggle StatusBar"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     AFX_IDS_SCSIZE          "Change the window size"
     AFX_IDS_SCMOVE          "Change the window position"
@@ -2777,24 +2784,24 @@
     AFX_IDS_SCCLOSE         "Close the active window and prompts to save the documents"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     AFX_IDS_SCRESTORE       "Restore the window to normal size"
     AFX_IDS_SCTASKLIST      "Activate Task List"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     AFX_IDS_PREVIEW_CLOSE   "Close print preview mode\nCancel Preview"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_FILE_MISSIONNOTES    "Displays designer notes and mission properties\nMission Specs"
     ID_SELECT               "Select objects mode\nSelect (S)"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_VIEW_FIGHTERS        "Show/Hide Fighter objects"
     ID_VIEW_CAPITALSHIPS    "Show/Hide Capital Ship objects"
@@ -2812,7 +2819,7 @@
     ID_EDITORS_SHIPS        "Open ship editor dialog window to edit ship"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_EDITORS_GOALS        "Activates Mission Goal Editor\nMission Goal Editor"
     ID_EDITORS_WAYPOINTS    "Activates Waypoint Editor\nWaypoint Editor"
@@ -2823,7 +2830,7 @@
     ID_PROPERTIES_ONE       "This is Mike's prompt!"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_INDICATOR_EXT        "EXT"
     ID_INDICATOR_CAPS       "CAP"
@@ -2837,7 +2844,7 @@
     ID_INDICATOR_MODIFIED   "MODIFIED"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_MISCSTUFF_SHOWSHIPSASICONS "This is the (help?) prompt!"
     ID_EDIT_POPUP_SHOW_SHIP_MODELS
@@ -2846,7 +2853,7 @@
                             "Display ship names and ship types for visible ships"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_ADD_MISSION_TIME     "Evaluates to elapsed time into mission in seconds"
     ID_ADD_EQUALS           "Evaluates to true if numbers or objects are the same"
@@ -2861,7 +2868,7 @@
     ID_ADD_FALSE            "Evaluates to a boolean value of false"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_EDIT_POPUP_SHOW_COMPASS
                             "Display a 3 dimentional compass in the upper right corner of window"
@@ -2875,7 +2882,7 @@
     ID_ADD_MINUS            "Evaluates to difference between first subexpression and remaining subexpressions"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_SHOW_GRID_POSITIONS  "Show position on grid for all visible objects"
     ID_SHOW_COORDINATES     "Display the coordinates of objects/waypoints."
@@ -2890,7 +2897,7 @@
     ID_DISSOLVE_WING        "Remove selected ships from Wing(s)\nRemove from Wing"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_SELECT_AND_MOVE      "Select and Move objects\nSelect and Move (M)"
     ID_SELECT_AND_ROTATE    "Select and Rotate objects\nSelect and Rotate (R)"
@@ -2905,7 +2912,7 @@
     ID_FIND_DISTANCE        "Find Distance between two objects\nFind Distance"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_BUTTON32944          "Constrain to YZ axis\nYZ Constraint"
     ID_BUTTON32945          "Constrain to XY axis\nXY Constraint"
@@ -2920,27 +2927,27 @@
     ID_SHOW_HORIZON         "Show the horizon line"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_EDITORS_PLAYER       "Edit loadout information for all teams"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_REVERT               "Revert changes by reloading mission from last save\nRevert"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_ERROR_CHECKER        "Checks campaign for errors"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_LOOKAT_OBJ           "Rotate camera around selected object\nRotate around object (Ctrl+V)"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_EDITORS_ADJUST_GRID  "Adjust the orientation and level of the grid."
     ID_EDITORS_SHIELD_SYS   "Editor for availability of shield system for ships."
@@ -2948,7 +2955,7 @@
     ID_MARK_WING            "Mark entire wing selected object is a member of."
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_CONTROL_OBJ          "Movement keys control marked objects instead of camera."
     ID_CHECKOUT             "Checks out the mission from Source Safe"
@@ -2956,14 +2963,14 @@
     ID_AA_GRIDLINES         "Toggle Gridlines being drawn anti-aliased or not."
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_FORMAT_FS2_OPEN      "Save missions with SCP features"
     ID_FORMAT_FS2_RETAIL    "Save missions compatible with FS2 retail"
     ID_FORMAT_FS1           "Save missions compatible with FS1 retail"
 END
 
-STRINGTABLE
+STRINGTABLE
 BEGIN
     ID_FORMAT_FS1_RETAIL    "Save missions compatible with FS1 retail"
 END
@@ -3013,7 +3020,7 @@
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+GUIDELINES DESIGNINFO
 BEGIN
     IDD_ALT_SHIP_CLASS, DIALOG
     BEGIN
Index: code/fred2/missionsave.cpp
===================================================================
--- code/fred2/missionsave.cpp (revision 9227)
+++ code/fred2/missionsave.cpp (working copy)
@@ -3297,7 +3297,7 @@
 int CFred_mission_save::save_events()
 {
  SCP_string sexp_out;
- int i;
+ int i, j, add_flag;
 
  fred_parse_flag = 0;
  required_string_fred("#Events");
@@ -3400,6 +3400,24 @@
  fout(" %d", Mission_events[i].team);
  }
 
+ if (Format_fs2_open != FSO_FORMAT_RETAIL && Mission_events[i].mission_log_flags != 0 ) {
+ if ( optional_string_fred("+Event Log Flags: (", "$Formula:")){
+ parse_comments();
+ } else {
+ fso_comment_push(";;FSO 3.6.11;;");
+ fout_version("\n+Event Log Flags: (");
+ fso_comment_pop();
+ }
+
+ for (j = 0; j < MAX_MISSION_EVENT_LOG_FLAGS ; j++) {
+ add_flag = 1 << j;
+ if (Mission_events[i].mission_log_flags & add_flag ) {
+ fout(" \"%s\"", Mission_event_log_flags[j]);
+ }
+ }
+ fout(" )");
+ }
+
  fso_comment_pop();
  }
 
Index: code/fred2/resource.h
===================================================================
--- code/fred2/resource.h (revision 9227)
+++ code/fred2/resource.h (working copy)
@@ -1162,6 +1162,12 @@
 #define IDC_NEB_NEAR_MULTIPLIER         1632
 #define IDC_EDIT6                       1633
 #define IDC_NEB_FAR_MULTIPLIER          1634
+#define IDC_MISSION_LOG_TRUE         1635
+#define IDC_MISSION_LOG_FALSE           1636
+#define IDC_MISSION_LOG_1ST_REPEAT      1637
+#define IDC_MISSION_LOG_LAST_REPEAT     1638
+#define IDC_MISSION_LOG_1ST_TRIGGER     1639
+#define IDC_MISSION_LOG_LAST_TRIGGER    1640
 #define ID_FILE_MISSIONNOTES            32771
 #define ID_DUPLICATE                    32774
 #define ID_VIEW_ROTATE                  32775
@@ -1455,7 +1461,7 @@
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        320
 #define _APS_NEXT_COMMAND_VALUE         33098
-#define _APS_NEXT_CONTROL_VALUE         1635
+#define _APS_NEXT_CONTROL_VALUE         1641
 #define _APS_NEXT_SYMED_VALUE           105
 #endif
 #endif
Index: code/freespace2/freespace.cpp
===================================================================
--- code/freespace2/freespace.cpp (revision 9227)
+++ code/freespace2/freespace.cpp (working copy)
@@ -122,6 +122,7 @@
 #include "osapi/osapi.h"
 #include "osapi/osregistry.h"
 #include "parse/encrypt.h"
+#include "parse/generic_log.h"
 #include "parse/lua.h"
 #include "parse/parselo.h"
 #include "parse/scripting.h"
@@ -1947,6 +1948,10 @@
 
  multi_init();
 
+ // start up the mission logfile
+ logfile_init(LOGFILE_EVENT_LOG);
+ log_string(LOGFILE_EVENT_LOG,"FS2_Open Mission Log - Opened \n\n", 1);
+
  // standalone's don't use the joystick and it seems to sometimes cause them to not get shutdown properly
  if(!Is_standalone){
  joy_init();
@@ -7322,6 +7327,7 @@
  mission_parse_close(); // clear out any extra memory that may be in use by mission parsing
  multi_voice_close(); // close down multiplayer voice (including freeing buffers, etc)
  multi_log_close();
+ logfile_close(LOGFILE_EVENT_LOG); // close down the mission log
 #ifdef MULTI_USE_LAG
  multi_lag_close();
 #endif
Index: code/mission/missiongoals.cpp
===================================================================
--- code/mission/missiongoals.cpp (revision 9227)
+++ code/mission/missiongoals.cpp (working copy)
@@ -170,7 +170,8 @@
 
 int Num_mission_events;
 int Num_goals = 0; // number of goals for this mission
-int Event_index;  // used by sexp code to tell what event it came from
+int Event_index = -1;  // used by sexp code to tell what event it came from
+bool Log_event = false;
 int Mission_goal_timestamp;
 
 mission_event Mission_events[MAX_MISSION_EVENTS];
@@ -377,6 +378,7 @@
  Mission_events[i].satisfied_time = 0;
  Mission_events[i].born_on_date = 0;
  Mission_events[i].team = -1;
+ Mission_events[i].mission_log_flags = 0;
  }
 
  Mission_goal_timestamp = timestamp(GOAL_TIMESTAMP);
@@ -884,6 +886,7 @@
 
  int result, sindex;
  bool bump_timestamp = false;
+ Log_event = false;
 
  Directive_count = 0;
  Event_index = event;
@@ -916,6 +919,9 @@
 
  if (sindex >= 0) {
  Sexp_useful_number = 1;
+ if (Mission_events[event].mission_log_flags != 0) {
+ Log_event = true;
+ }
  result = eval_sexp(sindex);
 
  // if the directive count is a special value, deal with that first.  Mark the event as a special
@@ -939,7 +945,11 @@
  }
  }
 
- Event_index = 0;
+ if (Mission_events[event].mission_log_flags != 0) {
+ maybe_write_to_event_log(result);
+ }
+
+ Event_index = -1;
  Mission_events[event].result = result;
 
  // if the sexpression is known false, then no need to evaluate anymore
Index: code/mission/missiongoals.h
===================================================================
--- code/mission/missiongoals.h (revision 9227)
+++ code/mission/missiongoals.h (working copy)
@@ -83,6 +83,17 @@
 #define MEF_DIRECTIVE_TEMP_TRUE (1 << 2) // this directive is temporarily true.
 #define MEF_USING_TRIGGER_COUNT (1 << 3) // Karajorma - use trigger count as well as repeat count to determine how many repeats this event has
 
+#define MAX_MISSION_EVENT_LOG_FLAGS 6 // this must be added if a mission log flag is added below
+
+#define MLF_SEXP_TRUE (1 << 0)
+#define MLF_SEXP_FALSE (1 << 1)
+#define MLF_FIRST_REPEAT_ONLY (1 << 2)
+#define MLF_LAST_REPEAT_ONLY (1 << 3)
+#define MLF_FIRST_TRIGGER_ONLY (1 << 4)
+#define MLF_LAST_TRIGGER_ONLY (1 << 5)
+
+#define MLF_ALL_REPETITION_FLAGS (MLF_FIRST_REPEAT_ONLY | MLF_LAST_REPEAT_ONLY | MLF_FIRST_TRIGGER_ONLY | MLF_LAST_TRIGGER_ONLY)
+
 typedef struct mission_event {
  char name[NAME_LENGTH]; // used for storing status of events in player file
  int formula; // index into sexpression array for this formula
@@ -100,12 +111,14 @@
  int satisfied_time; // this is used to temporarily mark the directive as satisfied when the event isn't (e.g. for a destroyed wave when there are more waves later)
  int born_on_date; // timestamp at which event was born
  int team; // for multiplayer games
+ int mission_log_flags; // flags that are used to determing which events are written to the log
 } mission_event;
 
 extern int Num_mission_events;
 extern mission_event Mission_events[MAX_MISSION_EVENTS];
 extern int Mission_goal_timestamp;
 extern int Event_index;  // used by sexp code to tell what event it came from
+extern bool Log_event;
 
 // prototypes
 void mission_init_goals( void );
Index: code/mission/missionparse.cpp
===================================================================
--- code/mission/missionparse.cpp (revision 9227)
+++ code/mission/missionparse.cpp (working copy)
@@ -22,6 +22,7 @@
 
 
 #include "mission/missionparse.h"
+#include "parse/generic_log.h"
 #include "parse/parselo.h"
 #include "mission/missiongoals.h"
 #include "mission/missionlog.h"
@@ -311,7 +312,16 @@
  "weapons-locked",
 };
 
+char *Mission_event_log_flags[MAX_MISSION_EVENT_LOG_FLAGS] = {
+ "true",
+ "false",
+ "first repeat",
+ "last repeat",
+ "first trigger",
+ "last trigger",
+};
 
+
 //XSTR:ON
 
 int Num_reinforcement_type_names = sizeof(Reinforcement_type_names) / sizeof(char *);
@@ -4652,6 +4662,43 @@
  }
  }
 
+ if( optional_string("+Event Log Flags:") ) {
+ SCP_vector<SCP_string> buffer;
+
+ stuff_string_list(buffer);
+ for (int i = 0; i < (int)buffer.size(); i++) {
+ int add_flag = 1;
+
+ for (int j = 0; j < MAX_MISSION_EVENT_LOG_FLAGS; j++) {
+ if (!stricmp(buffer[i].c_str(), Mission_event_log_flags[j])) {
+ // bitshift add_flag so that it equals the index of the flag in Mission_event_log_flags[]
+ add_flag = add_flag << j;
+ event->mission_log_flags |= add_flag;
+ }
+ }
+ /*
+ if (!strcmp(buffer[i].c_str(), "True")) {
+ event->mission_log_flags |= MLF_SEXP_TRUE;
+ }
+ else if (!strcmp(buffer[i].c_str(), "False")) {
+ event->mission_log_flags |= MLF_SEXP_FALSE;
+ }
+ else if (!strcmp(buffer[i].c_str(), "First Repeat")) {
+ event->mission_log_flags |= MLF_SEXP_FALSE;
+ }
+ else if (!strcmp(buffer[i].c_str(), "Last Repeat")) {
+ event->mission_log_flags |= MLF_SEXP_FALSE;
+ }
+ else if (!strcmp(buffer[i].c_str(), "First Trigger")) {
+ event->mission_log_flags |= MLF_SEXP_FALSE;
+ }
+ else if (!strcmp(buffer[i].c_str(), "Last Trigger")) {
+ event->mission_log_flags |= MLF_SEXP_FALSE;
+ }
+ */
+ }
+ }
+
  event->timestamp = timestamp(-1);
 
  // sanity check on the repeat count variable
@@ -5394,6 +5441,8 @@
  popup(PF_TITLE_BIG | PF_TITLE_RED | PF_NO_NETWORKING, 1, POPUP_OK, text);
  }
 
+ log_printf(LOGFILE_EVENT_LOG, "Mission %s loaded.\n", pm->name);
+
  // success
  return 0;
 }
Index: code/mission/missionparse.h
===================================================================
--- code/mission/missionparse.h (revision 9227)
+++ code/mission/missionparse.h (working copy)
@@ -281,6 +281,7 @@
 extern char *Parse_object_flags[];
 extern char *Parse_object_flags_2[];
 extern char *Icon_names[];
+extern char *Mission_event_log_flags[];
 
 extern char *Cargo_names[MAX_CARGO];
 extern char Cargo_names_buf[MAX_CARGO][NAME_LENGTH];
Index: code/network/multi_log.cpp
===================================================================
--- code/network/multi_log.cpp (revision 9227)
+++ code/network/multi_log.cpp (working copy)
@@ -12,6 +12,7 @@
 
 #include <stdarg.h>
 #include "network/multi_log.h"
+#include "parse/generic_log.h"
 #include "cfile/cfile.h"
 
 
@@ -23,18 +24,9 @@
 // max length for a line of the logfile
 #define MAX_LOGFILE_LINE_LEN 256
 
-// name of the multiplayer logfile
-#define MULTI_LOGFILE_NAME "multi.log"
-
-// echo all ml_printf's to the debug window
-//#define MULTI_LOGFILE_ECHO_TO_DEBUG
-
 // how often we'll write an update to the logfile (in seconds)
 #define MULTI_LOGFILE_UPDATE_TIME 2520 // every 42 minutes
 
-// outfile itself
-CFILE *Multi_log_out = NULL;
-
 // time when the logfile was opened
 int Multi_log_open_systime = -1;
 
@@ -54,7 +46,7 @@
  // header message
  timer = time(NULL);
  strftime(str, 1024, "FreeSpace Multi Log - Opened %a, %b %d, %Y  at %I:%M%p\n----\n----\n----\n\n", localtime(&timer));
- ml_string(str, 0);
+ log_string(LOGFILE_MULTI_LOG, str, 0);
 }
 
 // write the standard shutdown trailer
@@ -66,7 +58,7 @@
  // header message
  timer = time(NULL);
  strftime(str, 1024, "\n\n----\n----\n----\nFreeSpace Multi Log - Closing on %a, %b %d, %Y  at %I:%M%p", localtime(&timer));
- ml_string(str, 0);
+ log_string(LOGFILE_MULTI_LOG, str, 0);
 }
 
 // write out some info about stuff
@@ -87,41 +79,25 @@
 // initialize the multi logfile
 void multi_log_init()
 {
- // attempt to open the file
- Multi_log_out = cfopen(MULTI_LOGFILE_NAME, "wt", CFILE_NORMAL, CF_TYPE_DATA);
-
- // if we successfully opened the file, write the header
- if(Multi_log_out != NULL){
+ if (logfile_init(LOGFILE_MULTI_LOG)) {
  multi_log_write_header();
 
  // initialize our timer info
  Multi_log_open_systime = (int) time(NULL);
  Multi_log_update_systime = Multi_log_open_systime;
- } else {
- nprintf(("Network","Error opening %s for writing!!\n",MULTI_LOGFILE_NAME));
- }
+ }
 }
 
 // close down the multi logfile
 void multi_log_close()
 {
- // if we have a valid file, write a trailer and close
- if(Multi_log_out != NULL){
- multi_log_write_trailer();
-
- cfclose(Multi_log_out);
- Multi_log_out = NULL;
- }
+ multi_log_write_trailer();
+ logfile_close(LOGFILE_MULTI_LOG);
 }
 
 // give some processing time to the logfile system so it can check up on stuff
 void multi_log_process()
 {
- // if we don't have a valid logfile, do nothing
- if(Multi_log_out == NULL){
- return;
- }
-
  // check to see if we've been active a long enough time, and
  if(time(NULL) - Multi_log_update_systime > MULTI_LOGFILE_UPDATE_TIME){
  // write the update
@@ -136,19 +112,14 @@
 {
  char tmp[MAX_LOGFILE_LINE_LEN*4];
  va_list args;
-
- // if we don't have a valid logfile do nothing
- if(Multi_log_out == NULL){
- return;
- }
 
  // format the text
  va_start(args, format);
  vsprintf(tmp, format, args);
  va_end(args);
 
- // log the string
- ml_string(tmp);
+ // log the string including the time
+ log_string(LOGFILE_MULTI_LOG, tmp, 1);
 }
 
 // string print function
@@ -158,11 +129,6 @@
  char time_str[128];
  time_t timer;
 
- // if we don't have a valid logfile do nothing
- if(Multi_log_out == NULL){
- return;
- }
-
  // if the passed string is NULL, do nothing
  if(string == NULL){
  return;
@@ -181,8 +147,7 @@
  strcat_s(tmp, "\n");
 
  // now print it to the logfile if necessary
- cfputs(tmp, Multi_log_out);
- cflush(Multi_log_out);
+ log_string(LOGFILE_MULTI_LOG, tmp, 0);
 
  // add to standalone UI too
  extern int Is_standalone;
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp (revision 9227)
+++ code/parse/sexp.cpp (working copy)
@@ -104,6 +104,7 @@
 #include "object/objectshield.h"
 #include "network/multi_sexp.h"
 #include "io/keycontrol.h"
+#include "parse/generic_log.h"
 
 
 
@@ -891,6 +892,11 @@
 // hud-display-gauge magic values
 #define SEXP_HUD_GAUGE_WARPOUT "warpout"
 
+// event log stuff
+SCP_vector<SCP_string> event_log_buffer;
+SCP_vector<SCP_string> event_log_variable_buffer;
+SCP_vector<SCP_string> event_log_argument_buffer;
+
 // Goober5000 - arg_item class stuff, borrowed from sexp_list_item class stuff -------------
 void arg_item::add_data(char *str)
 {
@@ -2669,7 +2675,7 @@
  }
  }
 
- if (i == Builtin_moods.size()) {
+ if (i == (int)Builtin_moods.size()) {
  return SEXP_CHECK_INVALID_MISSION_MOOD;
  }
 
@@ -8109,7 +8115,7 @@
  ptr = Sexp_applicable_argument_list.get_next();
 
  while (ptr != NULL)
- {
+ {
  // acquire argument to be used
  Sexp_replacement_arguments.push_back(ptr->text);
  actions = all_actions;
@@ -8173,6 +8179,7 @@
 {
  int cond, val, actions;
  Assert( n >= 0 );
+ arg_item *ptr;
 
  // get the parts of the sexp and evaluate the conditional
  if (is_blank_argument_op(when_op_num))
@@ -8255,6 +8262,15 @@
 
  if (is_blank_argument_op(when_op_num))
  {
+ if (Log_event) {
+ ptr = Sexp_applicable_argument_list.get_next();
+ while(ptr != NULL) {
+ // See if we have an argument.
+ event_log_argument_buffer.push_back(ptr->text);
+ ptr = ptr->get_next();
+ }
+ }
+
  // clean up any special sexp stuff
  Sexp_applicable_argument_list.clear_nesting_level();
  Sexp_current_argument_nesting_level--;
@@ -20711,7 +20727,176 @@
  return ((result == SEXP_TRUE) || (result == SEXP_KNOWN_TRUE));
 }
 
+
 /**
+*
+*/
+int generate_event_log_flags_mask(int result)
+{
+ int matches = 0;
+ mission_event *current_event = &Mission_events[Event_index];
+
+ switch (result) {
+ case SEXP_TRUE:
+ matches |= MLF_SEXP_TRUE;
+ break;
+
+ case SEXP_FALSE:
+ matches |= MLF_SEXP_FALSE;
+ break;
+
+ default:
+ Int3(); // just for now. This shouldn't hit trunk!
+ }
+
+ if (( result == SEXP_TRUE ) || (result == SEXP_KNOWN_TRUE)) {
+ // now deal with the flags depending on repeat and trigger counts
+ switch (current_event->mission_log_flags) {
+ case MLF_FIRST_REPEAT_ONLY:
+ if (current_event->repeat_count > 1) {
+ matches |= MLF_FIRST_REPEAT_ONLY;
+ }
+ break;
+
+ case MLF_LAST_REPEAT_ONLY:
+ if (current_event->repeat_count == 1) {
+ matches |= MLF_LAST_REPEAT_ONLY;
+ }
+ break;
+
+ case MLF_FIRST_TRIGGER_ONLY:
+ if (current_event->trigger_count > 1) {
+ matches |= MLF_FIRST_TRIGGER_ONLY;
+ }
+ break;
+
+ case MLF_LAST_TRIGGER_ONLY:
+ if ((current_event->trigger_count == 1) && (current_event->flags & MEF_USING_TRIGGER_COUNT)) {
+ matches |= MLF_LAST_TRIGGER_ONLY;
+ }
+ break;
+ }
+ }
+
+ return matches;
+}
+
+
+/**
+* Checks the mission logs flags for this event and writes to the log if this has been asked for
+*/
+void maybe_write_to_event_log(int result)
+{
+ char buffer [TOKEN_LENGTH*2];
+
+ int mask = generate_event_log_flags_mask(result);
+ if (!(mask &=  Mission_events[Event_index].mission_log_flags)) {
+ event_log_buffer.clear();
+ return;
+ }
+
+ // remove some of the flags
+ if (mask & (MLF_FIRST_REPEAT_ONLY | MLF_FIRST_TRIGGER_ONLY)) {
+ Mission_events[Event_index].mission_log_flags &= ~(MLF_FIRST_REPEAT_ONLY | MLF_FIRST_TRIGGER_ONLY) ;
+ }
+
+ if (event_log_buffer.empty()) {
+ return;
+ }
+
+ sprintf(buffer, "%s at mission time %d seconds (%d milliseconds)", Mission_events[Event_index].name, f2i(Missiontime), f2i((longlong)Missiontime * 1000));
+
+ log_string(LOGFILE_EVENT_LOG, buffer);
+ while (!event_log_buffer.empty()) {
+ log_string(LOGFILE_EVENT_LOG, event_log_buffer.back().c_str());
+ event_log_buffer.pop_back();
+ }
+ log_string(LOGFILE_EVENT_LOG, "");
+}
+
+/**
+* Returns the constant used as a SEXP's result as text for printing to the event log
+*/
+char *sexp_get_result_as_text(int result)
+{
+ switch (result) {
+ case SEXP_TRUE:
+ return "TRUE";
+
+ case SEXP_FALSE:
+ return "FALSE";
+
+ case SEXP_KNOWN_FALSE:
+ return "ALWAYS FALSE";
+
+ case SEXP_KNOWN_TRUE:
+ return "ALWAYS TRUE";
+
+ case SEXP_UNKNOWN:
+ return "UNKNOWN";
+
+ case SEXP_NAN:
+ return "NOT A NUMBER";
+
+ case SEXP_NAN_FOREVER:
+ return "CAN NEVER BE A NUMBER";
+
+ case SEXP_CANT_EVAL:
+ return "CAN'T EVALUATE";
+
+ default:
+ return NULL;
+ }
+}
+
+/**
+* Checks the mission logs flags for this event and writes to the log if this has been asked for
+*/
+void add_to_event_log_buffer(int op_num, int result)
+{
+ char buffer[TOKEN_LENGTH];
+ SCP_string tmp;
+ tmp.append(Operators[op_num].text);
+ tmp.append(" returned ");
+
+ if (sexp_get_result_as_text(result) == NULL) {
+ sprintf(buffer, "%d", result);
+ tmp.append(buffer);
+ }
+ else {
+ tmp.append(sexp_get_result_as_text(result));
+ }
+
+ if (True_loop_argument_sexps && !Sexp_replacement_arguments.empty()) {
+ tmp.append(" for argument ");
+ tmp.append(Sexp_replacement_arguments.back());
+ }
+
+ if (!event_log_argument_buffer.empty()) {
+ tmp.append(" for the following arguments");
+ while (!event_log_argument_buffer.empty()) {
+ tmp.append("\n");
+ tmp.append(event_log_argument_buffer.back().c_str());
+ event_log_argument_buffer.pop_back();
+ }
+ }
+
+ if (!event_log_variable_buffer.empty()) {
+ tmp.append("\nVariables:\n");
+ while (!event_log_variable_buffer.empty()) {
+ tmp.append(event_log_variable_buffer.back().c_str());
+ event_log_variable_buffer.pop_back();
+ tmp.append("[");
+ tmp.append(event_log_variable_buffer.back().c_str());
+ event_log_variable_buffer.pop_back();
+ tmp.append("]");
+ }
+ }
+
+ event_log_buffer.push_back(tmp);
+}
+
+/**
  * High-level sexpression evaluator
  */
 int eval_sexp(int cur_node, int referenced_node)
@@ -22811,6 +22996,11 @@
  Error(LOCATION, "Looking for SEXP operator, found '%s'.\n", CTEXT(cur_node));
  break;
  }
+
+ if (Log_event) {
+ add_to_event_log_buffer(get_operator_index(cur_node), sexp_val);
+ }
+
  Assert(!Current_sexp_operator.empty());
  Current_sexp_operator.pop_back();
 
@@ -26331,6 +26521,11 @@
  Assert( !(Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NOT_USED) );
  Assert(Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_SET);
 
+ if (Log_event) {
+ event_log_variable_buffer.push_back(Sexp_variables[sexp_variable_index].text);
+ event_log_variable_buffer.push_back(Sexp_variables[sexp_variable_index].variable_name);
+ }
+
  return Sexp_variables[sexp_variable_index].text;
  }
  else
Index: code/parse/sexp.h
===================================================================
--- code/parse/sexp.h (revision 9227)
+++ code/parse/sexp.h (working copy)
@@ -1196,4 +1196,6 @@
 //Needed for scripting access to ship effects
 int get_effect_from_name(char* name);
 
+void maybe_write_to_event_log(int result);
+
 #endif
Index: projects/MSVC_2008/code.vcproj
===================================================================
--- projects/MSVC_2008/code.vcproj (revision 9227)
+++ projects/MSVC_2008/code.vcproj (working copy)
@@ -2437,6 +2437,14 @@
  >
  </File>
  <File
+ RelativePath="..\..\code\parse\generic_log.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\code\parse\generic_log.h"
+ >
+ </File>
+ <File
  RelativePath="..\..\code\parse\lua.cpp"
  >
  </File>



[attachment removed and sold on the black market]
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: FS2_Open Events & SEXPs Log.
This is so awesome. How did I ever FRED without this?
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.