diff --git a/code/missionui/redalert.cpp b/code/missionui/redalert.cpp
index 397f393..4a26646 100644
--- a/code/missionui/redalert.cpp
+++ b/code/missionui/redalert.cpp
@@ -500,7 +500,7 @@ void red_alert_bash_weapons(red_alert_ship_status *ras, ship_weapon *swp)
 	int i, list_size = 0;
 
 	// restore from ship_exited
-	if (ras->ship_class == RED_ALERT_EXITED_SHIP_CLASS) {
+	if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) {
 		return;
 	}
 
@@ -534,7 +534,7 @@ void red_alert_bash_subsys_status(red_alert_ship_status *ras, ship *shipp)
 	int list_size;
 
 	// restore from ship_exited
-	if (ras->ship_class == RED_ALERT_EXITED_SHIP_CLASS) {
+	if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) {
 		return;
 	}
 
@@ -637,8 +637,11 @@ void red_alert_store_wingman_status()
 			ras.hull = float(Ships_exited[idx].hull_strength);
 
 			// if a ship has been destroyed or removed manually by the player, then mark it as such ...
-			if ( (Ships_exited[idx].flags & SEF_DESTROYED) || (Ships_exited[idx].flags & SEF_PLAYER_DELETED) ) {
-				ras.ship_class = RED_ALERT_EXITED_SHIP_CLASS;
+			if ( Ships_exited[idx].flags & SEF_DESTROYED ) {
+				ras.ship_class = RED_ALERT_DESTROYED_SHIP_CLASS;
+			}
+			else if (Ships_exited[idx].flags & SEF_PLAYER_DELETED) {
+				ras.ship_class = RED_ALERT_PLAYER_DEL_SHIP_CLASS;
 			}
 			// ... otherwise we want to make sure and carry over the ship class
 			else {
@@ -659,10 +662,16 @@ void red_alert_store_wingman_status()
 }
 
 // Delete a ship in a red alert mission (since it must have died/departed in the previous mission)
-void red_alert_delete_ship(ship *shipp)
+void red_alert_delete_ship(ship *shipp, int ship_state)
 {
 	if ( (shipp->wing_status_wing_index >= 0) && (shipp->wing_status_wing_pos >= 0) ) {
-		hud_set_wingman_status_dead(shipp->wing_status_wing_index, shipp->wing_status_wing_pos);
+		if (ship_state == RED_ALERT_DESTROYED_SHIP_CLASS) {
+			hud_set_wingman_status_dead(shipp->wing_status_wing_index, shipp->wing_status_wing_pos);
+		} else if (ship_state == RED_ALERT_PLAYER_DEL_SHIP_CLASS) {
+			hud_set_wingman_status_none(shipp->wing_status_wing_index, shipp->wing_status_wing_pos);
+		} else {
+			Error(LOCATION, "Red Alert: asked to delete ship (%s) with invalid ship state (%d)", shipp->ship_name, ship_state);
+		}
 	}
 
 	ship_add_exited_ship( shipp, SEF_PLAYER_DELETED );
@@ -692,6 +701,7 @@ void red_alert_bash_wingman_status()
 	// go through all ships in the game, and see if there is red alert status data for any
 
 	int remove_list[MAX_SHIPS];
+	int remove_state[MAX_SHIPS];
 	int remove_count = 0;
 
 	for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
@@ -704,12 +714,13 @@ void red_alert_bash_wingman_status()
 		}
 
 		int found_match = 0;
+		int ship_state = 0;
 
 		for ( i = 0; i < (int)Red_alert_wingman_status.size(); i++ ) {
 			ras = &Red_alert_wingman_status[i];
 
-			// we only want to restore ships which haven't been destroyed (which the RED_ALERT_EXITED_SHIP_CLASS identifies)
-			if ( !stricmp(ras->name.c_str(), shipp->ship_name) && (ras->ship_class != RED_ALERT_EXITED_SHIP_CLASS) ) {
+			// we only want to restore ships which haven't been destroyed, or were removed by the player
+			if ( !stricmp(ras->name.c_str(), shipp->ship_name) && (ras->ship_class != RED_ALERT_DESTROYED_SHIP_CLASS) && (ras->ship_class != RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) {
 				found_match = 1;
 
 				// if necessary, restore correct ship class
@@ -728,10 +739,15 @@ void red_alert_bash_wingman_status()
 				}
 				red_alert_bash_weapons(ras, &shipp->weapons);
 				red_alert_bash_subsys_status(ras, shipp);
+
+			} else if ( !stricmp(ras->name.c_str(), shipp->ship_name) && ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) ) {
+				ship_state = ras->ship_class;
+				continue;
 			}
 		}
 
 		if ( !found_match ) {
+			remove_state[remove_count] = ship_state;
 			remove_list[remove_count++] = SHIP_INDEX(shipp);
 		}
 	}
@@ -739,7 +755,7 @@ void red_alert_bash_wingman_status()
 	// remove ships
 	for ( i = 0; i < remove_count; i++ ) {
 		// remove ship
-		red_alert_delete_ship(&Ships[remove_list[i]]);
+		red_alert_delete_ship(&Ships[remove_list[i]], remove_state[i]);
 	}
 }
 
diff --git a/code/missionui/redalert.h b/code/missionui/redalert.h
index 81a365d..9a330c2 100644
--- a/code/missionui/redalert.h
+++ b/code/missionui/redalert.h
@@ -37,7 +37,9 @@ void red_alert_voice_unpause();
 
 #define RED_ALERT_WARN_TIME		4000				// time to warn user that new orders are coming
 
-#define RED_ALERT_EXITED_SHIP_CLASS		-1
+static const int RED_ALERT_DESTROYED_SHIP_CLASS = -1;
+static const int RED_ALERT_PLAYER_DEL_SHIP_CLASS = -2;
+static const int RED_ALERT_LOWEST_VALID_SHIP_CLASS = RED_ALERT_PLAYER_DEL_SHIP_CLASS;  // for ship index bounds checks
 
 typedef struct red_alert_ship_status {
 	SCP_string	name;
diff --git a/code/pilotfile/csg.cpp b/code/pilotfile/csg.cpp
index 0df7f21..7d58a4c 100644
--- a/code/pilotfile/csg.cpp
+++ b/code/pilotfile/csg.cpp
@@ -800,10 +800,10 @@ void pilotfile::csg_read_redalert()
 
 		// ship class, index into ship_list[]
 		i = cfread_int(cfp);
-		if ( (i >= (int)ship_list.size()) || (i < -1) ) {
+		if ( (i >= (int)ship_list.size()) || (i < RED_ALERT_LOWEST_VALID_SHIP_CLASS) ) {
 			mprintf(("CSG => Parse Warning: Invalid value for red alert ship index (%d), emptying slot.\n", i));
-			ras.ship_class = -1;
-		} else if ( i == -1 ) {  // ship destroyed/exited
+			ras.ship_class = RED_ALERT_DESTROYED_SHIP_CLASS;
+		} else if ( (i < 0 ) && (i >= RED_ALERT_LOWEST_VALID_SHIP_CLASS) ) {  // ship destroyed/exited
 			ras.ship_class = i;
 		} else {
 			ras.ship_class = ship_list[i].index;
@@ -858,7 +858,7 @@ void pilotfile::csg_read_redalert()
 		}
 
 		// this is quite likely a *bad* thing if it doesn't happen
-		if (ras.ship_class >= RED_ALERT_EXITED_SHIP_CLASS) {
+		if (ras.ship_class >= RED_ALERT_LOWEST_VALID_SHIP_CLASS) {
 			Red_alert_wingman_status.push_back( ras );
 		}
 	}
