Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: karajorma on September 08, 2012, 12:31:07 pm

Title: Builtin Messages Overhaul
Post by: karajorma on September 08, 2012, 12:31:07 pm
(http://img826.imageshack.us/img826/4610/lizardisacylon.jpg)

Since I've apparently been given a very light workload for the next two weeks, I've decided that I'm going to get back into SCP programming with some improvements to the way Builtin Messages work. The image above shows one of the major problems with the system.

For this reason, I plan to upgrade the system to allow messages.tbl to have a +Mood entry for any message. Anything without a mood is considered okay to play at any time. Anything with a mood will only play if the pilot or mission has a matching mood. So given a table like this

Code: [Select]
$Name: Praise Self
$Message: XSTR("Damn I'm good!", 968)
+Persona: GenericPilot1
+Wave Name: Pil_gen1_praisehimself.ogg
+Mood:            Boasting


$Name: Praise Self
$Message: XSTR("Please, I can do that any day of the week.", 974)
+Persona: GenericPilot1
+Wave Name: Pil_gen3_praisehimself.ogg
+Mood:            Arrogant


$Name: Praise Self
$Message: XSTR("Got one! Take that you metal bastard.", 975)
+Persona: GenericPilot1
+Wave Name: Pil_gen4_praisehimself.ogg
+Mood:            Vengeful


$Name: Praise Self
$Message: XSTR("Yeah! Scratch one bogey!", 984)
+Persona: GenericPilot1
+Wave Name: Pil_gen5_praisehimself.ogg


$Name: Praise Self
$Message: XSTR("Score another one for me.", 985)
+Persona: GenericPilot1
+Wave Name: Pil_gen6_praisehimself.ogg

At the start of the mission, only the last two generic (no mood) messages will play. The I use the new SEXP I'll add

Set-Builtin-Pilot-Mood
-Red 2
-Boasting

and the first message will play instead. Then the players battlestar gets blown up. I don't just want Red 2 to react so I use a different SEXP

Set-Builtin-Mission-Mood
-Vengeful

And now everyone will start cursing the Cylons when they kill them.

Anyway, that's the plan. What I want to know is if there are any ways I could make that better, or if there is anything else I should do to the builtin messages system while I'm in there.
Title: Re: Builtin Messages Overhaul
Post by: Droid803 on September 08, 2012, 01:29:47 pm
While you're messing with builtin messages, could you also get rid of the hardcoded terran command "hostiles arrived" message that appears when you set the command sender to a capship?
It's hardcoded for sure because it's not in my messages.tbl yet shows up randomly anyway, playing the retail headani + voice over file with the default message... I had to hack "around" it by replacing the source headani and voice file...
Title: Re: Builtin Messages Overhaul
Post by: FreeSpaceFreak on September 08, 2012, 01:32:15 pm
Would it depend on a hard-coded list of moods, or would it work via string comparison? Hard-coded moods might be slightly faster and more fool-proof, but string comparison would allow infinite flexibility: mods could specify any moods they want. JAD could use 'troll' and 'disco' moods, for instance, and mission-specific built-in messages would also become possible. To continue your example, after the player's battlestar gets blown up, the pilots could go "There, that one's for the Theseus!". The only limit would be the modders' imagination.
Title: Re: Builtin Messages Overhaul
Post by: Sushi on September 08, 2012, 02:07:54 pm
You mention both mission-based and pilot-based moods. I humbly suggest starting just with the first one, and dealing with the second one later. The mission ones are both more immediately useful and more straightforward, I think, and will be easier to do.

Honestly, my first thought is to just allow "mood" to be a property of a mission that can be controlled via set-mood and clear-mood SEXPs. You can have more than one mood as appropriate for the current circumstances (so you basically track a list of active moods). And as you already mentioned, mood-keyed messages will only play if the current mission's mood list includes the right string. It may also be useful to have a +Not Mood property, for messages that are generally appropriate EXCEPT for specific times.

So for Diaspora, to prevent stuff like the above, you could do the following:

- Cocky pilot messages of praise for self and others have +not-mood: Somber.
- In the mission, track a variable called "somber-cooldown." This starts at 0.
- When a major friendly ship gets blown up, add some value to somber-cooldown and call set-mood "Somber".
- Have a SEXP that just fires off every second and decrements somber-cooldown until it is 0.
- Have a SEXP that fires when somber-cooldown reaches 0 to call clear-mood "Somber".

Or something like that. This is all pretty much off the top of my head.
Title: Re: Builtin Messages Overhaul
Post by: z64555 on September 08, 2012, 04:08:28 pm
If your going for cooldown stuff such as that, you might have to resort to mood scales... like from Overjoyed to Pissed off.  :nervous:
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 08, 2012, 08:42:49 pm
While you're messing with builtin messages, could you also get rid of the hardcoded terran command "hostiles arrived" message that appears when you set the command sender to a capship?
It's hardcoded for sure because it's not in my messages.tbl yet shows up randomly anyway, playing the retail headani + voice over file with the default message... I had to hack "around" it by replacing the source headani and voice file...

I'm not certain which error you're on about. But file a Mantis bug report on it and I'll assign it to myself.
Title: Re: Builtin Messages Overhaul
Post by: Goober5000 on September 09, 2012, 02:43:33 pm
This sounds like a terrific feature. :yes:  I think the string-comparison method for mood selection would be the most useful.
Title: Re: Builtin Messages Overhaul
Post by: redsniper on September 10, 2012, 09:10:13 am
Code: [Select]
when
-all-day
-erry-day
 -Set-Builtin-Pilot-Mood
  -Laporte
  -Vengeful
  -Murderous
  -Insane
Title: Re: Builtin Messages Overhaul
Post by: Droid803 on September 10, 2012, 10:48:22 pm
While you're messing with builtin messages, could you also get rid of the hardcoded terran command "hostiles arrived" message that appears when you set the command sender to a capship?
It's hardcoded for sure because it's not in my messages.tbl yet shows up randomly anyway, playing the retail headani + voice over file with the default message... I had to hack "around" it by replacing the source headani and voice file...

I'm not certain which error you're on about. But file a Mantis bug report on it and I'll assign it to myself.

...This appears to have been caused by a massive derp on my part.
It's been defaulting to some hardcoded arrival message because it's picking "Command" to send a message when the Command Persona selected has no "Arrive Enemy" message defined (I derped and typoed Command as Comand lol), thus causing it to play HEAD-CM1, TC_Arrival.wav, and a random "Arrive Enemy" message picked from messages.tbl, which, while being a strange default option, I guess isn't really a bug?

That said I am excite about this feature.
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 10, 2012, 11:42:33 pm
Cool. I'll have to get to coding it then. :)
Title: Re: Builtin Messages Overhaul
Post by: Woolie Wool on September 11, 2012, 05:10:38 pm
Is there any chance for a taunt function (you would be able to use it on enemies to goad them into dropping what they're doing for a while to attack you, and enemies could be set to use it on you every so often)?
Title: Re: Builtin Messages Overhaul
Post by: Dragon on September 11, 2012, 05:22:48 pm
Yes, that'd come in handy. Also, voice messages by player while giving orders could greatly add to atmosphere, especially in non-FS mods.
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 11, 2012, 06:24:52 pm
Neither of those are builtin messages but I'll look into it.
Title: Re: Builtin Messages Overhaul
Post by: Mongoose on September 18, 2012, 03:31:29 am
...you know what Spoon and Droid will do with this, right?  FS_Open: The Visual Novel.
Title: Re: Builtin Messages Overhaul
Post by: General Battuta on September 18, 2012, 07:12:03 am
...you know what Spoon and Droid will do with this, right?  FS_Open: The Visual Novel.

Both Spoon and I (and probably Droid too) have in fact already done this by use of some insane SEXP trees. You can build your own extremely detailed pilot personas in FRED. Right now I have several missions where each wingmate will react not just to orders in general but to orders to attack or defend specific ships at specific times in the mission, and they'll even draw from a pool of randomized lines so they don't repeat themselves too much.
Title: Re: Builtin Messages Overhaul
Post by: Spoon on September 18, 2012, 07:43:34 am
...you know what Spoon and Droid will do with this, right?  FS_Open: The Visual Novel.
>Implying I'm not already doing this without this feature

Both Spoon and I (and probably Droid too) have in fact already done this by use of some insane SEXP trees. You can build your own extremely detailed pilot personas in FRED. Right now I have several missions where each wingmate will react not just to orders in general but to orders to attack or defend specific ships at specific times in the mission, and they'll even draw from a pool of randomized lines so they don't repeat themselves too much.
I've seen this in action in BP and its super nice and impressive  :yes:
But a visual novel it is not  :p
Title: Re: Builtin Messages Overhaul
Post by: General Battuta on September 18, 2012, 07:44:47 am
Yeah but the VN stuff you're doing is the same technique, right? It's not a codeside pilot persona thing. You could already achieve all this 'mood' stuff with SEXPs - it'd just be much more of a pain in the ass.
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 18, 2012, 08:42:23 am
Yep. Which is why I want to put it into the code. :)

...you know what Spoon and Droid will do with this, right?  FS_Open: The Visual Novel.

And the only reason I'm not going to be making Diaspora : The Visual Novel is cause we're shooting for fully voice acted in every release. :p
Title: Re: Builtin Messages Overhaul
Post by: Droid803 on September 18, 2012, 01:24:32 pm
...you know what Spoon and Droid will do with this, right?  FS_Open: The Visual Novel.
>Implying I'm not already doing this without this feature

I have to commend you for being able to sift through 200+ events, enough to make the old FRED events editor lock up on closing, and have the events page span 2 whole monitors.

Yeah but the VN stuff you're doing is the same technique, right? It's not a codeside pilot persona thing. You could already achieve all this 'mood' stuff with SEXPs - it'd just be much more of a pain in the ass.

Yeah, which is why I actually haven't tried it (to any deep extent, after it being apparent that it would be a pain in the ass) :P
I've heard the horror stories and am not interested in fighting SEXPthulhu to make it work. :nervous:
With the codeside pilot things though, I'm much more inclined to make it happen XD
Title: Re: Builtin Messages Overhaul
Post by: General Battuta on September 18, 2012, 02:21:42 pm
Without even the luxury of Spoon's awesome dual monitors I ended up having to FRED in notepad a lot. (This feature would own as code)
Title: Re: Builtin Messages Overhaul
Post by: Spoon on September 18, 2012, 06:45:12 pm
Well the difference is that the VN parts are all pre set with variables and stuff.
This feature seems more about setting the mood for in mission persona's so they don't blab out at the most inappropriate moments.
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 19, 2012, 10:20:47 am
Okay boys and girls, here (http://fs2downloads.com/Misc-Downloads/Builds/Mission_Moods_Build.7z)'s a test build to play with. I'll go over how things work.

First you have to declare your list of moods in message.tbl. This goes between the #Message Frequencies (or top of the table if you don't have those) and #Personas sections.

Code: [Select]
;; This is a list of moods that the game will use for builtin
;; messages. Any message without a mood is treated as General

#Moods

$Mood: Happy
$Mood: Angry
$Mood: Vengeful

#End


#Personas


Next you have to define a mood for some or all of the messages in your table. Messages may remain with the default mood if you wish. You can also define a list of moods for which a message may not be played.

Code: [Select]

$Name: Attack Target
$Message: XSTR("Roger that, sir. Engaging your target.", 2737)
+Persona: Wingman 1
+Avi Name: Head-TP1
+Wave Name: 1_attack.wav

$Name: Attack Target
$Message: XSTR("Yes sir, I'll make the bastards pay for Capella!", 2737)
+Persona: Wingman 1
+Avi Name: Head-TP1
+Wave Name: 1_attack.wav
$Mood: Vengeful
$Exclude Mood: ( "Happy" )

$Name: Attack Target
$Message: XSTR("Yes sir. I just love killing Shivans!", 2737)
+Persona: Wingman 1
+Avi Name: Head-TP1
+Wave Name: 1_attack.wav
$Mood: Angry
$Exclude Mood: ( "Angry" "Vengeful" )


Builtin messages are selected by these criteria

1) If there is a message (or messages) for this persona that matches the mood (including no mood set) - one of those will be sent.
2) If there is no message that matches the mood, any message that isn't on the excluded list for this persona will be sent.
3) If only excluded messages for this persona match, one of those will be sent.
4) If there is no message from this persona, a matching message from any ship of the same species will be sent.
5) If that fails, any builtin message at all which is of the right type will be sent.

