bool CScriptSurfaceType::Load( int nId ) { m_nId = nId; IScriptSystem *pScriptSystem = gEnv->pScriptSystem; SmartScriptTable mtlTable; if (!pScriptSystem->GetGlobalValue("Materials", mtlTable)) { return false; } ////////////////////////////////////////////////////////////////////////// if (!pScriptSystem->ExecuteFile( m_script,true )) { GetISystem()->Warning( VALIDATOR_MODULE_3DENGINE,VALIDATOR_WARNING, VALIDATOR_FLAG_FILE|VALIDATOR_FLAG_SCRIPT, m_script.c_str(), "'%s' failed to load surface type definition script",m_name.c_str() ); return false; } if (!mtlTable->GetValue( m_name,m_pScriptTable )) return false; XmlNodeRef matNode = m_root->newChild("SurfaceType"); matNode->setAttr( "name",m_name ); // Load physics params. SmartScriptTable pPhysicsTable,props; float fBouncyness = 0.0f; float fFriction = 1.0f; int iPiercingResistence = sf_max_pierceable; // physics traces range 0-15 int imatBreakable = -1, bManuallyBreakable=0; m_iBreakability=0; m_nHitpoints=0; m_breakEnergy=0; if (m_pScriptTable->GetValue("physics",pPhysicsTable)) { pPhysicsTable->GetValue("friction",fFriction); pPhysicsTable->GetValue("bouncyness",fBouncyness); pPhysicsTable->GetValue("breakable_id",imatBreakable); if (pPhysicsTable->GetValue("pierceability",iPiercingResistence)) { if(iPiercingResistence>sf_max_pierceable) iPiercingResistence = sf_max_pierceable; } int nBreakable2d = 0; int bNoCollide = 0; pPhysicsTable->GetValue("no_collide", bNoCollide); if (pPhysicsTable->GetValue("break_energy",m_breakEnergy)) { bManuallyBreakable = sf_manually_breakable; m_iBreakability = 2; pPhysicsTable->GetValue("hit_points",m_nHitpoints); } else if (m_pScriptTable->GetValue("breakable_2d",props)) { nBreakable2d = 1; bManuallyBreakable = sf_manually_breakable; m_iBreakability = 1; props->GetValue("break_energy",m_breakEnergy); props->GetValue("hit_points",m_nHitpoints); } m_nFlags &= ~SURFACE_TYPE_NO_COLLIDE; if (bNoCollide) m_nFlags |= SURFACE_TYPE_NO_COLLIDE; XmlNodeRef physNode = matNode->newChild("Physics"); physNode->setAttr( "friction",fFriction ); physNode->setAttr( "elasticity",fBouncyness ); physNode->setAttr( "breakable_id",imatBreakable ); physNode->setAttr( "pierceability",iPiercingResistence ); physNode->setAttr( "no_collide",bNoCollide ); physNode->setAttr( "break_energy",m_breakEnergy ); physNode->setAttr( "hit_points",m_nHitpoints ); physNode->setAttr( "breakable_2d",nBreakable2d ); } SmartScriptTable pAITable; if (m_pScriptTable->GetValue("AI",pAITable)) { XmlNodeRef aiNode = matNode->newChild("AI"); float fImpactRadius = 1; float fFootStepRadius = 1; float proneMult = 1; float crouchMult = 1; float movingMult = 1; pAITable->GetValue( "fImpactRadius",fImpactRadius ); pAITable->GetValue( "fFootStepRadius",fFootStepRadius ); pAITable->GetValue( "proneMult",proneMult ); pAITable->GetValue( "crouchMult",crouchMult ); pAITable->GetValue( "movingMult",movingMult ); aiNode->setAttr( "fImpactRadius",fImpactRadius ); aiNode->setAttr( "fFootStepRadius",fFootStepRadius ); aiNode->setAttr( "proneMult",proneMult ); aiNode->setAttr( "crouchMult",crouchMult ); aiNode->setAttr( "movingMult",movingMult ); } gEnv->pPhysicalWorld->SetSurfaceParameters(m_nId,fBouncyness,fFriction, (uint32)(sf_pierceability(iPiercingResistence) | sf_matbreakable(imatBreakable) | bManuallyBreakable)); return true; }