I didn't want to bump the other thread as it's so old, but basically I've been "working" on custom comm menu stuff with Goober for a while the discussion of which originally surfaced
here. I say "working" because progress has languished for a few months, and so instead of just keeping the patch on my HDD I thought I'd put up the (admittedly not very large) bit that I've done so that hopefully someone else can pick it up, since at this point I've resigned myself to the fact that I won't be working on it, and I apologise that it took me this long to get this out there.
Basically this introduces a new menu item currently named "Special" that is intended to support FREDder defined comm menu items. Credit for the initial design goes to Goober; I was just doing the implementation. I'll let the patch speak for itself instead of trying to explain everything, but I'm happy to answer questions.
Please note: This is nowhere near complete; all I had accomplished really was displaying the "Special" item in the comm menu and recursively displaying a custom_comm_item's children.
Index: code/hud/hudsquadmsg.cpp
===================================================================
--- code/hud/hudsquadmsg.cpp (revision 9699)
+++ code/hud/hudsquadmsg.cpp (working copy)
@@ -149,7 +149,7 @@
// following are defines and character strings that are used as part of messaging mode
-#define NUM_COMM_ORDER_TYPES 6
+#define NUM_COMM_ORDER_TYPES 7
#define TYPE_SHIP_ITEM 0
#define TYPE_WING_ITEM 1
@@ -157,8 +157,8 @@
#define TYPE_REINFORCEMENT_ITEM 3
#define TYPE_REPAIR_REARM_ITEM 4
#define TYPE_REPAIR_REARM_ABORT_ITEM 5
+#define TYPE_SPECIAL_ITEM 6
-
char Comm_order_types[NUM_COMM_ORDER_TYPES][NAME_LENGTH];
comm_order Comm_orders[NUM_COMM_ORDER_ITEMS];
@@ -196,10 +196,38 @@
{ "Keep safe distance", -1, KEEP_SAFE_DIST_ITEM},
};
+
+custom_comm_item* Comm_special_menu = new custom_comm_item("Special"); //the master item that will appear in the comm menu
+//DUMMY ITEMS FOR TESTING ONLY - CommanderDJ
+custom_comm_item* Item1 = new custom_comm_item("Item1");
+custom_comm_item* Item2 = new custom_comm_item("Item2");
+custom_comm_item* Item3 = new custom_comm_item("Item3");
+
+custom_comm_item* Item1A = new custom_comm_item("Item1A");
+custom_comm_item* Item1B = new custom_comm_item("Item1B");
+
+custom_comm_item* Item2A = new custom_comm_item("Item2A");
+custom_comm_item* Item2B = new custom_comm_item("Item2B");
+
+custom_comm_item* Item3A = new custom_comm_item("Item3A");
+
void hud_init_comm_orders()
{
int i;
+ //DUMMY ITEMS FOR TESTING ONLY - CommanderDJ
+ Comm_special_menu->children.push_back(Item1);
+ Comm_special_menu->children.push_back(Item2);
+ Comm_special_menu->children.push_back(Item3);
+
+ Item1->children.push_back(Item1A);
+ Item1A->children.push_back(Item1B);
+
+ Item2->children.push_back(Item2A);
+ Item2A->children.push_back(Item2B);
+
+ Item3->children.push_back(Item3A);
+
char *temp_comm_order_types[] =
{
XSTR("Ships", 293),
@@ -207,7 +235,8 @@
XSTR("All Fighters", 295),
XSTR("Reinforcements", 296),
XSTR("Rearm/Repair Subsys", 297),
- XSTR("Abort Rearm", 298)
+ XSTR("Abort Rearm", 298),
+ XSTR(const_cast<char*>(Comm_special_menu->name.c_str()), -1)
};
for (i = 0; i < NUM_COMM_ORDER_TYPES; i++)
@@ -1640,6 +1669,7 @@
MsgItems[TYPE_REPAIR_REARM_ITEM].active = 1; // this item will always be available (I think)
MsgItems[TYPE_REPAIR_REARM_ABORT_ITEM].active = 0;
+
// AL: 10/13/97
// If the player ship communications are severely damaged, then the player
// will only be able to call for repair/rearm ships
@@ -1679,6 +1709,11 @@
}
}
+ // only make special choices available if we have some to select
+ if(Comm_special_menu->children.empty()) {
+ MsgItems[TYPE_SPECIAL_ITEM].active = 0;
+ }
+
// if using keyboard shortcut, these items are always inactive
if ( Msg_shortcut_command != -1 ) {
MsgItems[TYPE_REPAIR_REARM_ITEM].active = 0;
@@ -1707,6 +1742,8 @@
hud_squadmsg_do_mode( SM_MODE_REPAIR_REARM );
} else if ( k == TYPE_REPAIR_REARM_ABORT_ITEM ) {
hud_squadmsg_do_mode( SM_MODE_REPAIR_REARM_ABORT );
+ } else if ( k == TYPE_SPECIAL_ITEM ) {
+ hud_squadmsg_do_mode( SM_MODE_SPECIAL_SELECT );
}
}
}
@@ -2099,7 +2136,39 @@
}
+void hud_squadmsg_special_select(const custom_comm_item& special_menu)
+{
+ if ( Num_menu_items == -1 ) {
+ Num_menu_items = 0;
+ for(SCP_vector<custom_comm_item*>::const_iterator iter = special_menu.children.begin(); iter != special_menu.children.end(); ++iter)
+ {
+
+ Assert ( Num_menu_items < MAX_MENU_ITEMS );
+ strcpy_s( MsgItems[Num_menu_items].text, (*iter)->name.c_str() ); //what happens if name.size is greater than 32 characters? Rectify before final patch.
+ end_string_at_first_hash_symbol(MsgItems[Num_menu_items].text); // truncate the name if it has a # in it
+ //MsgItems[Num_menu_items].instance =
+ //What do we do with instance in this case? It's not a ship or wing.
+ MsgItems[Num_menu_items].active = 1;
+ Num_menu_items++;
+ }
+ }
+ strcpy_s(Squad_msg_title, XSTR( "Message What", 316));
+ int k = hud_squadmsg_get_key();
+ if(k != -1)
+ {
+ //There will later be code here for what happens when an item is "sent" (ie it has no children).
+ //For now, we just check if it has children and recurse to display them.
+ if(!special_menu.children.at(k)->children.empty())
+ {
+ Num_menu_items = -1; //Reset this for the next iteration - though it might be better to just remove the if check?
+ hud_squadmsg_special_select(*special_menu.children.at(k));
+ }
+ }
+
+}
+
+
//----------------------------------------------------------
// external entry points below!!!!
@@ -2356,6 +2425,10 @@
hud_squadmsg_msg_all_fighters();
break;
+ case SM_MODE_SPECIAL_SELECT:
+ hud_squadmsg_special_select(*Comm_special_menu);
+ break;
+
default:
Int3(); // get allender -- invalid mode in messaging system
break;
Index: code/hud/hudsquadmsg.h
===================================================================
--- code/hud/hudsquadmsg.h (revision 9699)
+++ code/hud/hudsquadmsg.h (working copy)
@@ -18,12 +18,13 @@
#define SM_MODE_TYPE_SELECT 1 //am I going to message a ship or a wing
#define SM_MODE_SHIP_SELECT 2 //choosing actual ship
#define SM_MODE_WING_SELECT 3 //choosing actual wing
-#define SM_MODE_SHIP_COMMAND 4 //which command to send to a ship
-#define SM_MODE_WING_COMMAND 5 //which command to send to a wing
+#define SM_MODE_SHIP_COMMAND 4 //which command to send to a ship
+#define SM_MODE_WING_COMMAND 5 //which command to send to a wing
#define SM_MODE_REINFORCEMENTS 6 //call for reinforcements
-#define SM_MODE_REPAIR_REARM 7 //repair/rearm player ship
+#define SM_MODE_REPAIR_REARM 7 //repair/rearm player ship
#define SM_MODE_REPAIR_REARM_ABORT 8 //abort repair/rearm of player ship
-#define SM_MODE_ALL_FIGHTERS 9 //message all fighters/bombers
+#define SM_MODE_ALL_FIGHTERS 9 //message all fighters/bombers
+#define SM_MODE_SPECIAL_SELECT 10 //choosing a special item
// define for trapping messages send to "all fighters"
#define MESSAGE_ALL_FIGHTERS -999
@@ -76,6 +77,22 @@
extern comm_order Comm_orders[];
extern sexp_com_order Sexp_comm_orders[];
+#define CCIF_ENABLED (1<<0)
+
+class custom_comm_item {
+public:
+ custom_comm_item() : name(), children(), sexp_variable_index(-1), trigger_value(0), flags(0) {}
+ custom_comm_item(const SCP_string& name) : name(name), children(), sexp_variable_index(-1), trigger_value(0), flags(0) {}
+
+ SCP_string name;
+ SCP_vector<custom_comm_item*> children;
+ int sexp_variable_index; //index into Sexp_variables[], a variable will be linked to the comm item
+ int trigger_value; //the value the variable is set to when the comm item is selected
+ int flags;
+
+};
+
+
// following defines are the set of possible commands that can be given to a ship. A mission designer
// might not allow some messages