in cases 3-5 a message is written to the debug log.

You can change the mission mood using the new set-mission-mood SEXP.

Here's the code.
Code: [Select]
Index: code/fred2/sexp_tree.cpp
===================================================================
--- code/fred2/sexp_tree.cpp (revision 9214)
+++ code/fred2/sexp_tree.cpp (working copy)
@@ -2758,6 +2758,12 @@
  else
  return 0;
 
+ case OPF_MISSION_MOOD:
+ if (Builtin_moods.empty())
+ return 0;
+ else
+ return 1;
+
  default:
  Int3();
 
@@ -4385,6 +4391,10 @@
  list = get_listing_opf_ship_effect();
  break;
 
+ case OPF_MISSION_MOOD:
+ list = get_listing_opf_mission_moods();
+ break;
+
  default:
  Int3();  // unknown OPF code
  list = NULL;
@@ -5857,6 +5867,18 @@
  return head.next;
 }
 
+sexp_list_item *sexp_tree::get_listing_opf_mission_moods()
+{
+ sexp_list_item head;
+ for (SCP_vector<SCP_string>::iterator iter = Builtin_moods.begin(); iter != Builtin_moods.end(); ++iter) {
+ head.add_data_dup(iter->c_str());
+ }
+
+ return head.next;
+}
+
+
+
 // Deletes sexp_variable from sexp_tree.
 // resets tree to not include given variable, and resets text and type
 void sexp_tree::delete_sexp_tree_variable(const char *var_name)
