bool CVehiclePartSuspensionPart::ChangeState(EVehiclePartState state, int flags)
{
	if (!inherited::ChangeState(state, flags))
		return false;

	// Remove the statobj from the cga joint (again)
	if (m_animatedRoot && m_jointId>=0)
	{
		ICharacterInstance* pCharInstance = m_animatedRoot->GetEntity()->GetCharacter(m_animatedRoot->GetSlot());
		if (pCharInstance)
		{
			ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose();
			pSkeletonPose->SetStatObjOnJoint(m_jointId, NULL);
		}
	}
	return true;
}
bool CVehiclePartSuspensionPart::Init(IVehicle *pVehicle, const CVehicleParams &table, IVehiclePart *pParent, CVehicle::SPartInitInfo &initInfo, int partType)
{
	if (!inherited::Init(pVehicle, table, pParent, initInfo, partType))
		return false;
	
	m_animatedRoot = CAST_VEHICLEOBJECT(CVehiclePartAnimated, GetParent(true));
	m_jointId = -1;
	m_ikFlags = 0;

	if (m_animatedRoot)
	{
		if(CVehicleParams subPartTable = table.findChild("SubPart"))
		{
			// We need to remove this part from the animated root, otherwise we have two parts
			// NB: for now we are not doing anything with the physics - infact its preferable
			// if we dont have physics on suspension arms!
			const char*	geoName = subPartTable.getAttr("geometryname");
			ICharacterInstance* pCharInstance = m_animatedRoot->GetEntity()->GetCharacter(m_animatedRoot->GetSlot());
			if (pCharInstance)
			{
				IDefaultSkeleton& rIDefaultSkeleton = pCharInstance->GetIDefaultSkeleton();
				ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose();
				m_jointId = rIDefaultSkeleton.GetJointIDByName(geoName);
				pSkeletonPose->SetStatObjOnJoint(m_jointId, NULL);
			}
		}
	}
	else
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: needs to have an AnimatedPart as a parent!");
		return false;
	}

	CVehicleParams ikTable = table.findChild("IK");
	if (!ikTable)
		return false;

	const char* targetPartName = ikTable.getAttr("target");
	m_targetPart = static_cast<CVehiclePartBase*>(pVehicle->GetPart(targetPartName));
	if (m_targetPart==NULL)
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: couldn't find target part: '%s'", targetPartName);
		return false;
	}

	// Set up the target
	m_targetOffset.zero();
	const char* targetHelper = ikTable.getAttr("targetHelper");
	if (targetHelper && targetHelper[0])
	{
		if (IVehicleHelper* pHelper = m_pVehicle->GetHelper(targetHelper))
		{
			// NB: this is in vehicle space, and needs translating in PostInit()
			m_targetOffset = pHelper->GetLocalTM().GetTranslation();
			m_ikFlags |= k_flagTargetHelper;
		}
	}
	Vec3 offset(0);
	ikTable.getAttr("offset", offset);
	m_targetOffset += offset;
	
	m_mode = k_modeStretch;
	const char* mode = ikTable.getAttr("mode");
	if (strcmp(mode,"rotate")==0)
		m_mode = k_modeRotate;
	if (strcmp(mode,"stretch")==0)
		m_mode = k_modeStretch;
	if (strcmp(mode,"snap")==0)
		m_mode = k_modeSnapToEF;
			
	bool bIgnoreTargetRotation=0;
	ikTable.getAttr("ignoreTargetRotation", bIgnoreTargetRotation);
	if (bIgnoreTargetRotation)
		m_ikFlags |= k_flagIgnoreTargetRotation;

	return true;
}