bool CStickyProjectile::AttachToCharacter(CProjectile* pProjectile, IEntity& pEntity, ICharacterInstance& pCharacter, const char* boneName) { IEntity* pProjectileEntity = pProjectile->GetEntity(); char attachName[16] = ""; sprintf(attachName, "StickyProj_%d", s_attachNameID++); IAttachment* pCharacterAttachment = pCharacter.GetIAttachmentManager()->CreateAttachment(attachName, CA_BONE, boneName, false); if(!pCharacterAttachment) { CryLogAlways("Could not create attachment for StickyProjectile[%s]. AttachmentName[%s] BoneName[%s]", pProjectileEntity->GetName(), attachName, boneName ); CRY_ASSERT_MESSAGE(pCharacterAttachment, "Could not create attachment for StickyProjectile. This must be fixed."); return false; } m_characterAttachmentCrC = pCharacterAttachment->GetNameCRC(); SetProjectilePhysics(pProjectile, ePT_None); pCharacterAttachment->SetAttRelativeDefault(QuatT(m_stuckRot, m_stuckPos)); CEntityAttachment *pEntityAttachment = new CEntityAttachment(); pEntityAttachment->SetEntityId(pProjectileEntity->GetId()); pCharacterAttachment->AddBinding(pEntityAttachment); return true; }
bool CMFXParticleEffect::AttachToCharacter( IEntity& targetEntity, const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, const Vec3& dir, float scale ) { if (params.partID >= 0) { //Assume character is loaded in first slot //We could iterate through all available slots, but first one should be good enough ICharacterInstance* pCharacterInstace = targetEntity.GetCharacter(0); ISkeletonPose* pSkeletonPose = pCharacterInstace ? pCharacterInstace->GetISkeletonPose() : NULL; if (pSkeletonPose) { IDefaultSkeleton& rIDefaultSkeleton = pCharacterInstace->GetIDefaultSkeleton(); //It hit the character, but probably in a physicalized attached part, like armor plates, etc if (params.partID >= rIDefaultSkeleton.GetJointCount()) { return false; } //It hit some valid joint, create an attachment const char* boneName = rIDefaultSkeleton.GetJointNameByID(params.partID); TAttachmentName attachmentName; GetNextCharacterAttachmentName(attachmentName); IAttachmentManager* pAttachmentManager = pCharacterInstace->GetIAttachmentManager(); CRY_ASSERT(pAttachmentManager); //Remove the attachment first (in case was created before) pAttachmentManager->RemoveAttachmentByName(attachmentName.c_str()); //Create attachment on nearest hit bone IAttachment* pAttachment = pAttachmentManager->CreateAttachment(attachmentName.c_str(), CA_BONE, boneName, false); if (pAttachment) { //Apply relative offsets const QuatT boneLocation = pSkeletonPose->GetAbsJointByID(params.partID); Matrix34 inverseJointTM = targetEntity.GetWorldTM() * Matrix34(boneLocation); inverseJointTM.Invert(); Vec3 attachmentOffsetPosition = inverseJointTM * params.pos; Quat attachmentOffsetRotation = Quat(inverseJointTM) * targetEntity.GetRotation(); CRY_ASSERT(attachmentOffsetPosition.IsValid()); //CRY_ASSERT(attachmentOffsetRotation.IsUnit()); pAttachment->SetAttRelativeDefault(QuatT(attachmentOffsetRotation, attachmentOffsetPosition)); //Finally attach the effect CEffectAttachment* pEffectAttachment = new CEffectAttachment(particleParams.name.c_str(), Vec3(0,0,0), dir, scale); pAttachment->AddBinding(pEffectAttachment); return true; } } } return false; }
void UpdateOffset(SActivationInfo *pActInfo) { IAttachment *pAttachment = GetAttachment(pActInfo); if (pAttachment) { const Vec3& rotationOffsetEuler = GetPortVec3(pActInfo, eIP_RotationOffset); QuatT offset = QuatT::CreateRotationXYZ(Ang3(DEG2RAD(rotationOffsetEuler))); offset.t = GetPortVec3(pActInfo, eIP_TranslationOffset); pAttachment->SetAttRelativeDefault(offset); } }
//------------------------------------------------------------------------ void CItem::SetCharacterAttachmentLocalTM(int slot, const char *name, const Matrix34 &tm) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if (!pCharacter) return; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name); if (!pAttachment) { GameWarning("Item '%s' trying to set local TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name); return; } pAttachment->SetAttRelativeDefault( QuatT(tm)); }
//------------------------------------------------------------------------ void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if (!pCharacter) return; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name); if (!pAttachment) { GameWarning("Item '%s' trying to set world TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name); return; } // Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) * pCharacter->GetISkeleton()->GetAbsJMatrixByID(pAttachment->GetBoneID()); Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) * Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) ); Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm); pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix)); }
//------------------------------------------------------------------------ //Above function is almost the same, just some special stuff for flashlight //------------------------------------------------------------------------ uint32 CItem::AttachLightEx(int slot, uint32 id, bool attach, bool fakeLight /*= false */, bool castShadows /*= false*/, IRenderNode* pCasterException, float radius, const Vec3 &color, const float fSpecularMult, const char *projectTexture, float projectFov, const char *helper, const Vec3 &offset, const Vec3 &dir, const char* material, float fHDRDynamic) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (radius<0.1f) return 0; if (attach) { CDLight light; light.SetLightColor(ColorF(color.x, color.y, color.z, 1.0f)); light.SetSpecularMult( fSpecularMult ); light.m_nLightStyle = 0; light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = radius; light.m_fLightFrustumAngle = projectFov*0.5f; light.m_fHDRDynamic = fHDRDynamic; if(fakeLight) light.m_Flags |= DLF_FAKE; //Only on hight/very hight spec if(castShadows && (g_pGameCVars->i_lighteffects!=0)) light.m_Flags |= DLF_CASTSHADOW_MAPS; if (projectTexture && projectTexture[0]) { int flags = 0; light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(projectTexture, flags); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("Item '%s' failed to load projecting light texture '%s'!", GetEntity()->GetName(), projectTexture); return 0; } } if (light.m_fLightFrustumAngle && (light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) light.m_Flags |= DLF_PROJECT; else { if (light.m_pLightImage) light.m_pLightImage->Release(); light.m_pLightImage = 0; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = 0; if (material && material[0]) pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material); // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; effectInfo.slot = -1; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj) { // get helper position Vec3 position(0,0,0); if (validSlot) { IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } position+=offset; // find a free slot SEntitySlotInfo dummy; int i=0; while (GetEntity()->GetSlotInfo(eIGS_Last+i, dummy)) i++; // move light slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadLight(eIGS_Last+i, &light); if (effectInfo.slot != -1 && pMaterial) GetEntity()->SetSlotMaterial(effectInfo.slot, pMaterial); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(position); GetEntity()->SetSlotLocalTM(effectInfo.slot, tm); } else if (slotInfo.pCharacter) // bone attachment { effectInfo.helper = helper; effectInfo.characterSlot = slot; ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (!pAttachment) { GameWarning("Item '%s' trying to attach light to attachment '%s' which does not exist!", GetEntity()->GetName(), helper); return 0; } CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); if (pMaterial) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetMaterial(pMaterial); } if(light.m_Flags&DLF_CASTSHADOW_MAPS) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetCastingException(pCasterException); } Matrix34 tm =Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pLightAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); } m_effects.insert(TEffectInfoMap::value_type(m_effectGenId, effectInfo)); return m_effectGenId; } else if (id) { TEffectInfoMap::iterator it = m_effects.find(id); if (it == m_effects.end()) return 0; SEffectInfo &info = it->second; if (info.slot>-1) { GetEntity()->FreeSlot(info.slot); } else { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(info.characterSlot); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
//------------------------------------------------------------------------ uint32 CItem::AttachEffect(int slot, uint32 id, bool attach, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (attach) { if (!g_pGameCVars->i_particleeffects) return 0; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (!pParticleEffect) return 0; // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj || (!helper || !helper[0])) { // get helper position Vec3 position(0,0,0); if (validSlot && helper && helper[0]) { IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } position+=offset; // find a free slot SEntitySlotInfo dummy; int i=0; while (GetEntity()->GetSlotInfo(eIGS_Last+i, dummy)) i++; // move particle slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadParticleEmitter(eIGS_Last+i, pParticleEffect, 0, prime, true); Matrix34 tm = IParticleEffect::ParticleLoc(position, dir, scale); GetEntity()->SetSlotLocalTM(effectInfo.slot, tm); } else if (slotInfo.pCharacter) // bone attachment { effectInfo.helper = helper; effectInfo.characterSlot = slot; ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (!pAttachment) { GameWarning("Item '%s' trying to attach effect '%s' to attachment '%s' which does not exist!", GetEntity()->GetName(), effectName, helper); return 0; } CEffectAttachment *pEffectAttachment = new CEffectAttachment(effectName, Vec3(0,0,0), Vec3(0,1,0), scale); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pEffectAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); pEffectAttachment->UpdateAttachment(pAttachment); if (pEffectAttachment->GetEmitter()) { if (prime) pEffectAttachment->GetEmitter()->Prime(); } } m_effects.insert(TEffectInfoMap::value_type(m_effectGenId, effectInfo)); return m_effectGenId; } else if (id) { TEffectInfoMap::iterator it = m_effects.find(id); if (it == m_effects.end()) return 0; SEffectInfo &info = it->second; if (info.slot>-1) { GetEntity()->FreeSlot(info.slot); } else { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(info.characterSlot); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); if(pAttachment) pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
void CLaserBeam::FixAttachment(IEntity* pLaserEntity) { m_usingEntityAttachment = false; IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); CItem* pOwnerItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId)); if (pOwnerItem) { IEntity* pOwnerEntity = pOwnerItem->GetEntity(); IEntity* pAttachedEntity = pOwnerEntity; const char* attach_helper = "laser_term"; Vec3 offset = pOwnerItem->GetSlotHelperPos(m_geometrySlot, attach_helper, false); if(m_geometrySlot == eIGS_FirstPerson) { if(pOwnerItem->IsAccessory()) { EntityId parentId = pOwnerItem->GetParentId(); if(parentId) { if(CItem* pParentItem = static_cast<CItem*>(pItemSystem->GetItem(parentId))) { const SAccessoryParams* pParams = pParentItem->GetAccessoryParams(pAttachedEntity->GetClass()); attach_helper = pParams->attach_helper.c_str(); pAttachedEntity = pParentItem->GetEntity(); } } } if(pAttachedEntity) { ICharacterInstance *pCharacter = pAttachedEntity->GetCharacter(eIGS_FirstPerson); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pLaserAttachment = pAttachmentManager->GetInterfaceByName(LASER_ATTACH_NAME); if(!pLaserAttachment) { IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(attach_helper); if(pAttachment) { const char* pBone = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton()->GetJointNameByID(pAttachment->GetJointID()); pLaserAttachment = pAttachmentManager->CreateAttachment(LASER_ATTACH_NAME, CA_BONE, pBone); if(pLaserAttachment) { QuatT relative = pAttachment->GetAttRelativeDefault(); if(pOwnerItem->GetEntity() != pAttachedEntity) { Matrix34 mtx(relative); relative.t = relative * offset; } pLaserAttachment->SetAttRelativeDefault(relative); } } } if(pLaserAttachment) { CEntityAttachment* pEntAttach = new CEntityAttachment; pEntAttach->SetEntityId(m_laserEntityId); pLaserAttachment->AddBinding(pEntAttach); pLaserAttachment->HideAttachment(0); m_usingEntityAttachment = true; } } } } if(!m_usingEntityAttachment && pOwnerEntity) { pOwnerEntity->AttachChild(pLaserEntity); pLaserEntity->SetLocalTM(Matrix34::CreateTranslationMat(offset)); } } }
TAttachedEffectId CEffectsController::AttachLight(const int targetSlot, const char *helperName, const SLightAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); CDLight light; light.SetLightColor(ColorF(attachParams.color.x * attachParams.diffuseMultiplier, attachParams.color.y * attachParams.diffuseMultiplier, attachParams.color.z * attachParams.diffuseMultiplier, 1.0f)); light.SetSpecularMult( (float)__fsel( -attachParams.diffuseMultiplier, attachParams.specularMultiplier, (attachParams.specularMultiplier / (attachParams.diffuseMultiplier + FLT_EPSILON)) ) ); light.m_nLightStyle = attachParams.style; light.SetAnimSpeed(attachParams.animSpeed); light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = attachParams.radius; light.m_fLightFrustumAngle = attachParams.projectFov * 0.5f; light.m_fHDRDynamic = attachParams.hdrDynamic; light.m_Flags |= attachParams.deferred ? DLF_DEFERRED_LIGHT : 0; light.m_Flags |= attachParams.castShadows ? DLF_CASTSHADOW_MAPS : 0; light.m_nEntityId = m_pOwnerEntity->GetId(); if (attachParams.projectTexture && attachParams.projectTexture[0]) { light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(attachParams.projectTexture); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("[EntityEffects] Entity '%s' failed to load projecting light texture '%s'!", m_pOwnerEntity->GetName(), attachParams.projectTexture); return 0; } } if ((light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) { light.m_Flags |= DLF_PROJECT; } else { if (light.m_pLightImage) { light.m_pLightImage->Release(); } light.m_pLightImage = NULL; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = NULL; if (attachParams.material && attachParams.material[0]) { pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(attachParams.material); } SEntitySlotInfo slotInfo; SEffectInfo effectInfo; const bool validSlot = m_pOwnerEntity->GetSlotInfo(targetSlot, slotInfo); if (!validSlot || slotInfo.pStatObj) { //Get helper position on static object (if any) Vec3 helperPos(ZERO); Vec3 localHelperPosition = attachParams.offset; if (validSlot) { helperPos = slotInfo.pStatObj->GetHelperPos(helperName); if (helperPos.IsZero()) { const int childCount = m_pOwnerEntity->GetChildCount(); for (int i=0;i<childCount;++i) { if (IEntity* pChild = m_pOwnerEntity->GetChild(i)) { if (IStatObj* statObj = pChild->GetStatObj(targetSlot)) { helperPos = statObj->GetHelperPos(helperName); if (!helperPos.IsZero()) { helperPos += pChild->GetPos(); break; } } } } } localHelperPosition = helperPos + attachParams.offset; localHelperPosition = m_pOwnerEntity->GetSlotLocalTM(targetSlot, false).TransformPoint(localHelperPosition); } int attachSlot = FindSafeSlot(attachParams.firstSafeSlot); ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.entityEffectSlot = m_pOwnerEntity->LoadLight(attachSlot, &light); if ((effectInfo.entityEffectSlot >= 0) && pMaterial) { m_pOwnerEntity->SetSlotMaterial(effectInfo.entityEffectSlot, pMaterial); } Matrix34 localEffectMtx = Matrix34(Matrix33::CreateRotationVDir(attachParams.direction)); localEffectMtx.SetTranslation(localHelperPosition); m_pOwnerEntity->SetSlotLocalTM(effectInfo.entityEffectSlot, localEffectMtx); m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } else if (slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName); if (pAttachment) { CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); ILightSource* pLightSource = pLightAttachment->GetLightSource(); if (pLightSource) { pLightSource->SetMaterial(pMaterial); pLightSource->SetCastingException(attachParams.pCasterException); } pAttachment->AddBinding(pLightAttachment); const bool customOffset = (attachParams.offset != Vec3Constants<float>::fVec3_Zero) || (attachParams.direction != Vec3Constants<float>::fVec3_OneY); if (customOffset) { pAttachment->SetAttRelativeDefault(QuatT(Quat::CreateRotationVDir(attachParams.direction), attachParams.offset)); } } else { GameWarning("[EntityEffects] Entity '%s' trying to attach light to attachment '%s' which does not exist!", m_pOwnerEntity->GetName(), helperName); return 0; } ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.helperName = helperName; effectInfo.characterEffectSlot = targetSlot; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } return 0; }
//------------------------------------------------------------------------ EntityEffects::TAttachedEffectId CItem::AttachEffect(int slot, bool attachToAccessory, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime) { if(!g_pGameCVars->i_particleeffects) { return 0; } Vec3 finalOffset(offset); string helperName(helper); if(attachToAccessory) { SEntitySlotInfo slotInfo; QuatT accessoryOffset; accessoryOffset.SetIdentity(); const char* accessoryHelper = ""; const char* accessoryName = NULL; const int numAccessories = m_accessories.size(); for (int curIndex = 0; curIndex < numAccessories; curIndex++) { IEntity* pAccessory = gEnv->pEntitySystem->GetEntity(m_accessories[curIndex].accessoryId); if(pAccessory && pAccessory->GetSlotInfo(slot, slotInfo)) { if(slotInfo.pStatObj) { accessoryOffset.t = slotInfo.pStatObj->GetHelperPos(helper); if(!accessoryOffset.t.IsZero()) { accessoryOffset.q = pAccessory->GetRotation(); accessoryOffset.t += pAccessory->GetPos(); accessoryName = m_accessories[curIndex].pClass->GetName(); break; } } if(slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if(pAttachment) { accessoryHelper = GetAccessoryParams(m_accessories[curIndex].pClass)->attach_helper.c_str(); accessoryName = m_accessories[curIndex].pClass->GetName(); accessoryOffset = pAttachment->GetAttAbsoluteDefault(); break; } } } } if(accessoryName) { bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj) { if (validSlot) { Matrix34 mtx = GetEntity()->GetSlotLocalTM(slot, false) * Matrix34(accessoryOffset); finalOffset += mtx.GetTranslation(); } EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last); return m_effectsController.AttachParticleEffect(effectName, attachParams); } else if (slotInfo.pCharacter) // bone attachment { ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = NULL; helperName = string().Format("%s_%s", helper, accessoryName); pAttachment = pAttachmentManager->GetInterfaceByName(helperName.c_str()); if(!pAttachment) { IAttachment* pAccessoryAttachment = pAttachmentManager->GetInterfaceByName(accessoryHelper); if(pAccessoryAttachment) { const char* bone = pCharacter->GetIDefaultSkeleton().GetJointNameByID(pAccessoryAttachment->GetJointID()); pAttachment = pAttachmentManager->CreateAttachment(helperName.c_str(), CA_BONE, bone); if (pAttachment) { QuatT relative = pAccessoryAttachment->GetAttRelativeDefault(); relative = relative * accessoryOffset; relative.t = relative * finalOffset; finalOffset.zero(); pAttachment->SetAttRelativeDefault(relative); } } } } } } EntityEffects::SEffectAttachParams attachParams(finalOffset, dir, scale, prime, eIGS_Last); return m_effectsController.AttachParticleEffect(effectName, slot, helperName, attachParams); }
void CFlashLight::EnableFogVolume(CWeapon* pWeapon, int slot, bool enable) { if (!g_pGameCVars->i_flashlight_has_fog_volume) { return; } if (!m_sharedparams->pFlashLightParams) { return; } IEntity* pFogVolume = 0; if (m_fogVolume == 0) { const Vec3 size = Vec3( m_sharedparams->pFlashLightParams->fogVolumeRadius, m_sharedparams->pFlashLightParams->fogVolumeSize, m_sharedparams->pFlashLightParams->fogVolumeRadius); SEntitySpawnParams fogVolumeParams; fogVolumeParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("FogVolume"); fogVolumeParams.nFlags = ENTITY_FLAG_NO_SAVE; fogVolumeParams.vPosition = Vec3(ZERO); pFogVolume = gEnv->pEntitySystem->SpawnEntity(fogVolumeParams); if (!pFogVolume) { return; } m_fogVolume = pFogVolume->GetId(); SmartScriptTable pProperties; pFogVolume->GetScriptTable()->GetValue("Properties", pProperties); if (pProperties) { pProperties->SetValue("color_Color", m_sharedparams->pFlashLightParams->fogVolumeColor); pProperties->SetValue("GlobalDensity", m_sharedparams->pFlashLightParams->fogVolumeDensity); pProperties->SetValue("Size", size); pProperties->SetValue("FallOffScale", 0.0f); } EntityScripts::CallScriptFunction(pFogVolume, pFogVolume->GetScriptTable(), "OnPropertyChange"); pFogVolume->Activate(true); } else { pFogVolume = gEnv->pEntitySystem->GetEntity(m_fogVolume); } if (!pFogVolume) { return; } const char* attachHelper = "lightFog_term"; const float distance = m_sharedparams->pFlashLightParams->fogVolumeSize * 0.5f; ICharacterInstance* pCharacter = pWeapon->GetEntity()->GetCharacter(slot); if (enable && pCharacter) { IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment* pAttachment = pAttachmentManager->GetInterfaceByName(attachHelper); if (pAttachment) { CEntityAttachment* pEntityAttachment = new CEntityAttachment(); pEntityAttachment->SetEntityId(m_fogVolume); pAttachment->AddBinding(pEntityAttachment); QuatT relative(IDENTITY); relative.t.y = distance; pAttachment->SetAttRelativeDefault(relative); } } pFogVolume->Hide(!enable); }