Index: code/ai/aiturret.cpp
===================================================================
--- code/ai/aiturret.cpp	(revision 10966)
+++ code/ai/aiturret.cpp	(working copy)
@@ -479,7 +479,7 @@
 		}
 
 		// don't shoot at ships without collision check
-		if (sip->flags & SIF_NO_COLLIDE) {
+		if (!(objp->flags & OF_COLLIDES)) {
 			return 0;
 		}
 
Index: code/fred2/fred.rc
===================================================================
--- code/fred2/fred.rc	(revision 10966)
+++ code/fred2/fred.rc	(working copy)
@@ -1837,6 +1837,7 @@
     CONTROL         "Does Not Move",IDC_IMMOBILE,"Button",BS_3STATE | WS_TABSTOP,7,274,66,10
     CONTROL         "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
     CONTROL         "Scramble Messages",IDC_SCRAMBLE_MESSAGES,"Button",BS_3STATE | WS_TABSTOP,165,177,79,10
+    CONTROL         "No Collisions",IDC_NO_COLLIDE,"Button",BS_3STATE | WS_TABSTOP,165,188,66,10
 END
 
 IDD_ADD_VARIABLE DIALOG  0, 0, 422, 102
Index: code/fred2/missionsave.cpp
===================================================================
--- code/fred2/missionsave.cpp	(revision 10966)
+++ code/fred2/missionsave.cpp	(working copy)
@@ -1742,6 +1742,8 @@
 				fout(" \"weapons-locked\"");
 			if (shipp->flags2 & SF2_SCRAMBLE_MESSAGES)
 				fout(" \"scramble-messages\"");
+			if (!(objp->flags & OF_COLLIDES))
+				fout(" \"no-collide\"");
 			fout(" )");
 		}
 		// -----------------------------------------------------------
Index: code/fred2/resource.h
===================================================================
--- code/fred2/resource.h	(revision 10966)
+++ code/fred2/resource.h	(working copy)
@@ -1179,6 +1179,7 @@
 #define IDC_MISSION_LOG_LAST_REPEAT     1640
 #define IDC_MISSION_LOG_1ST_TRIGGER     1641
 #define IDC_MISSION_LOG_LAST_TRIGGER    1642
+#define IDC_NO_COLLIDE                  1643
 #define ID_FILE_MISSIONNOTES            32771
 #define ID_DUPLICATE                    32774
 #define ID_VIEW_ROTATE                  32775
@@ -1471,7 +1472,7 @@
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        320
 #define _APS_NEXT_COMMAND_VALUE         33098
-#define _APS_NEXT_CONTROL_VALUE         1643
+#define _APS_NEXT_CONTROL_VALUE         1644
 #define _APS_NEXT_SYMED_VALUE           105
 #endif
 #endif
Index: code/fred2/shipflagsdlg.cpp
===================================================================
--- code/fred2/shipflagsdlg.cpp	(revision 10966)
+++ code/fred2/shipflagsdlg.cpp	(working copy)
@@ -74,6 +74,7 @@
 	DDX_Control(pDX, IDC_HIDE_SHIP_NAME, m_hide_ship_name);
 	DDX_Control(pDX, IDC_DISABLE_ETS, m_disable_ets);
 	DDX_Control(pDX, IDC_CLOAKED, m_cloaked);
+	DDX_Control(pDX, IDC_NO_COLLIDE, m_no_collide);
 	DDX_Control(pDX, IDC_SET_CLASS_DYNAMICALLY, m_set_class_dynamically);
 	DDX_Control(pDX, IDC_SCRAMBLE_MESSAGES, m_scramble_messages);
 	//}}AFX_DATA_MAP
@@ -140,6 +141,7 @@
 	ON_BN_CLICKED(IDC_DISABLE_ETS, OnDisableETS)
 	ON_BN_CLICKED(IDC_CLOAKED, OnCloaked)
 	ON_BN_CLICKED(IDC_SCRAMBLE_MESSAGES, OnScrambleMessages)
+	ON_BN_CLICKED(IDC_NO_COLLIDE, OnNoCollide)
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -161,7 +163,7 @@
 	int toggle_subsystem_scanning = 0, scannable = 0, kamikaze = 0, no_dynamic = 0, red_alert_carry = 0;
 	int special_warpin = 0, disable_messages = 0, guardian = 0, vaporize = 0, stealth = 0, friendly_stealth_invisible = 0;
 	int no_death_scream = 0, always_death_scream = 0, scramble_messages = 0;
-	int nav_carry = 0, nav_needslink = 0, hide_ship_name = 0, set_class_dynamically = 0, no_ets = 0, cloaked = 0;
+	int nav_carry = 0, nav_needslink = 0, hide_ship_name = 0, set_class_dynamically = 0, no_ets = 0, cloaked = 0, no_collide = 0;
 
 	object *objp;
 	ship *shipp;
@@ -210,6 +212,7 @@
 					no_ets = (shipp->flags2 & SF2_NO_ETS) ? 1 : 0;
 					cloaked = (shipp->flags2 & SF2_CLOAKED) ? 1 : 0;
 					scramble_messages = (shipp->flags2 & SF2_SCRAMBLE_MESSAGES) ? 1 : 0;