Index: code/fred2/sexp_tree.h
===================================================================
--- code/fred2/sexp_tree.h (revision 9214)
+++ code/fred2/sexp_tree.h (working copy)
@@ -267,6 +267,7 @@
  sexp_list_item *get_listing_opf_hud_gauge();
  sexp_list_item *get_listing_opf_ship_effect();
  sexp_list_item *get_listing_opf_animation_type();
+ sexp_list_item *get_listing_opf_mission_moods();
 
  int m_mode;
  int item_index;
Index: code/mission/missionmessage.cpp
===================================================================
--- code/mission/missionmessage.cpp (revision 9214)
+++ code/mission/missionmessage.cpp (working copy)
@@ -35,6 +35,8 @@
 #include "network/multiutil.h"
 #include "mod_table/mod_table.h"
 
+SCP_vector<SCP_string> Builtin_moods;
+int Current_mission_mood;
 
 int Valid_builtin_message_types[MAX_BUILTIN_MESSAGE_TYPES];
 // here is the list of the builtin message names and the settings which control how frequently
@@ -417,6 +419,49 @@
  }
  }
 
+ if ( optional_string("$Mood:")) {
+ SCP_string buf;
+ bool found = false;
+
+ stuff_string(buf, F_NAME);
+ for (SCP_vector<SCP_string>::iterator iter = Builtin_moods.begin(); iter != Builtin_moods.end(); ++iter) {
+ if (iter->compare(buf) == 0) {
+ msg.mood = iter - Builtin_moods.begin();
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // found a mood, but it's not in the list of moods at the start of the table
+ Warning(LOCATION, "Message.tbl has an entry for mood type %s, but this mood is not in the #Moods section of the table.", buf.c_str());
+ }
+ }
+ else {
+ msg.mood = 0;
+ }
+
+ if ( optional_string("$Exclude Mood:")) {
+ SCP_vector<SCP_string> buff;
+ bool found = false;
+
+ stuff_string_list(buff);
+ for (SCP_vector<SCP_string>::iterator parsed_moods = buff.begin(); parsed_moods != buff.end(); ++parsed_moods) {
+ for (SCP_vector<SCP_string>::iterator iter = Builtin_moods.begin(); iter != Builtin_moods.end(); ++iter) {
+ if (!stricmp(iter->c_str(), parsed_moods->c_str())) {
+ msg.excluded_moods.push_back(iter - Builtin_moods.begin());
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // found a mood, but it's not in the list of moods at the start of the table
+ Warning(LOCATION, "Message.tbl has an entry for exclude mood type %s, but this mood is not in the #Moods section of the table.", parsed_moods->c_str());
+ }
+ }
+ }
+
  Num_messages++;
  Messages.push_back(msg);
 }
@@ -464,6 +509,21 @@
  }
 }
 
