void ShipModulesControllerSystem::drop(Entity* p_parent, unsigned int p_slot)
{
	if (p_slot < 0)
		return;
	//Module is dropped based on damage it sustains
	ConnectionPointSet* connected = static_cast<ConnectionPointSet*>(
		p_parent->getComponent(ComponentType::ConnectionPointSet) );

	Entity* toDrop = m_world->getEntity(connected->m_connectionPoints[p_slot].cpConnectedEntity);

	ShipModule* m = static_cast<ShipModule*>(toDrop->getComponent(ComponentType::ShipModule));

	NetworkSynced* networkSynced = static_cast<NetworkSynced*>(
		toDrop->getComponent(ComponentType::NetworkSynced));

	ConnectionPointSet* toDropConnected =
		static_cast<ConnectionPointSet*>(
		m_world->getComponentManager()->getComponent(toDrop,
		ComponentType::getTypeFor(ComponentType::ConnectionPointSet)));

	if (toDropConnected)
	{
		for (unsigned int i = 0; i < toDropConnected->m_connectionPoints.size(); i++)
		{
			int e = toDropConnected->m_connectionPoints[i].cpConnectedEntity;
			if (e >= 0 && m->m_parentEntity != e)
				drop(toDrop, i);
			else if (m->m_parentEntity == e)
			{
				toDropConnected->m_connectionPoints[i].cpConnectedEntity = -1;
			}
		}
	}

	//Perform the drop
	connected->m_connectionPoints[p_slot].cpConnectedEntity = -1;
	m->m_parentEntity = -1;
	PhysicsBody* b = static_cast<PhysicsBody*>(toDrop->getComponent(ComponentType::PhysicsBody));
	PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));

	Body* body = ps->getController()->getBody(b->m_id);
	ps->getController()->DetachBodyFromCompound((RigidBody*)body);
	b->setParentId(-1);

	// ===========================
	//     Update module data
	// ===========================
	m->m_health = m->getMaxHealth();
	m->m_value = ModuleHelper::changeModuleValueOnDetach(m->m_value);
	m->deactivate();
	m->m_lastShipEntityWhenAttached = -1; 

	// send status effect updates
	updateModuleHealthEffect(networkSynced->getNetworkOwner(),
							 m->m_health/m->getMaxHealth());
	updateModuleValueEffect(networkSynced->getNetworkOwner(),
							 m->m_value/m->getMaxValue());

	//Change particle effects on slots
	if (true) //m_editMode
	{
		Entity* parentShip = p_parent;
		ShipModule* parentModule = static_cast<ShipModule*>(parentShip->getComponent(ComponentType::ShipModule));
		Entity* firstChild = toDrop;
		while (parentModule)
		{
			firstChild = parentShip;
			parentShip = m_world->getEntity(parentModule->m_parentEntity);
			parentModule = static_cast<ShipModule*>(parentShip->getComponent(ComponentType::ShipModule));
		}

		int shipSlot = -1;
		if (firstChild == toDrop)
			shipSlot = p_slot;
		else
		{
			ConnectionPointSet* shipcps = static_cast<ConnectionPointSet*>(
				m_world->getComponentManager()->getComponent(parentShip,
				ComponentType::getTypeFor(ComponentType::ConnectionPointSet)));
			for (unsigned int i = 0; i < shipcps->m_connectionPoints.size(); i++)
			{
				if (shipcps->m_connectionPoints[i].cpConnectedEntity == firstChild->getIndex())
				{
					shipSlot = i;
					break;
				}
			}
		}

		NetworkSynced* parentNetworkSynced = static_cast<NetworkSynced*>(
			p_parent->getComponent(ComponentType::NetworkSynced));
		NetworkSynced* shipNetworkSynced = static_cast<NetworkSynced*>(
			parentShip->getComponent(ComponentType::NetworkSynced));

		//Remove particle effects from the slot
		for (unsigned int i = 0; i < toDropConnected->m_connectionPoints.size(); i++)
		{
			if (toDropConnected->m_connectionPoints[i].cpConnectedEntity < 0)
			{
				SlotParticleEffectPacket slotPacket;
				slotPacket.translationOffset = AglVector3(0, 0, 0);
				slotPacket.forwardDirection = AglVector3(0, 0, 0);
				slotPacket.slot = i;
				slotPacket.networkIdentity = networkSynced->getNetworkIdentity();
				slotPacket.active = false;
				slotPacket.inEditMode = m_editMode;
				m_server->unicastPacket(slotPacket.pack(), shipNetworkSynced->getNetworkOwner() );
			}
		}

		//Add back the parent slot
		SlotParticleEffectPacket slotPacket;
		slotPacket.translationOffset = connected->m_connectionPoints[p_slot].cpTransform.GetTranslation();
		slotPacket.forwardDirection = connected->m_connectionPoints[p_slot].cpTransform.GetForward();
		slotPacket.slot = p_slot;
		slotPacket.networkIdentity = parentNetworkSynced->getNetworkIdentity();
		slotPacket.active = true;
		slotPacket.inEditMode = m_editMode;
		slotPacket.moduleType = networkSynced->getNetworkType();
		slotPacket.shipSlot = shipSlot;
		m_server->unicastPacket(slotPacket.pack(), shipNetworkSynced->getNetworkOwner() );

		//Send a packet back to the client telling him how the edit sphere should be oriented
		ShipManagerSystem* sms = static_cast<ShipManagerSystem*>(m_world->getSystem(SystemType::ShipManagerSystem));
		EditSphereUpdatePacket editSphereUpdate;
		AglBoundingSphere bs = sms->findEditSphere(shipNetworkSynced->getNetworkOwner());
		editSphereUpdate.m_offset = bs.position;
		editSphereUpdate.m_radius = bs.radius;
		m_server->unicastPacket(editSphereUpdate.pack(), shipNetworkSynced->getNetworkOwner());
	}
}