Index: FS2Source-multieval/code/parse/sexp.cpp
===================================================================
--- FS2Source-multieval/code/parse/sexp.cpp	(revision 10927)
+++ FS2Source-multieval/code/parse/sexp.cpp	(working copy)
@@ -681,6 +681,7 @@
 	{ "damaged-escort-priority",		OP_DAMAGED_ESCORT_LIST,					3,	INT_MAX,	SEXP_ACTION_OPERATOR,	},	//phreak
 	{ "damaged-escort-priority-all",	OP_DAMAGED_ESCORT_LIST_ALL,				1,	MAX_COMPLETE_ESCORT_LIST,	SEXP_ACTION_OPERATOR,	},	// Goober5000
 	{ "set-support-ship",				OP_SET_SUPPORT_SHIP,					6,	7,			SEXP_ACTION_OPERATOR,	},	// Goober5000
+	{ "multi-eval",						OP_SCRIPT_EVAL_MULTI,					1,	INT_MAX,	SEXP_ACTION_OPERATOR,   },
 	{ "script-eval",					OP_SCRIPT_EVAL,							1,	INT_MAX,	SEXP_ACTION_OPERATOR,	},
 	{ "debug",							OP_DEBUG,								2,	2,			SEXP_ACTION_OPERATOR,	},	// Karajorma
 	{ "do-nothing",						OP_NOP,									0,	0,			SEXP_ACTION_OPERATOR,	},
@@ -21502,7 +21503,7 @@
 }
 
 //WMC - This is a bit of a hack, however, it's easier than
-//coding in a whole new SCript_system function.
+//coding in a whole new Script_system function.
 int sexp_script_eval(int node, int return_type)
 {
 	int n = node;
@@ -21575,6 +21576,102 @@
 	return -1;
 }
 