+void message_moods_parse()
+{
+
+ while (required_string_either("#End", "$Mood:")){
+ SCP_string buf;
+
+ required_string("$Mood:");
+ stuff_string(buf, F_NAME);
+
+ Builtin_moods.push_back(buf);
+ }
+
+ required_string("#End");
+}
+
 void parse_msgtbl()
 {
  int i, j;
@@ -499,11 +559,17 @@
 
  // now we can start parsing
  if (optional_string("#Message Frequencies")) {
- while ( required_string_either("#Personas", "$Name:")) {
+ while (!required_string_3("#Personas", "#Moods", "$Name:")) {
  message_frequency_parse();
  }
  }
 
+ Builtin_moods.push_back("Default");
+ if (optional_string("#Moods")) {
+ message_moods_parse();
+ }
+
+
  required_string("#Personas");
  while ( required_string_either("#Messages", "$Persona:")){
  persona_parse();
@@ -600,6 +666,8 @@
  table_read = 1;
  }
 
+ Current_mission_mood = 0;
+
  // reset the number of messages that we have for this mission
  Num_messages = Num_builtin_messages;
  Num_message_avis = Num_builtin_avis;
@@ -1816,9 +1884,12 @@
  nprintf (("messaging", "Couldn't find message id %s to send to player!\n", id ));
 }
 
-#define BUILTIN_MATCHES_TYPE 0
-#define BUILTIN_MATCHES_SPECIES 1
-#define BUILTIN_MATCHES_EXACTLY 2
+#define BUILTIN_MATCHES_TYPE 0
+#define BUILTIN_MATCHES_SPECIES 1
+#define BUILTIN_MATCHES_PERSONA_CHECK_MOOD 2
+#define BUILTIN_MATCHES_PERSONA_EXCLUDED 3
+#define BUILTIN_MATCHES_PERSONA 4
+#define BUILTIN_MATCHES_PERSONA_MOOD 5
 
 typedef struct matching_builtin {
  int type_of_match;
@@ -1911,9 +1982,28 @@
  // NOTE: doesn't need to be nested under the species condition above
  if ( (persona_index >= 0) && (Messages[i].persona_index == persona_index) ) {
  // condition 3: type + species + persona index match
- current_builtin->type_of_match =  BUILTIN_MATCHES_EXACTLY;
+ current_builtin->type_of_match =  BUILTIN_MATCHES_PERSONA_CHECK_MOOD;
  }
 
+ // check if the personas mood suits this particular message, first check if it is excluded
+ if (!Messages[i].excluded_moods.empty() && (current_builtin->type_of_match ==  BUILTIN_MATCHES_PERSONA_CHECK_MOOD)) {
+ for (SCP_vector<int>::iterator iter = Messages[i].excluded_moods.begin(); iter != Messages[i].excluded_moods.end(); ++iter) {
+ if (*iter == Current_mission_mood) {
+ current_builtin->type_of_match =  BUILTIN_MATCHES_PERSONA_EXCLUDED;
+ break;
+ }
+ }
+ }
+
+ if (current_builtin->type_of_match ==  BUILTIN_MATCHES_PERSONA_CHECK_MOOD) {
+ if (Current_mission_mood == Messages[i].mood) {
+ current_builtin->type_of_match =  BUILTIN_MATCHES_PERSONA_MOOD;
+ }
+ else {
+ current_builtin->type_of_match =  BUILTIN_MATCHES_PERSONA;
+ }
+ }
+
  if (current_builtin->type_of_match == best_match) {
  num_matching_builtins++;
  }
@@ -1928,14 +2018,17 @@
  }
  }
 
