Skip to content

Commit

Permalink
Merge pull request scp-fs2open#6385 from Goober5000/which_personas_to…
Browse files Browse the repository at this point in the history
…_sync

allow voice acting manager to handle non-wingman personas
  • Loading branch information
Goober5000 authored Nov 29, 2024
2 parents 0a31226 + 44ddc5f commit fa30b46
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 83 deletions.
2 changes: 1 addition & 1 deletion code/mission/missionmessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ void message_load_wave(int index, const char *filename)
}

// Goober5000
bool message_filename_is_generic(char *filename)
bool message_filename_is_generic(const char *filename)
{
char truncated_filename[MAX_FILENAME_LEN];

Expand Down
2 changes: 1 addition & 1 deletion code/mission/missionmessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ void message_pagein_mission_messages();
int message_filter_multi(int id);

// Goober5000
bool message_filename_is_generic(char *filename);
bool message_filename_is_generic(const char *filename);

// m!m
void message_load_wave(int index, const char *filename);
Expand Down
8 changes: 4 additions & 4 deletions fred2/fred.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2221,16 +2221,16 @@ BEGIN
CONTROL "Just Briefings",IDC_EXPORT_BRIEFINGS,"Button",BS_AUTORADIOBUTTON,280,151,99,9
CONTROL "Just Debriefings",IDC_EXPORT_DEBRIEFINGS,"Button",BS_AUTORADIOBUTTON,280,161,99,9
CONTROL "Just Messages",IDC_EXPORT_MESSAGES,"Button",BS_AUTORADIOBUTTON,280,171,99,9
PUSHBUTTON "Generate Script",IDC_GENERATE_SCRIPT,275,242,120,30
PUSHBUTTON "Generate Script",IDC_GENERATE_SCRIPT,275,208,120,30
CONTROL "Group send-message-list messages before others",IDC_GROUP_MESSAGES,
"Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,293,182,100,19
GROUPBOX "Sync Personas",IDC_SYNC_PERSONAS,149,121,119,152
GROUPBOX "Sync Personas",IDC_SYNC_PERSONAS,149,121,119,118
COMBOBOX IDC_WHICH_TO_SYNC,154,133,109,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Copy message personas to ships",IDC_MESSAGE_PERSONAS_TO_SHIPS,154,151,109,14
PUSHBUTTON "Copy ship personas to messages",IDC_SHIP_PERSONAS_TO_MESSAGES,154,168,109,14
PUSHBUTTON "Set head ANIs using personas in messages.tbl",IDC_SET_HEAD_ANIS_USING_MESSAGES_TBL,154,211,109,23,BS_MULTILINE
PUSHBUTTON "Clear personas from ships that don't send messages",IDC_CLEAR_PERSONAS_FROM_NON_SENDERS,154,185,109,23,BS_MULTILINE
PUSHBUTTON "Check if messages sent by \x22<any wingman>\x22 have at least one ship with that persona",IDC_CHECK_ANY_WINGMAN_PERSONAS,154,237,109,31,BS_MULTILINE
LTEXT "NOTE: Only wingman personas are modified here.",IDC_LBL_NOTE,155,132,107,16
PUSHBUTTON "Check if messages sent by \x22<any wingman>\x22 have at least one ship with that persona",IDC_CHECK_ANY_WINGMAN_PERSONAS,149,242,119,30,BS_MULTILINE
END

IDD_CUSTOM_WING_NAMES DIALOG 0, 0, 390, 54
Expand Down
2 changes: 1 addition & 1 deletion fred2/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@
#define IDC_SBITMAP 1189
#define IDC_ASCT1_VARIABLES_COMBO1 1189
#define IDC_WEAPON_VARIABLES_COMBO 1189
#define IDC_WHICH_TO_SYNC 1189
#define IDC_ASCT1_CLASS_COMBO2 1190
#define IDC_BACKGROUND_NUM 1190
#define IDC_WING_DISPLAY_FILTER 1191
Expand Down Expand Up @@ -1119,7 +1120,6 @@
#define IDC_SYNC_PERSONAS 1582
#define IDC_TOGGLE_START_CHASE 1583
#define IDC_RESTRICT_PATHS_LABEL 1584
#define IDC_LBL_NOTE 1584
#define IDC_PATH_LIST 1585
#define IDC_LISTITEM 1586
#define IDC_ENTRY_FORMAT_DESC 1588
Expand Down
183 changes: 108 additions & 75 deletions fred2/voiceactingmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "fred.h"
#include "freddoc.h"
#include "VoiceActingManager.h"
#include "globalincs/vmallocator.h"
#include "missionui/missioncmdbrief.h"
#include "mission/missionbriefcommon.h"
#include "mission/missionmessage.h"
Expand Down Expand Up @@ -35,6 +36,10 @@ char Voice_script_entry_format[NOTES_LENGTH];
int Voice_export_selection;
bool Voice_group_messages;

constexpr int WINGMAN_PERSONAS = 0;
constexpr int NON_WINGMAN_PERSONAS = 1;
constexpr int SPECIFIC_PERSONAS_START_AT = 2;


/////////////////////////////////////////////////////////////////////////////
// VoiceActingManager dialog
Expand All @@ -60,6 +65,7 @@ VoiceActingManager::VoiceActingManager(CWnd* pParent /*=NULL*/)
m_export_debriefings = FALSE;
m_export_messages = FALSE;
m_group_messages = FALSE;
m_which_persona_to_sync = 0;
//}}AFX_DATA_INIT
}