+					no_collide = (objp->flags & OF_COLLIDES) ? 0 : 1;
 
 					destroy_before_mission = (shipp->flags & SF_KILL_BEFORE_MISSION) ? 1 : 0;
 					m_destroy_value.init(shipp->final_death_time);
@@ -270,6 +273,7 @@
 					no_ets = tristate_set(shipp->flags2 & SF2_NO_ETS, no_ets);
 					cloaked = tristate_set(shipp->flags2 & SF2_CLOAKED, cloaked);
 					scramble_messages = tristate_set(shipp->flags2 & SF2_SCRAMBLE_MESSAGES, scramble_messages);
+					no_collide = tristate_set(!(objp->flags & OF_COLLIDES), no_collide);
 
 					// check the final death time and set the internal variable according to whether or not
 					// the final_death_time is set.  Also, the value in the edit box must be set if all the
@@ -344,6 +348,7 @@
 	m_disable_ets.SetCheck(no_ets);
 	m_cloaked.SetCheck(cloaked);
 	m_scramble_messages.SetCheck(scramble_messages);
+	m_no_collide.SetCheck(no_collide);
 		
 	m_kdamage.setup(IDC_KDAMAGE, this);
 	m_destroy_value.setup(IDC_DESTROY_VALUE, this);
@@ -961,6 +966,22 @@
 			break;
 	}
 
+	switch (m_no_collide.GetCheck()) {
+		case 1:
+			if ( objp->flags & OF_COLLIDES )
+				set_modified();
+
+			objp->flags &= ~OF_COLLIDES;
+			break;
+
+		case 0:
+			if (!(objp->flags & OF_COLLIDES))
+				set_modified();
+
+			objp->flags |= OF_COLLIDES;
+			break;
+	}
+
 	switch (m_guardian.GetCheck()) {
 		case 1:
 			if ( !(shipp->ship_guardian_threshold) )
@@ -1410,3 +1431,12 @@
 		m_scramble_messages.SetCheck(1);
 	}
 }
+
+void ship_flags_dlg::OnNoCollide()
+{
+	if (m_no_collide.GetCheck() == 1) {
+		m_no_collide.SetCheck(0);
+	} else {
+		m_no_collide.SetCheck(1);
+	}
+}
Index: code/fred2/shipflagsdlg.h
===================================================================
--- code/fred2/shipflagsdlg.h	(revision 10966)
+++ code/fred2/shipflagsdlg.h	(working copy)
@@ -65,6 +65,7 @@
 	CButton m_hide_ship_name;
 	CButton m_disable_ets;
 	CButton m_cloaked;
+	CButton m_no_collide;
 	CButton	m_set_class_dynamically;
 	CButton	m_scramble_messages;
 
@@ -126,6 +127,7 @@
 	afx_msg void OnDisableETS();
 	afx_msg void OnCloaked();
 	afx_msg void OnScrambleMessages();
+	afx_msg void OnNoCollide();
 	//}}AFX_MSG
 	DECLARE_MESSAGE_MAP()
 };
Index: code/mission/missionparse.cpp
===================================================================
--- code/mission/missionparse.cpp	(revision 10966)
+++ code/mission/missionparse.cpp	(working copy)
@@ -311,6 +311,7 @@
 	"ship-locked",
 	"weapons-locked",
 	"scramble-messages",
+	"no-collide",
 };
 
 char *Mission_event_log_flags[MAX_MISSION_EVENT_LOG_FLAGS] = {
@@ -2582,6 +2583,12 @@
 
 	if (parse_flags2 & P2_SF2_SCRAMBLE_MESSAGES)
 		shipp->flags2 |= SF2_SCRAMBLE_MESSAGES;
+
+	// Make sure that the correct flag is set in any case
+	if (parse_flags2 & P2_OF_NO_COLLIDE)
+		obj_set_flags(objp, objp->flags & ~OF_COLLIDES);
+	else
+		obj_set_flags(objp, objp->flags | OF_COLLIDES);
 }
 
 void fix_old_special_explosions(p_object *p_objp, int variable_index) 
Index: code/mission/missionparse.h
===================================================================
--- code/mission/missionparse.h	(revision 10966)
+++ code/mission/missionparse.h	(working copy)
@@ -487,7 +487,7 @@
 // same caveat: This list of bitfield indicators MUST correspond EXACTLY
 // (i.e., order and position must be the same) to its counterpart in MissionParse.cpp!!!!
 
-#define MAX_PARSE_OBJECT_FLAGS_2	23
+#define MAX_PARSE_OBJECT_FLAGS_2	24
 
 #define P2_SF2_PRIMITIVE_SENSORS			(1<<0)
 #define P2_SF2_NO_SUBSPACE_DRIVE			(1<<1)
@@ -512,6 +512,7 @@
 #define P2_SF2_SHIP_LOCKED					(1<<20)
 #define P2_SF2_WEAPONS_LOCKED				(1<<21)
 #define P2_SF2_SCRAMBLE_MESSAGES			(1<<22)