- if (best_match == BUILTIN_MATCHES_SPECIES) {
- nprintf(("messaging", "Couldn't find builtin message %s for persona %d\n", Builtin_messages[type].name, persona_index ));
- nprintf(("messaging", "using a message for any persona of that species\n"));
+ if (best_match == BUILTIN_MATCHES_PERSONA_EXCLUDED) {
+ mprintf(("MESSAGING", "Couldn't find builtin message %s for persona %d with a none excluded mood\n", Builtin_messages[type].name, persona_index ));
+ mprintf(("MESSAGING", "using an excluded message for this persona\n"));
+ }else if (best_match == BUILTIN_MATCHES_SPECIES) {
+ mprintf(("MESSAGING", "Couldn't find builtin message %s for persona %d\n", Builtin_messages[type].name, persona_index ));
+ mprintf(("MESSAGING", "using a message for any persona of that species\n"));
  } else if (best_match == BUILTIN_MATCHES_TYPE) {
- nprintf(("messaging", "Couldn't find builtin message %s for persona %d\n", Builtin_messages[type].name, persona_index ));
- nprintf(("messaging", "looking for message for any persona of any species\n"));
+ mprintf(("MESSAGING", "Couldn't find builtin message %s for persona %d\n", Builtin_messages[type].name, persona_index ));
+ mprintf(("MESSAGING", "looking for message for any persona of any species\n"));
  } else if (best_match < 0) {
- nprintf(("messaging", "Couldn't find any builtin message of type %d\n", type ));
+ mprintf(("MESSAGING", "Couldn't find any builtin message of type %d\n", type ));
  Int3();
  return;
  }
Index: code/mission/missionmessage.h
===================================================================
--- code/mission/missionmessage.h (revision 9214)
+++ code/mission/missionmessage.h (working copy)
@@ -63,6 +63,9 @@
  int min_delay;
 } builtin_message;
 
