Index: code/object/objcollide.cpp
===================================================================
--- code/object/objcollide.cpp	(revision 11167)
+++ code/object/objcollide.cpp	(working copy)
@@ -668,15 +668,16 @@
 //			is useful if a moving object wants to prevent a collision.
 int objects_will_collide(object *A, object *B, float duration, float radius_scale)
 {
-	object	A_future;
+	vec3d	prev_pos;
 	vec3d	hitpos;
+	int ret;
 
 
-	A_future = *A;
-	vm_vec_scale_add2(&A_future.pos, &A->phys_info.vel, duration);
+	prev_pos = A->pos;
+	vm_vec_scale_add2(&A->pos, &A->phys_info.vel, duration);
 
 	if (radius_scale == 0.0f) {
-		return ship_check_collision_fast(B, &A_future, &hitpos );
+		ret = ship_check_collision_fast(B, A, &hitpos);
 	} else {
 		float		size_A, size_B, dist, r;
 		vec3d	nearest_point;
@@ -686,18 +687,23 @@
 
 		//	If A is moving, check along vector.
 		if (A->phys_info.speed != 0.0f) {
-			r = find_nearest_point_on_line(&nearest_point, &A->pos, &A_future.pos, &B->pos);
+			r = find_nearest_point_on_line(&nearest_point, &prev_pos, &A->pos, &B->pos);
 			if (r < 0) {
+				nearest_point = prev_pos;
+			} else if (r > 1) {
 				nearest_point = A->pos;
-			} else if (r > 1) {
-				nearest_point = A_future.pos;
 			}
 			dist = vm_vec_dist_quick(&B->pos, &nearest_point);
-			return (dist < size_A + size_B);
+			ret = (dist < size_A + size_B);
 		} else {
-			return vm_vec_dist_quick(&B->pos, &A->pos) < size_A + size_B;
+			ret = vm_vec_dist_quick(&B->pos, &prev_pos) < size_A + size_B;
 		}
 	}
+
+	// Reset the position to the previous value
+	A->pos = prev_pos;
+
+	return ret;
 }
 
 //	Return true if the vector from *start_pos to *end_pos is within objp->radius*radius_scale of *objp
Index: code/object/object.cpp
===================================================================
--- code/object/object.cpp	(revision 11167)
+++ code/object/object.cpp	(working copy)
@@ -107,6 +107,36 @@
 	{OF_COLLIDES,				"collides",					1,  },
 };
 
+static dock_instance* copy_dock_list(dock_instance* other)
+{
+	dock_instance* ret = NULL;
+	dock_instance* current = NULL;
+
+	while (other != NULL)
+	{
+		// create item
+		dock_instance* item = (dock_instance *)vm_malloc(sizeof(dock_instance));
+		item->dockpoint_used = other->dockpoint_used;
+		item->docked_objp = other->docked_objp;
+		item->next = NULL;
+
+		if (ret == NULL)
+		{
+			ret = item;
+		}
+		if (current != NULL)
+		{
+			current->next = item;
+		}
+
+		current = item;
+
+		other = other->next;
+	}
+
+	return ret;
+}
+
 // all we need to set are the pointers, but type, parent, and instance are useful to set as well
 object::object()
 	: next(NULL), prev(NULL), type(OBJ_NONE), parent(-1), instance(-1), n_quadrants(0), hull_strength(0.0),
@@ -115,6 +145,48 @@
 	memset(&(this->phys_info), 0, sizeof(physics_info));
 }
 
+object::object(const object& other)
+	: next(NULL), prev(NULL), type(other.type), parent(other.parent), instance(other.instance), n_quadrants(other.n_quadrants),
+	hull_strength(other.hull_strength), sim_hull_strength(other.sim_hull_strength), net_signature(other.net_signature),
+	num_pairs(other.num_pairs), dock_list(NULL), dead_dock_list(NULL), collision_group_id(other.collision_group_id),
+	phys_info(other.phys_info)
+{
+	dock_list = copy_dock_list(other.dock_list);
+	dead_dock_list = copy_dock_list(other.dead_dock_list);
+}
+
+object& object::operator=(const object& other)
+{
+	if (this != &other) // protect against invalid self-assignment
+	{
+		// Free the old dock lists
+		dock_free_dock_list(this);
+		dock_free_dead_dock_list(this);
+
+		next = NULL;
+		prev = NULL;
+		type = other.type;
+		parent = other.parent;
+		instance = other.instance;
+		n_quadrants = other.n_quadrants;
+		hull_strength = other.hull_strength;
+		sim_hull_strength = other.sim_hull_strength;
+		net_signature = other.net_signature;
+		num_pairs = other.num_pairs;
+		dock_list = NULL;
+		dead_dock_list = NULL;
+		collision_group_id = other.collision_group_id;
+		phys_info = other.phys_info;
+
+		// And allocate the new ones
+		dock_list = copy_dock_list(other.dock_list);
+		dead_dock_list = copy_dock_list(other.dead_dock_list);
+	}
+
+	// by convention, always return *this
+	return *this;
+}
+
 object::~object()
 {
 	objsnd_num.clear();
Index: code/object/object.h
===================================================================
--- code/object/object.h	(revision 11167)
+++ code/object/object.h	(working copy)
@@ -168,6 +168,10 @@
 	int				collision_group_id; // This is a bitfield. Collision checks will be skipped if A->collision_group_id & B->collision_group_id returns nonzero
 
 	object();
+	object(const object& other);
+	
+	object& operator= (const object & other);
+
 	~object();
 	void clear();
 };