+void sexp_script_eval_multi(int node)
+ {
+	char s[TOKEN_LENGTH];
+	bool success = true;
+	int sindex;
+	player *p;
+	
+		strcpy_s(s, CTEXT(node));
+	
+		node = CDR(node);
+	
+		multi_start_callback();
+	multi_send_string(s);
+		// evalutate on all clients
+		if (node == -1) {
+		multi_send_bool(true);
+		success = Script_system.EvalString(s, NULL, NULL, s);
+		
+	}
+		// we have to send to all clients but we need to send a list of ships so that they know if they evaluate or not
+		else {
+		multi_send_bool(false);
+		
+			do {
+			p = get_player_from_ship_node(node, true);
+			
+							// not a player ship so skip it
+				if (p == NULL){
+				node = CDR(node);
+				continue;
+				
+			}
+			else {
+								// if this is me, execute the script
+					if (p == Player) {
+					success = Script_system.EvalString(s, NULL, NULL, s);
+					
+				}
+								// otherwise notify the clients
+					else {
+					sindex = ship_name_lookup(CTEXT(node));
+					multi_send_ship(sindex);
+					
+				}
+				
+			}
+			
+				node = CDR(node);
+			
+		} while (node != -1);
+		
+	}
+	
+		multi_end_callback();
+	
+		if (!success) {
+		Warning(LOCATION, "sexp-script-eval failed to evaluate string \"%s\"; check your syntax", s);
+		
+	}
+}
+
+void multi_sexp_script_eval_multi()
+ {
+	int sindex;
+	char s[TOKEN_LENGTH];
+	bool sent_to_all = false;
+	bool success = true;
+	
+		multi_get_string(s);
+	multi_get_bool(sent_to_all);
+	
+		if (sent_to_all) {
+		success = Script_system.EvalString(s, NULL, NULL, s);
+		
+	}
+		// go through all the ships that were sent and see if any of them match this client.
+		else {
+		while (multi_get_ship(sindex)) {
+			Assertion(sindex >= 0, "Illegal value for the ship index sent in multi_sexp_script_eval_multi()! Ship %d does not exist!", sindex);
+			if (Player->objnum == Ships[sindex].objnum) {
+				success = Script_system.EvalString(s, NULL, NULL, s);
+				
+			}
+			
+		}
+		
+	}
+	
+		if (!success) {
+		Warning(LOCATION, "sexp-script-eval failed to evaluate string \"%s\"; check your syntax", s);
+		
+	}
+	}
+
+
+
 void sexp_force_glide(int node)
 {
 	ship *shipp;
@@ -24263,6 +24360,11 @@
 				sexp_val = sexp_script_eval(node, OPR_NULL);
 				break;
 
+			case OP_SCRIPT_EVAL_MULTI:
+				sexp_script_eval_multi(node);
+				sexp_val = SEXP_TRUE;
+				break;
+
 			case OP_CHANGE_IFF_COLOR:
 				sexp_change_iff_color(node);
 				sexp_val = SEXP_TRUE;
@@ -24694,6 +24796,10 @@
 				multi_sexp_set_ets_values();
 				break;
 
+			case OP_SCRIPT_EVAL_MULTI:
+				multi_sexp_script_eval_multi();
+				break;
+
 			// bad sexp in the packet
 			default: 
 				// probably just a version error where the host supports a SEXP but a client does not
@@ -25296,6 +25402,7 @@
 		case OP_SET_NUM_COUNTERMEASURES:
 		case OP_SCRIPT_EVAL:
 		case OP_SCRIPT_EVAL_STRING:
+		case OP_SCRIPT_EVAL_MULTI:
 		case OP_ENABLE_BUILTIN_MESSAGES:
 		case OP_DISABLE_BUILTIN_MESSAGES:
 		case OP_LOCK_PRIMARY_WEAPON:
@@ -27342,6 +27449,12 @@
 			if (argnum == 1)return OPF_VARIABLE_NAME;
 			else return OPF_STRING;
 
+		case OP_SCRIPT_EVAL_MULTI:
+			if (argnum == 0)
+					return OPF_STRING;
+			else
+					return OPF_SHIP;
+
 		case OP_CHANGE_IFF_COLOR:
 			if ((argnum == 0) || (argnum == 1))
 				return OPF_IFF;
@@ -29119,6 +29232,7 @@
 		case OP_SET_SUPPORT_SHIP:
 		case OP_SCRIPT_EVAL_STRING:
 		case OP_SCRIPT_EVAL:
+		case OP_SCRIPT_EVAL_MULTI:
 			return CHANGE_SUBCATEGORY_OTHER;
 
 		case OP_NUM_SHIPS_IN_BATTLE:
@@ -32739,6 +32853,14 @@
 		"\t1:\tScript to evaluate\r\n"
 	},
 
+	{OP_SCRIPT_EVAL_MULTI, "multi-eval\r\n"
+	 "\tEvaluates script\r\n\r\n"
+	 "Takes at least 1 argument...\r\n"
+	 "\t1:\tScript to evaluate\r\n"
+	 "\t(rest):\tList of players who should evaluate this script. If no player is given, all clients will execute the script\r\n"
+	},
+	
+
 	{OP_FORCE_GLIDE, "force-glide\r\n"
 		"\tForces a given ship into glide mode, provided it is capable of gliding. Note that the player will not be able to leave glide mode on his own,, and that a ship in glide mode cannot warp out or enter autopilot."
 		"Takes 2 Arguments...\r\n"
Index: FS2Source-multieval/code/parse/sexp.h
===================================================================
--- FS2Source-multieval/code/parse/sexp.h	(revision 10927)
+++ FS2Source-multieval/code/parse/sexp.h	(working copy)
@@ -723,6 +723,7 @@
 #define OP_SET_MOTION_DEBRIS				(0x0025 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG)    // The E
 #define OP_HUD_SET_CUSTOM_GAUGE_ACTIVE		(0x0026 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) 	// The E, just revamped a bit by Axem
 #define OP_HUD_SET_RETAIL_GAUGE_ACTIVE		(0x0027 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG) 	// The E, just revamped a bit by Axem
+#define OP_SCRIPT_EVAL_MULTI				(0x0028 | OP_CATEGORY_CHANGE2 | OP_NONCAMPAIGN_FLAG)	// Karajorma
 
 // defined for AI goals
 #define OP_AI_CHASE							(0x0000 | OP_CATEGORY_AI | OP_NONCAMPAIGN_FLAG)