+extern SCP_vector<SCP_string> Builtin_moods;
+extern int Current_mission_mood;
+
 // this number in this define should match the number of elements in the next array
 #define MAX_BUILTIN_MESSAGE_TYPES 45
 
@@ -119,6 +122,8 @@
  char message[MESSAGE_LENGTH]; // actual message
  int persona_index; // which persona says this message
  int multi_team; // multiplayer team filter (important for TvT only)
+ int mood;
+ SCP_vector<int> excluded_moods;
 
  // unions for avi/wave information.  Because of issues with Fred, we are using
  // the union to specify either the index into the avi or wave arrays above,
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp (revision 9214)
+++ code/parse/sexp.cpp (working copy)
@@ -343,8 +343,10 @@
  { "disable-builtin-messages", OP_DISABLE_BUILTIN_MESSAGES, 0, INT_MAX,}, // Karajorma
  { "enable-builtin-messages", OP_ENABLE_BUILTIN_MESSAGES, 0, INT_MAX,}, // Karajorma
  { "set-persona", OP_SET_PERSONA, 2, INT_MAX,}, // Karajorma
- { "set-death-message", OP_SET_DEATH_MESSAGE, 1, 1 }, // Goober5000
+ { "set-death-message", OP_SET_DEATH_MESSAGE, 1, 1 }, // Goober5000
+ { "set-mission-mood", OP_SET_MISSION_MOOD, 1, 1 }, // Karajorma
 
+
  //AI Control Sub-Category
  { "add-goal", OP_ADD_GOAL, 2, 2, },
  { "remove-goal", OP_REMOVE_GOAL, 2, 2, }, // Goober5000
@@ -2656,6 +2658,23 @@
  }
  break;
 
+ case OPF_MISSION_MOOD:
+ if (type2 != SEXP_ATOM_STRING) {
+ return SEXP_CHECK_TYPE_MISMATCH;
+ }
+
+ for (i = 0; i < (int)Builtin_moods.size(); i++) {
+ if (!strcmp(Builtin_moods[i].c_str(), CTEXT(node))) {
+ break;
+ }
+ }
+
+ if (i == Builtin_moods.size()) {
+ return SEXP_CHECK_INVALID_MISSION_MOOD;
+ }
+
+ break;
+
  case OPF_FONT:
  if (type2 != SEXP_ATOM_STRING) {
  return SEXP_CHECK_TYPE_MISMATCH;
@@ -2977,8 +2996,7 @@
  if (get_effect_from_name(CTEXT(node)) == -1 ) {
  return SEXP_CHECK_INVALID_SHIP_EFFECT;
  }
- break;
-
+ break;
 
  default:
  Error(LOCATION, "Unhandled argument format");
@@ -12575,6 +12593,21 @@
  }
 }
 