+#define P2_OF_NO_COLLIDE					(1<<23) // This actually changes the OF_COLLIDES object flag
 
 // and again: these flags do not appear in the array
 //#define blah							(1<<28)
Index: code/object/collideshipship.cpp
===================================================================
--- code/object/collideshipship.cpp	(revision 10966)
+++ code/object/collideshipship.cpp	(working copy)
@@ -172,15 +172,6 @@
 		}
 	}
 
-	//	If either of these objects doesn't get collision checks, abort.
-	if (heavy_sip->flags & SIF_NO_COLLIDE) {
-		return 0;
-	}
-
-	if (light_sip->flags & SIF_NO_COLLIDE) {
-		return 0;
-	}
-
 	// Set up model_collide info
 	mc_info mc;
 	mc_info_init(&mc);
Index: code/object/collideshipweapon.cpp
===================================================================
--- code/object/collideshipweapon.cpp	(revision 10966)
+++ code/object/collideshipweapon.cpp	(working copy)
@@ -140,11 +140,7 @@
 
 	// Make ships that are warping in not get collision detection done
 	if ( shipp->flags & SF_ARRIVING ) return 0;
-
-	//	If either of these objects doesn't get collision checks, abort.
-	if (Ship_info[shipp->ship_info_index].flags & SIF_NO_COLLIDE)
-		return 0;
-
+	
 	//	Return information for AI to detect incoming fire.
 	//	Could perhaps be done elsewhere at lower cost --MK, 11/7/97
 	float	dist = vm_vec_dist_quick(&ship_objp->pos, &weapon_objp->pos);
Index: code/object/object.cpp
===================================================================
--- code/object/object.cpp	(revision 10966)
+++ code/object/object.cpp	(working copy)
@@ -104,6 +104,7 @@
 	{OF_LASER_PROTECTED,		"laser-protect-ship",		1,	},
 	{OF_MISSILE_PROTECTED,		"missile-protect-ship",		1,	},
 	{OF_IMMOBILE,				"immobile",					1,	},
+	{OF_COLLIDES,				"collides",					1,  },
 };
 
 // all we need to set are the pointers, but type, parent, and instance are useful to set as well
Index: code/object/object.h
===================================================================
--- code/object/object.h	(revision 10966)
+++ code/object/object.h	(working copy)
@@ -132,7 +132,7 @@
 	int flag_list;
 } obj_flag_name;
 
-#define MAX_OBJECT_FLAG_NAMES			9
+#define MAX_OBJECT_FLAG_NAMES			10
 extern obj_flag_name Object_flag_names[];
 
 struct dock_instance;
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp	(revision 10966)
+++ code/parse/sexp.cpp	(working copy)
@@ -12807,9 +12807,9 @@
 			{
 				// set or clear?
 				if (set_flag)
-					oswpt.objp->flags |= object_flag;
+					obj_set_flags(oswpt.objp, oswpt.objp->flags | object_flag);
 				else
-					oswpt.objp->flags &= ~object_flag;
+					obj_set_flags(oswpt.objp, oswpt.objp->flags & ~object_flag);
 			}
 
 			// handle ETS when modifying shields
Index: code/ship/ship.cpp
===================================================================
--- code/ship/ship.cpp	(revision 10966)
+++ code/ship/ship.cpp	(working copy)
@@ -5138,6 +5138,11 @@
 	if (sip->flags & SIF_SHIP_CLASS_DONT_COLLIDE_INVIS)
 		shipp->flags2 |= SF2_DONT_COLLIDE_INVIS;
 
+	if (sip->flags & SIF_NO_COLLIDE)
+		obj_set_flags(objp, objp->flags & ~OF_COLLIDES);
+	else
+		obj_set_flags(objp, objp->flags | OF_COLLIDES);
+
 	if (sip->flags2 & SIF2_NO_ETS)
 		shipp->flags2 |= SF2_NO_ETS;
 
@@ -9423,10 +9428,10 @@
 	else if (sip_orig->flags & SIF_SHIP_CLASS_DONT_COLLIDE_INVIS)	// changing FROM a don't-collide-invisible ship class
 		sp->flags2 &= ~SF2_DONT_COLLIDE_INVIS;
 
-	if (sip->flags & SIF_NO_COLLIDE)								// changing TO a no_collide ship
-		Objects[sp->objnum].flags &= ~OF_COLLIDES;
-	else if (sip_orig->flags & SIF_NO_COLLIDE)						// changing FROM a no_collide ship
-		Objects[sp->objnum].flags |= OF_COLLIDES;
+	if (sip->flags & SIF_NO_COLLIDE)								// changing TO a no-collision ship class
+		objp->flags &= ~OF_COLLIDES;
+	else if (sip_orig->flags & SIF_NO_COLLIDE)					// changing FROM a no-collision ship class
+		objp->flags |= OF_COLLIDES;
 
 	if (sip->flags2 & SIF2_NO_ETS)
 		sp->flags2 |= SF2_NO_ETS;