Expand All @@ -84,6 +90,7 @@ void VoiceActingManager::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_EXPORT_DEBRIEFINGS, m_export_debriefings);
DDX_Check(pDX, IDC_EXPORT_MESSAGES, m_export_messages);
DDX_Check(pDX, IDC_GROUP_MESSAGES, m_group_messages);
DDX_CBIndex(pDX, IDC_WHICH_TO_SYNC, m_which_persona_to_sync);
//}}AFX_DATA_MAP
}

Expand Down Expand Up @@ -114,6 +121,7 @@ BEGIN_MESSAGE_MAP(VoiceActingManager, CDialog)
ON_BN_CLICKED(IDC_EXPORT_DEBRIEFINGS, OnExportDebriefings)
ON_BN_CLICKED(IDC_EXPORT_MESSAGES, OnExportMessages)
ON_BN_CLICKED(IDC_INCLUDE_SENDER, OnBnClickedIncludeSender)
ON_CBN_SELCHANGE(IDC_WHICH_TO_SYNC, OnChangeWhichToSync)
ON_BN_CLICKED(IDC_MESSAGE_PERSONAS_TO_SHIPS, OnCopyMessagePersonasToShips)
ON_BN_CLICKED(IDC_SHIP_PERSONAS_TO_MESSAGES, OnCopyShipPersonasToMessages)
ON_BN_CLICKED(IDC_SET_HEAD_ANIS_USING_MESSAGES_TBL, OnSetHeadANIsUsingMessagesTbl)
Expand Down Expand Up @@ -170,6 +178,13 @@ BOOL VoiceActingManager::OnInitDialog()
CButton *button = ((CButton *) GetDlgItem(IDC_GROUP_MESSAGES));
button->EnableWindow(m_export_everything || m_export_messages);

// populate persona dropdown
box = ((CComboBox *) GetDlgItem(IDC_WHICH_TO_SYNC));
box->AddString("<Wingman Personas>");
box->AddString("<Non-Wingman Personas>");
for (const auto& persona : Personas)
box->AddString(persona.name);

UpdateData(FALSE);

return TRUE;
Expand Down Expand Up @@ -327,11 +342,15 @@ CString VoiceActingManager::generate_filename(CString section, int number, int d
return str;
}

#define STRCPY_IF_MODIFIED(dest, src) { auto temp = src; if (stricmp(dest, temp)) { strcpy(dest, temp); num_modified++; } }
#define COPY_IF_MODIFIED(dest, src) { auto temp = src; if (dest != temp) { dest = temp; num_modified++; } }
#define STRDUP_IF_MODIFIED(dest, src) { auto temp = src; if (dest == nullptr || stricmp(dest, temp)) { if (dest != nullptr) { free(dest); } dest = strdup(temp); num_modified++; } }

void VoiceActingManager::OnGenerateFileNames()
{
int i;
int digits;
size_t modified_filenames = 0;
size_t num_modified = 0;

// stuff data to variables
UpdateData(TRUE);
Expand All @@ -344,10 +363,7 @@ void VoiceActingManager::OnGenerateFileNames()

// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_command_briefing, i + 1, digits)));
modified_filenames++;
}
STRCPY_IF_MODIFIED(filename, generate_filename(m_abbrev_command_briefing, i + 1, digits));
}

// briefings
Expand All @@ -358,10 +374,7 @@ void VoiceActingManager::OnGenerateFileNames()

// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_briefing, i + 1, digits)));
modified_filenames++;
}
STRCPY_IF_MODIFIED(filename, generate_filename(m_abbrev_briefing, i + 1, digits));
}

// debriefings
Expand All @@ -372,40 +385,29 @@ void VoiceActingManager::OnGenerateFileNames()

// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
strcpy(filename, LPCTSTR(generate_filename(m_abbrev_debriefing, i + 1, digits)));
modified_filenames++;
}
STRCPY_IF_MODIFIED(filename, generate_filename(m_abbrev_debriefing, i + 1, digits));
}

// messages
digits = calc_digits(Num_messages - Num_builtin_messages);
for (i = 0; i < Num_messages - Num_builtin_messages; i++)
{
char *filename = Messages[i + Num_builtin_messages].wave_info.name;
MMessage *message = &Messages[i + Num_builtin_messages];
const char *filename = message->wave_info.name;

// generate only if we're replacing or if it has a replaceable name
if (!m_no_replace || !strlen(filename) || message_filename_is_generic(filename))
{
// free existing filename
if (filename != NULL)
free(filename);

// allocate new filename
Messages[i + Num_builtin_messages].wave_info.name = strdup(LPCTSTR(generate_filename(m_abbrev_message, i + 1, digits, message)));
modified_filenames++;
}
STRDUP_IF_MODIFIED(message->wave_info.name, generate_filename(m_abbrev_message, i + 1, digits, message));
}

if ( modified_filenames > 0 ) {
if ( num_modified > 0 ) {
// Tell FRED that we actually modified something
set_modified(TRUE);
}

// notify user that we are done and how many filenames were changed
SCP_string message;
sprintf(message, "File name generation complete. " SIZE_T_ARG " file %s modified.", modified_filenames, (modified_filenames == 1) ? "name was" : "names were");
sprintf(message, "File name generation complete. " SIZE_T_ARG " file %s modified.", num_modified, (num_modified == 1) ? "name was" : "names were");
MessageBox(message.c_str(), "Voice Acting Manager");
}

Expand Down Expand Up @@ -566,19 +568,30 @@ void VoiceActingManager::export_one_message(const MMessage *message)

/** Passed sender string will have either have the senders name
or '\<none\>'*/
void VoiceActingManager::get_valid_sender(char *sender, size_t sender_size, const MMessage *message, int *sender_shipnum)
void VoiceActingManager::get_valid_sender(char *sender, size_t sender_size, const MMessage *message, int *sender_shipnum, bool *is_command)
{
Assert( sender != NULL );
Assert( message != NULL );

memset(sender, 0, sender_size);
strncpy(sender, get_message_sender(message), sender_size - 1);

// check if we're overriding #Command
if (The_mission.flags[Mission::Mission_Flags::Override_hashcommand] && !strcmp("#Command", sender))
if (!strcmp("#Command", sender))
{
memset(sender, 0, sender_size);
strncpy(sender, The_mission.command_sender, sender_size - 1);
if (is_command)
*is_command = true;

// check if we're overriding #Command
if (The_mission.flags[Mission::Mission_Flags::Override_hashcommand])
{
memset(sender, 0, sender_size);
strncpy(sender, The_mission.command_sender, sender_size - 1);
}
}
else
{
if (is_command)
*is_command = false;
}

// strip hash if present
Expand Down Expand Up @@ -971,10 +984,36 @@ void VoiceActingManager::OnBnClickedIncludeSender()
UpdateData(FALSE);
}

void VoiceActingManager::OnChangeWhichToSync()
{
UpdateData(TRUE);
}

bool VoiceActingManager::check_persona(int persona)
{
Assertion(SCP_vector_inbounds(Personas, persona), "The persona index provided to check_persona() is not in range!");

if (m_which_persona_to_sync == WINGMAN_PERSONAS)
{
return (Personas[persona].flags & PERSONA_FLAG_WINGMAN) != 0;
}
else if (m_which_persona_to_sync == NON_WINGMAN_PERSONAS)
{
return (Personas[persona].flags & PERSONA_FLAG_WINGMAN) == 0;
}
else
{
int real_persona_to_sync = m_which_persona_to_sync - SPECIFIC_PERSONAS_START_AT;
Assertion(SCP_vector_inbounds(Personas, real_persona_to_sync), "The m_which_persona_to_sync dropdown index is not in range!");
return real_persona_to_sync == persona;
}
}

