Example #1
0
//------------------------------------------------------------------------
bool CVehiclePartTread::Init(IVehicle* pVehicle, const CVehicleParams& table, IVehiclePart* parent, CVehicle::SPartInitInfo& initInfo, int partType)
{
	if (!CVehiclePartBase::Init(pVehicle, table, parent, initInfo, eVPT_Tread))
		return false;

	CVehicleParams subTable = table.findChild("Tread"); // Tread subtable
	if (!subTable)
		return false;

	string filename = subTable.getAttr("filename");
	if (filename.empty())
		return false;

	subTable.getAttr("uvSpeedMultiplier", m_uvSpeedMultiplier);

	if (table.haveAttr("component"))
	{
		if (CVehicleComponent* pComponent = static_cast<CVehicleComponent*>(m_pVehicle->GetComponent(table.getAttr("component"))))
			pComponent->AddPart(this);
	}

	m_slot = GetEntity()->LoadCharacter(m_slot, filename);

	m_pCharInstance = GetEntity()->GetCharacter(m_slot);
	if (!m_pCharInstance)
		return false;

	if (subTable.haveAttr("materialName"))
	{
		string materialName = subTable.getAttr("materialName");
		materialName.MakeLower();

		IMaterial* pMaterial = 0;
		const char* subMtlName = 0;
		int subMtlSlot = -1;

		// find tread material
		IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)GetEntity()->GetProxy(ENTITY_PROXY_RENDER);
		if (pRenderProxy)
		{
			pMaterial = pRenderProxy->GetRenderMaterial(m_slot);
			if (pMaterial)
			{
				// if matname doesn't fit, look in submaterials
				if (string(pMaterial->GetName()).MakeLower().find(materialName) == string::npos)
				{
					for (int i=0; i < pMaterial->GetSubMtlCount(); ++i)
					{
						if (string(pMaterial->GetSubMtl(i)->GetName()).MakeLower().find(materialName) != string::npos)
						{
							subMtlName = pMaterial->GetSubMtl(i)->GetName();
							subMtlSlot = i;
							break;
						}
					}
				}
			}
		}

		if (pMaterial)
		{
			// clone
			IMaterial *pCloned = pMaterial->GetMaterialManager()->CloneMultiMaterial(pMaterial, subMtlName);
			if (pCloned)
			{
				pRenderProxy->SetSlotMaterial(m_slot, pCloned);
				pMaterial = pCloned;
				m_pMaterial = pMaterial;
			}

			if (subMtlSlot > -1)
				m_pShaderResources = pMaterial->GetShaderItem(subMtlSlot).m_pShaderResources;
			else
				m_pShaderResources = pMaterial->GetShaderItem().m_pShaderResources;
		}

		if (m_pShaderResources)
		{
			for (int i = 0; i < EFTT_MAX; ++i)
			{
				if (!m_pShaderResources->GetTexture(i))
					continue;

				SEfTexModificator& modif = *m_pShaderResources->GetTexture(i)->AddModificator();

				modif.SetMember("m_eMoveType[0]", 1.0f);  // ETMM_Fixed: u = m_OscRate[0] + sourceU

				modif.SetMember("m_OscRate[0]", 0.0f);
			}
		}
	}

	char wheelName[256];

	IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
	for (int i=0; i<rIDefaultSkeleton.GetJointCount(); ++i)
	{
		const char* boneName = rIDefaultSkeleton.GetJointNameByID(i);
		if (0 != boneName)
		{
			// extract wheel name
			const size_t len = strcspn(boneName, "_");
			if (len < strlen(boneName) && len < sizeof(wheelName))
			{
				cry_strcpy(wheelName, boneName, len);

				CVehiclePartSubPartWheel* pWheel = (CVehiclePartSubPartWheel*)m_pVehicle->GetPart(wheelName);
				if (pWheel)
				{
					SWheelInfo wheelInfo;
					wheelInfo.slot = pWheel->m_slot;
					wheelInfo.jointId = i;
					wheelInfo.pWheel = pWheel;
					m_wheels.push_back(wheelInfo);

					m_lastWheelIndex = pWheel->GetWheelIndex();
				}
			}
		}
	}

	m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);

	m_state = eVGS_Default;
	return true;
}