+void sexp_set_mission_mood (int node)
+{
+ char *mood;
+
+ mood = CTEXT(node);
+ for (SCP_vector<SCP_string>::iterator iter = Builtin_moods.begin(); iter != Builtin_moods.end(); ++iter) {
+ if (!strcmp(iter->c_str(), mood)) {
+ Current_mission_mood = iter - Builtin_moods.begin();
+ return;
+ }
+ }
+
+ Warning(LOCATION, "Sexp-mission-mood attempted to set mood %s which does not exist in messages.tbl", mood);
+}
+
 int sexp_weapon_fired_delay(int node, int op_num)
 {
  ship *shipp;
@@ -21579,6 +21612,11 @@
  sexp_val = SEXP_TRUE;
  break;
 
+ case OP_SET_MISSION_MOOD:
+ sexp_set_mission_mood (node);
+ sexp_val = SEXP_TRUE;
+ break;
+
  case OP_SEND_MESSAGE_LIST:
  sexp_send_message_list(node);
  sexp_val = SEXP_TRUE;
@@ -23677,6 +23715,7 @@
  case OP_UNLOCK_AFTERBURNER:
  case OP_RESET_ORDERS:
  case OP_SET_PERSONA:
+ case OP_SET_MISSION_MOOD:
  case OP_CHANGE_SUBSYSTEM_NAME:
  case OP_SET_RESPAWNS:
  case OP_SET_AFTERBURNER_ENERGY:
@@ -24615,6 +24654,9 @@
  else
  return OPF_SHIP;
 
+ case OP_SET_MISSION_MOOD:
+ return OPF_MISSION_MOOD;
+
  case OP_SELF_DESTRUCT:
  return OPF_SHIP;
 
@@ -26153,6 +26195,9 @@
  case SEXP_CHECK_INVALID_ANIMATION_TYPE:
  return "Invalid animation type";
 
+ case SEXP_CHECK_INVALID_MISSION_MOOD:
+ return "Invalid mission mood";
+
  default:
  Warning(LOCATION, "Unhandled sexp error code %d!", num);
  return "Unhandled sexp error code!";
@@ -26925,6 +26970,7 @@
  case OP_DISABLE_BUILTIN_MESSAGES:
  case OP_SET_DEATH_MESSAGE:
  case OP_SET_PERSONA:
+ case OP_SET_MISSION_MOOD:
  return CHANGE_SUBCATEGORY_MESSAGING;
 
 
@@ -28338,6 +28384,12 @@
  "\tAll:\tName of ship to be silenced." },
 
  // Karajorma
+ { OP_SET_MISSION_MOOD, "set Mission Mood (Action operator)\r\n"
+ "\tSets the mood of the mission, this affects the choice of builtin messages sent by wingmen\r\n"
+ "Takes 1 argument...\r\n"
+ "\t1:\tMission mood (from messages.tbl) to use." },
+
+ // Karajorma
  { OP_SET_PERSONA, "Set Persona (Action operator)\r\n"
  "\tSets the persona of the supplied ship to the persona supplied\r\n"
  "Takes 2 or more arguments...\r\n"
Index: code/parse/sexp.h
===================================================================
--- code/parse/sexp.h (revision 9214)
+++ code/parse/sexp.h (working copy)
@@ -106,6 +106,7 @@
 #define OPF_DAMAGE_TYPE 79 // FUBAR - Damage type or <none>
 #define OPF_SHIP_EFFECT 80 // The E - per-ship effects, as defined in post-processing.tbl
 #define OPF_ANIMATION_TYPE 81 // Goober5000 - as defined in modelanim.h
+#define OPF_MISSION_MOOD 82 // Karajorma - Moods determine which builtin messages will be sent
 
 // Operand return types
 #define OPR_NUMBER 1 // returns number
@@ -699,6 +700,7 @@
 #define OP_DESTROY_INSTANTLY (0x0015 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) // Admiral MS
 #define OP_DESTROY_SUBSYS_INSTANTLY (0x0016 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) // Admiral MS
 #define OP_DEBUG (0x0017 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) // Karajorma
+#define OP_SET_MISSION_MOOD (0x0018 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) // Karajorma
 
 
 // defined for AI goals
@@ -956,6 +958,7 @@
 #define SEXP_CHECK_INVALID_AUDIO_VOLUME_OPTION -152
 #define SEXP_CHECK_INVALID_HUD_GAUGE -153
 #define SEXP_CHECK_INVALID_ANIMATION_TYPE -154
+#define SEXP_CHECK_INVALID_MISSION_MOOD -155
 
 #define TRAINING_CONTEXT_SPEED (1<<0)
 #define TRAINING_CONTEXT_FLY_PATH (1<<1)
Title: Re: Builtin Messages Overhaul
Post by: z64555 on September 19, 2012, 12:37:00 pm
Maybe split/move this into test builds? Not sure what the MO is here...  :nervous:
Title: Re: Builtin Messages Overhaul
Post by: karajorma on September 20, 2012, 03:15:34 am
I've updated the builds slightly. All messages which don't define a mood now automatically are given the mood "Default". This means that they can easily be excluded.