void VoiceActingManager::OnCopyPersonas(bool messages_to_ships)
{
char sender_buf[NAME_LENGTH];
int sender_shipnum;
bool is_command;
size_t num_modified = 0;

SCP_unordered_set<int> already_assigned;
Expand All @@ -986,41 +1025,46 @@ void VoiceActingManager::OnCopyPersonas(bool messages_to_ships)
auto message = &Messages[i + Num_builtin_messages];

// find whoever sent this message
get_valid_sender(sender_buf, NAME_LENGTH, message, &sender_shipnum);
get_valid_sender(sender_buf, NAME_LENGTH, message, &sender_shipnum, &is_command);
auto sender_shipp = (sender_shipnum < 0) ? nullptr : &Ships[sender_shipnum];

// if it's a ship, copy the persona
if (sender_shipnum >= 0)
{
auto sender_shipp = &Ships[sender_shipnum];
auto persona_to_copy = (messages_to_ships) ? message->persona_index : sender_shipp->persona_index;
// NOTE: It is possible for a ship that is behaving as a "command source" to have a different persona than the mission's "command persona".
// If this is so, any messages sent by #Command will have the mission's "command persona", and any messages sent by the ship will have the ship's persona.

// don't copy None, and only copy wingman personas
if (persona_to_copy >= 0 && (Personas[persona_to_copy].flags & PERSONA_FLAG_WINGMAN))
int persona_to_copy;
if (messages_to_ships)
persona_to_copy = message->persona_index;
else if (is_command)
persona_to_copy = The_mission.command_persona;
else if (sender_shipp)
persona_to_copy = sender_shipp->persona_index;
else
persona_to_copy = -1;

// don't copy None, and only copy the personas we want
if (persona_to_copy >= 0 && check_persona(persona_to_copy))
{
if (messages_to_ships && sender_shipp)
{
if (messages_to_ships)
if (already_assigned.count(sender_shipnum) > 0 && sender_shipp->persona_index != persona_to_copy)
{
if (already_assigned.count(sender_shipnum) > 0 && sender_shipp->persona_index != persona_to_copy)
{
inconsistent_copy_msg += "\n\u2022 ";
inconsistent_copy_msg += sender_shipp->ship_name;
}

sender_shipp->persona_index = persona_to_copy;
already_assigned.insert(sender_shipnum);
num_modified++;
inconsistent_copy_msg += "\n\u2022 ";
inconsistent_copy_msg += sender_shipp->ship_name;
}
else
already_assigned.insert(sender_shipnum);

COPY_IF_MODIFIED(sender_shipp->persona_index, persona_to_copy);
}
else if (!messages_to_ships)
{
if (already_assigned.count(i) > 0 && message->persona_index != persona_to_copy)
{
if (already_assigned.count(i) > 0 && message->persona_index != persona_to_copy)
{
inconsistent_copy_msg += "\n\u2022 ";
inconsistent_copy_msg += message->name;
}

message->persona_index = persona_to_copy;
already_assigned.insert(i);
num_modified++;
inconsistent_copy_msg += "\n\u2022 ";
inconsistent_copy_msg += message->name;
}
already_assigned.insert(i);

COPY_IF_MODIFIED(message->persona_index, persona_to_copy);
}
}
}
Expand Down Expand Up @@ -1075,12 +1119,11 @@ void VoiceActingManager::OnClearPersonasFromNonSenders()
// for ships that aren't message senders
if (all_senders.count(objp->instance) == 0)
{
// only clear wingman personas
if ((Ships[objp->instance].persona_index >= 0) && (Personas[Ships[objp->instance].persona_index].flags & PERSONA_FLAG_WINGMAN))
// only for the personas we want
if ((Ships[objp->instance].persona_index >= 0) && check_persona(Ships[objp->instance].persona_index))
{
// clear the persona
Ships[objp->instance].persona_index = -1;
num_modified++;
COPY_IF_MODIFIED(Ships[objp->instance].persona_index, -1);
}
}
}
Expand Down Expand Up @@ -1117,8 +1160,8 @@ void VoiceActingManager::OnSetHeadANIsUsingMessagesTbl()
if (message->persona_index < 0)
continue;

// only wingman personas
if (!(Personas[message->persona_index].flags & PERSONA_FLAG_WINGMAN))
// only the personas we want
if (!check_persona(message->persona_index))
continue;

// find the corresponding head for this persona
Expand All @@ -1130,17 +1173,7 @@ void VoiceActingManager::OnSetHeadANIsUsingMessagesTbl()
if (message->persona_index == builtin_message->persona_index)
{
// either assign the correct head from scratch, or change the head to the correct one
if (message->avi_info.name == nullptr)
{
message->avi_info.name = strdup(builtin_message->avi_info.name);
num_modified++;
}
else if (stricmp(message->avi_info.name, builtin_message->avi_info.name) != 0)
{
free(message->avi_info.name);
message->avi_info.name = strdup(builtin_message->avi_info.name);
num_modified++;
}
STRDUP_IF_MODIFIED(message->avi_info.name, builtin_message->avi_info.name);

// done searching
found = true;
Expand Down
Loading

0 comments on commit fa30b46

Please sign in to comment.