void CVehicleSeatActionRotateTurret::MaintainPartRotationWorldSpace(EVehicleTurretRotationType eType) { CVehiclePartBase* pPart = m_rotations[eType].m_pPart; IVehiclePart* pParent = pPart->GetParent(); IActor* pActor = m_pSeat->GetPassengerActor(); bool remote = m_pSeat->GetCurrentTransition() == IVehicleSeat::eVT_RemoteUsage; bool worldSpace = m_rotations[eType].m_worldSpace && VehicleCVars().v_independentMountedGuns != 0; if (worldSpace && pParent && pActor && pActor->IsClient() && !remote) { // we want to keep the old worldspace rotation // therefore we're updating the local transform from it // NB: there is no need to clamp here, its done later Matrix34 localTM = pParent->GetWorldTM().GetInverted() * Matrix34(m_rotations[eType].m_prevWorldQuat); localTM.OrthonormalizeFast(); // precision issue const Matrix34 &baseTM = pPart->GetLocalBaseTM(); if (!Matrix34::IsEquivalent(baseTM,localTM)) { Ang3 anglesCurr(baseTM); Ang3 angles(localTM); if (eType == eVTRT_Pitch) { angles.y = anglesCurr.y; angles.z = anglesCurr.z; } else if (eType == eVTRT_Yaw) { angles.x = anglesCurr.x; angles.y = anglesCurr.y; } localTM.SetRotationXYZ(angles); localTM.SetTranslation(baseTM.GetTranslation()); pPart->SetLocalBaseTM(localTM); m_pSeat->ChangedNetworkState(CVehicle::ASPECT_PART_MATRIX); } #if ENABLE_VEHICLE_DEBUG if (VehicleCVars().v_debugdraw == eVDB_Parts) { float color[] = {1,1,1,1}; Ang3 a(localTM), aBase(baseTM); gEnv->pRenderer->Draw2dLabel(200,200,1.4f,color,false,"localAng: %.1f (real: %.1f)", RAD2DEG(a.z), RAD2DEG(aBase.z)); } #endif } }
//------------------------------------------------------------------------ void CGunTurret::OnReset() { if(IScriptTable *pScriptTable = GetEntity()->GetScriptTable()) { SmartScriptTable props; if(pScriptTable->GetValue("Properties", props)) ReadProperties(props); } CItem::OnReset(); Matrix34 tm = GetEntity()->GetSlotLocalTM(eIGS_Aux0,false); tm.SetTranslation(GetSlotHelperPos(eIGS_Aux0,m_radarHelper.c_str(),false)); GetEntity()->SetSlotLocalTM(eIGS_ThirdPerson,tm); if(GetEntity()->IsSlotValid(eIGS_Aux1)) { tm.SetTranslation(GetSlotHelperPos(eIGS_ThirdPerson,m_barrelHelper.c_str(),false)); GetEntity()->SetSlotLocalTM(eIGS_Aux1,tm); } m_targetId = 0; m_destinationId = 0; m_updateTargetTimer = 0.0f; m_abandonTargetTimer = 0.0f; m_goalYaw = 0.0f; m_goalPitch = 0.0f; m_burstTimer = 0.0f; m_pauseTimer = 0.0f; m_searchHint = 0; m_fireHint = 1; m_deviationPos.zero(); m_randoms[eRV_UpdateTarget].Range(m_turretparams.update_target_time * m_fireparams.randomness); m_randoms[eRV_AbandonTarget].Range(m_turretparams.abandon_target_time * m_fireparams.randomness); m_randoms[eRV_BurstTime].Range(m_turretparams.burst_time * m_fireparams.randomness); m_randoms[eRV_BurstPause].Range(m_turretparams.burst_pause * m_fireparams.randomness); m_lightId = AttachLight(eIGS_ThirdPerson, m_lightId, false); StopSound(m_lightSound); m_lightSound = INVALID_SOUNDID; if(m_turretparams.light_fov > 0.f) { m_lightId = AttachLight(eIGS_ThirdPerson, 0, true, m_turretparams.mg_range, m_searchparams.light_color*m_searchparams.light_diffuse_mul, 1.f/m_searchparams.light_diffuse_mul, m_searchparams.light_texture, m_turretparams.light_fov, m_searchparams.light_helper, Vec3(0,0,0), Vec3(-1,0,0), m_searchparams.light_material, m_searchparams.light_hdr_dyn); m_lightSound = PlayAction(g_pItemStrings->use_light); } SetFiringLocator(this); if(m_fm2) m_fm2->Activate(true); EnableUpdate(true, eIUS_General); }
void CBattleEvent::Update(SEntityUpdateContext &ctx, int updateSlot) { IEntity* pEntity = GetEntity(); if(pEntity) { Matrix34 tm = pEntity->GetWorldTM(); tm.SetTranslation(m_worldPos); pEntity->SetWorldTM(tm); if(m_numParticles > 0 && !m_pParticleEffect) { // attach the particle effect to this entity now m_pParticleEffect = gEnv->pParticleManager->FindEffect(g_pGameCVars->g_battleDust_effect->GetString()); if (m_pParticleEffect) { pEntity->LoadParticleEmitter(0, m_pParticleEffect, 0, true, true); Matrix34 tm = IParticleEffect::ParticleLoc(Vec3(0,0,0)); pEntity->SetSlotLocalTM(0, tm); } } if(m_pParticleEffect) { SEntitySlotInfo info; pEntity->GetSlotInfo(0, info); if(info.pParticleEmitter) { SpawnParams sp; sp.fCountScale = (float)m_numParticles/60.0f; info.pParticleEmitter->SetSpawnParams(sp); } } if(g_pGameCVars->g_battleDust_debug != 0) { if(g_pGameCVars->g_battleDust_debug >= 2) { if(m_numParticles > 0) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(m_worldPos, m_numParticles, ColorF(0.0f,1.0f,0.0f,0.2f)); } else { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(m_worldPos, 0.5f, ColorF(1.0f,0.0f,0.0f,0.2f)); } } else { if(m_numParticles > 0) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(m_worldPos, 0.5f, ColorF(0.0f,1.0f,0.0f,0.2f)); } else { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(m_worldPos, 0.5f, ColorF(1.0f,0.0f,0.0f,0.2f)); } } } } }
//------------------------------------------------------------------------ void CItem::UpdateFPPosition(float frameTime) { CActor* pActor = GetOwnerActor(); if (!pActor) return; SPlayerStats *pStats = static_cast<SPlayerStats *>(pActor->GetActorStats()); if (!pStats) return; Matrix34 tm = Matrix33::CreateRotationXYZ(pStats->FPWeaponAngles); Vec3 offset(0.0f,0.0f,0.0f); float right(g_pGameCVars->i_offset_right); float front(g_pGameCVars->i_offset_front); float up(g_pGameCVars->i_offset_up); if (front!=0.0f || up!=0.0f || right!=0.0f) { offset += tm.GetColumn(0).GetNormalized() * right; offset += tm.GetColumn(1).GetNormalized() * front; offset += tm.GetColumn(2).GetNormalized() * up; } tm.SetTranslation(pStats->FPWeaponPos + offset); GetEntity()->SetWorldTM(tm); //CryLogAlways("weaponpos: %.3f,%.3f,%.3f // weaponrot: %.3f,%.3f,%.3f", tm.GetTranslation().x,tm.GetTranslation().y,tm.GetTranslation().z, pStats->FPWeaponAngles.x, pStats->FPWeaponAngles.y, pStats->FPWeaponAngles.z); }
//----------------------------------------------------- void CThrow::ThrowObject(IEntity* pEntity, IPhysicalEntity* pPE) { bool strengthMode = false; CPlayer *pPlayer = static_cast<CPlayer*>(m_pWeapon->GetOwnerActor()); if (pPlayer) { // Report throw to AI system. if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pEntity->GetId(); pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_THROW, &AIevent); } } Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(dir); float speed = 12.0f; if(strengthMode) speed *= m_pShared->throwparams.strenght_scale; speed = max(2.0f, speed); pe_params_pos ppos; ppos.pos = pEntity->GetWorldPos(); pPE->SetParams(&ppos); if(CheckForIntersections(pPE,dir)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation()-(dir*0.4f)); pEntity->SetWorldTM(newTM,ENTITY_XFORM_POS); } else { pe_action_set_velocity asv; asv.v = (dir*speed)+vel; AABB box; pEntity->GetWorldBounds(box); Vec3 finalW = -gEnv->pSystem->GetViewCamera().GetMatrix().GetColumn0()*(8.0f/max(0.1f,box.GetRadius())); finalW.x *= Random(0.5f,1.3f); finalW.y *= Random(0.5f,1.3f); finalW.z *= Random(0.5f,1.3f); asv.w = finalW; //asv.w = Vec3(Random(-4.5f,3.5f),Random(-1.75f,2.5f),Random(-1.5f,2.2f)); pPE->Action(&asv); } SEntityEvent entityEvent; entityEvent.event = ENTITY_EVENT_PICKUP; entityEvent.nParam[0] = 0; if (pPlayer) entityEvent.nParam[1] = pPlayer->GetEntityId(); entityEvent.fParam[0] = speed; pEntity->SendEvent( entityEvent ); }
void CFlowNode_AISequenceAction_ApproachAndEnterVehicle::TeleportToVehicleSeat() { if (IEntity* pEntity = GetEntity()) { Matrix34 transform = pEntity->GetWorldTM(); transform.SetTranslation(m_vehicleSeatEnterPosition); pEntity->SetWorldTM(transform); } }
//------------------------------------------------------------------------ void CVehicleHelper::GetWorldTM(Matrix34& worldTM) const { FUNCTION_PROFILER( gEnv->pSystem, PROFILE_ACTION ); const Matrix34& partWorldTM = m_pParentPart->GetWorldTM(); worldTM = Matrix34(Matrix33(partWorldTM) * Matrix33(m_localTM)); worldTM.SetTranslation((partWorldTM * m_localTM).GetTranslation()); }
//----------------------------------------------------------------------------- bool CNetworkedPhysicsEntity::NetSerialize( TSerialize ser, EEntityAspects aspect, uint8 profile, int flags ) { NET_PROFILE_SCOPE("NetworkedPhysicsEntity", ser.IsReading()); if (aspect == eEA_Physics) { pe_type type = PE_NONE; switch (profile) { case ePhys_PhysicalizedRigid: { type = PE_RIGID; break; } case ePhys_PhysicalizedStatic: { type = PE_STATIC; // Serialise the position ourselves - physics system won't do it for static entities const Matrix34 &worldTM = GetEntity()->GetWorldTM(); Vec3 worldPos = worldTM.GetTranslation(); ser.Value("worldPos", worldPos, 'wrld'); if (ser.IsReading()) { Matrix34 newTM = worldTM; newTM.SetTranslation(worldPos); GetEntity()->SetWorldTM(newTM); } break; } } if (type == PE_NONE) return true; IEntityPhysicalProxy * pEPP = (IEntityPhysicalProxy *) GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS); if (ser.IsWriting()) { if (!pEPP || !pEPP->GetPhysicalEntity() || pEPP->GetPhysicalEntity()->GetType() != type) { gEnv->pPhysicalWorld->SerializeGarbageTypedSnapshot( ser, type, 0 ); return true; } } else if (!pEPP) { return false; } pEPP->SerializeTyped( ser, type, flags ); } return true; }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CC4Projectile, ClSetPosition) { Matrix34 mat; mat.SetRotation33(Matrix33(params.rot)); mat.SetTranslation(params.pos); GetEntity()->SetWorldTM(mat); m_stuck = true; return true; }
//------------------------------------------------------------------------- IMPLEMENT_RMI(CC4Projectile, ClStickToEntity) { if(IEntity *pEntity = gEnv->pEntitySystem->GetEntity(params.targetId)) { Matrix34 localMatrix; localMatrix.SetRotation33(Matrix33(params.localRotation)); localMatrix.SetTranslation(params.localCollisonPos); StickToEntity(pEntity,localMatrix); } return true; }
//------------------------------------------------------------------------ void CVehicleHelper::GetReflectedWorldTM(Matrix34 &reflectedWorldTM) const { FUNCTION_PROFILER( gEnv->pSystem, PROFILE_ACTION ); Matrix34 tempMatrix = m_localTM; tempMatrix.m03 = -tempMatrix.m03; // negate x coord of translation const Matrix34& partWorldTM = m_pParentPart->GetWorldTM(); reflectedWorldTM = Matrix34(Matrix33(partWorldTM) * Matrix33(tempMatrix)); reflectedWorldTM.SetTranslation((partWorldTM * tempMatrix).GetTranslation()); }
void SetPos( SActivationInfo* pActInfo, const Vec3& vPos) { if (pActInfo->pEntity) { if (m_coorSys==CS_WORLD && pActInfo->pEntity->GetParent()) { Matrix34 tm = pActInfo->pEntity->GetWorldTM(); tm.SetTranslation(vPos); pActInfo->pEntity->SetWorldTM(tm); } else pActInfo->pEntity->SetPos( vPos ); } }
void CBurnEffectManager::SpawnImpactEffect(const EventPhysCollision& pCollision, const char* effectName) { Vec3 surfaceNormal = pCollision.n; Vec3 surfacePosition = pCollision.pt; CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache(); IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(effectName); if (pParticleEffect) { Matrix34 loc; loc.SetIdentity(); loc.SetTranslation(surfacePosition); loc.SetRotation33(OrthoNormalVector(surfaceNormal)); pParticleEffect->Spawn(false, loc); } }
//------------------------------------------------------------------------ void CVehicleActionDeployRope::AttachOnRope(IEntity *pEntity) { assert(pEntity); if(!pEntity) return; IRopeRenderNode *pRopeUpper = GetRopeRenderNode(m_ropeUpperId); if(!pRopeUpper) return; assert(pRopeUpper->GetPointsCount() >= 2); IPhysicalEntity *pRopePhys = pRopeUpper->GetPhysics(); assert(pRopePhys); typedef std::vector <Vec3> TVec3Vector; TVec3Vector points; int pointCount; pe_status_rope ropeStatus; if(pRopePhys->GetStatus(&ropeStatus)) pointCount = ropeStatus.nSegments + 1; else pointCount = 0; if(pointCount < 2) return; points.resize(pointCount); ropeStatus.pPoints = &points[0]; if(pRopePhys->GetStatus(&ropeStatus)) { Matrix34 worldTM; worldTM.SetIdentity(); worldTM = Matrix33(m_pVehicle->GetEntity()->GetWorldTM()); worldTM.SetTranslation(ropeStatus.pPoints[1]); pEntity->SetWorldTM(worldTM); } pRopeUpper->LinkEndEntities(m_pVehicle->GetEntity()->GetPhysics(), pEntity->GetPhysics()); }
void CStickyProjectile::NetSetStuck(CProjectile* pProjectile, bool stuck) { if(stuck && ((m_flags&eSF_IsStuck)==0)) { IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(m_parentId); if(pTargetEntity) { if(ICharacterInstance* pTargetCharacter = pTargetEntity->GetCharacter(0)) { const char* boneName = pTargetCharacter->GetICharacterModel()->GetICharacterModelSkeleton()->GetJointNameByID(m_stuckJoint); if(AttachToCharacter(pProjectile, *pTargetEntity, *pTargetCharacter, boneName)) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; m_childId = pProjectile->GetEntityId(); } } } if((m_flags&eSF_IsStuck)==0) { IEntity* pProjectileEntity = pProjectile->GetEntity(); AttachTo(pProjectile, pTargetEntity); m_childId = pProjectileEntity->GetId(); if(pTargetEntity) //If we have a parent then the stuck position/rotation are local to the parent { pProjectileEntity->SetPos(m_stuckPos); pProjectileEntity->SetRotation(m_stuckRot); } else if(m_flags&eSF_OrientateToCollNormal) { Matrix34 mat; mat.SetTranslation(m_stuckPos); mat.SetRotation33(Matrix33(m_stuckRot)); pProjectileEntity->SetWorldTM(mat); } else { pProjectileEntity->SetPos(m_stuckPos); } m_flags |= eSF_IsStuck; } } }
//--------------------------------------------------------------------- //This function is only executed on the server void CC4Projectile::StickToStaticObject(EventPhysCollision *pCollision, IPhysicalEntity *pTarget) { //Calculate new position and orientation Matrix34 mat; Vec3 pos = pCollision->pt+(pCollision->n*0.05f); mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI)); Vec3 newUpDir = mat.TransformVector(Vec3(0,0,1)); pos += (newUpDir*-0.1f); mat.SetTranslation(pos+(newUpDir*-0.1f)); GetEntity()->SetWorldTM(mat); GetGameObject()->SetAspectProfile(eEA_Physics, ePT_Static); pos = mat.GetTranslation(); Quat rot = GetEntity()->GetWorldRotation(); if(gEnv->bMultiplayer) GetGameObject()->InvokeRMI(CC4Projectile::ClSetPosition(),ProjectileStaticParams(pos,rot),eRMI_ToAllClients); }
//------------------------------------------------------------------------ void CVehicleViewFirstPerson::Update(float frameTimeIn) { // Use the physics frame time, but only if non zero! const float physFrameTime = static_cast<CVehicle*>(m_pVehicle)->GetPhysicsFrameTime(); const float frameTime = (physFrameTime>0.f) ? min(physFrameTime,frameTimeIn) : frameTimeIn; CVehicleViewBase::Update(frameTime); if (m_frameSlot != -1 && m_pHelper) { Matrix34 tm; m_pHelper->GetVehicleTM(tm); tm = tm * m_invFrame; tm.SetTranslation(tm.GetTranslation() + tm.TransformVector(m_frameObjectOffset)); m_pVehicle->GetEntity()->SetSlotLocalTM(m_frameSlot, tm); } m_viewPosition = GetWorldPosGoal(); }
//----------------------------------------------------- void CThrow::ThrowLivingEntity(IEntity* pEntity, IPhysicalEntity* pPE) { Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(dir); CPlayer *pPlayer = static_cast<CPlayer*>(m_pWeapon->GetOwnerActor()); if(pPlayer) { float speed = 8.0f; dir.Normalize(); if(CheckForIntersections(pPE,dir)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation()-(dir*0.6f)); pEntity->SetWorldTM(newTM,ENTITY_XFORM_POS); } { pe_action_set_velocity asv; asv.v = (dir*speed)+vel; pPE->Action(&asv); // [anton] use thread safe=1 (immediate) if the character is still a living entity at this stage, // but will be ragdollized during the same frame pe_params_articulated_body pab; pab.bCheckCollisions = 1; // was set to 0 while carrying pPE->SetParams(&pab); } // Report throw to AI system. if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pEntity->GetId(); pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_THROW_NPC, &AIevent); } } }
void CMountedGunController::UpdateGunnerLocation( CItem* pMountedGun, IEntity* pParent, const Vec3& bodyDirection ) { const SMountParams* pMountParams = pMountedGun->GetMountedParams(); if (pMountParams) { f32 bodyDist = pMountParams->body_distance; f32 groundDist = pMountParams->ground_distance; Matrix34 gunLocalTM = pMountedGun->GetEntity()->GetLocalTM(); Matrix34 gunLocalTMXY(IDENTITY); Matrix34 characterTM(IDENTITY); Matrix34 newGunnerTM; Vec3 playerOffset(0.0f, -bodyDist, -groundDist); characterTM.SetTranslation(playerOffset); IEntity* pControlledPlayerEntity = m_pControlledPlayer->GetEntity(); IVehicle *pVehicle = NULL; if (gEnv->bMultiplayer && m_pControlledPlayer->IsClient() && m_pControlledPlayer->GetLinkedVehicle()) { newGunnerTM = gunLocalTM; newGunnerTM.SetTranslation(gunLocalTM.GetTranslation() + Quat(gunLocalTM) * playerOffset); } else { float rotZ = pMountedGun->GetEntity()->GetRotation().GetRotZ(); gunLocalTMXY.SetRotationZ(rotZ); gunLocalTMXY.SetTranslation(gunLocalTM.GetTranslation()); newGunnerTM = gunLocalTMXY*characterTM; } pControlledPlayerEntity->SetLocalTM(newGunnerTM, ENTITY_XFORM_USER); // CryWatch("Mount wrot: plr: %f vehicle: %f wpn: %f", pControlledPlayerEntity->GetWorldRotation().GetRotZ(), pParent ? pParent->GetWorldRotation().GetRotZ() : -99.0f, pMountedGun->GetEntity()->GetWorldRotation().GetRotZ()); // CryWatch("Mount lrot: plr: %f vehicle: %f wpn: %f", pControlledPlayerEntity->GetRotation().GetRotZ(), pParent ? pParent->GetRotation().GetRotZ() : -99.0f, pMountedGun->GetEntity()->GetRotation().GetRotZ()); } }
//----------------------------------------------------------------------- void CVehiclePartLight::UpdateLight(const float frameTime) { if (m_slot == -1) return; // move to vehicle event change view? if (m_diffuseMult[0] != m_diffuseMult[1]) { SEntitySlotInfo info; if (m_pVehicle->GetEntity()->GetSlotInfo(m_slot, info) && info.pLight) { CDLight& light = info.pLight->GetLightProperties(); IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); bool localPlayer = (pActor != NULL) && (pActor->GetLinkedVehicle() == m_pVehicle); IVehicleSeat* pSeat = pActor ? m_pVehicle->GetSeatForPassenger(pActor->GetEntityId()) : NULL; IVehicleView* pView = pSeat? pSeat->GetView(pSeat->GetCurrentView()) : NULL; bool isThirdPersonView = pView? pView->IsThirdPerson() : true; if (localPlayer && !isThirdPersonView) light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[0], 1.f)); else light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[1], 1.f)); } } if (m_pHelper) { const static Matrix33 rot(Matrix33::CreateRotationXYZ(Ang3(0.f, 0.f, DEG2RAD(90.f)))); Matrix34 helperTM; m_pHelper->GetVehicleTM(helperTM); Matrix34 localTM = Matrix33(helperTM) * rot; localTM.SetTranslation(helperTM.GetTranslation()); GetEntity()->SetSlotLocalTM(m_slot, localTM); } }
void CBurnEffectManager::CreateBurnEffect(const EventPhysCollision& pCollision, CBurnEffectManager::SBurnPoint* pBurnPoint) { Vec3 surfaceNormal = pCollision.n; Vec3 hitDir(ZERO); if (pCollision.vloc[0].GetLengthSquared() > 1e-6f) { hitDir = pCollision.vloc[0].GetNormalized(); } Vec3 surfacePosition = pCollision.pt; Vec3 halfVector = (surfaceNormal + (-hitDir)).GetNormalized(); CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache(); IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(pBurnPoint->m_pBurnParams->m_effectName); if (pParticleEffect) { Matrix34 loc; loc.SetIdentity(); loc.SetTranslation(surfacePosition); loc.SetRotation33(OrthoNormalVector(surfaceNormal)); IParticleEmitter* pEffect = pParticleEffect->Spawn(false, loc); if(pEffect) { pEffect->AddRef(); pBurnPoint->m_effect = pEffect; const ParticleParams& particleParams = pParticleEffect->GetParticleParams(); pBurnPoint->m_attachType = particleParams.eAttachType; pBurnPoint->m_attachForm = particleParams.eAttachForm; } UpdateBurnEffect(pBurnPoint); } UpdateBurnEffect(pBurnPoint); }
void CVehicleWeaponControlled::Update(SEntityUpdateContext& ctx, int update) { IVehicle *pVehicle = m_vehicleId ? gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) : NULL; if (!m_vehicleId && GetEntity()->GetParent()) { IEntity *entity = GetEntity(); if (entity) { IEntity *parent = entity->GetParent(); if (parent) { m_vehicleId = parent->GetId(); pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(parent->GetId()); } } } if (pVehicle) { IVehiclePart *pPart = pVehicle->GetWeaponParentPart(GetEntityId()); if(pPart) { if(IVehiclePart *pParentPart = pPart->GetParent()) { CRY_ASSERT(pVehicle->GetEntity()); if(ICharacterInstance *characterInst = pVehicle->GetEntity()->GetCharacter(pParentPart->GetSlot())) { if(ISkeletonPose* pose = characterInst->GetISkeletonPose()) { IDefaultSkeleton& rIDefaultSkeleton = characterInst->GetIDefaultSkeleton(); int16 joint = rIDefaultSkeleton.GetJointIDByName(pPart->GetName()); const QuatT &jQuat = pose->GetAbsJointByID(joint); Matrix34 localT(jQuat); localT.SetTranslation(jQuat.t/* - Vec3(0.0f, 0.75f, 0.0f)*/); Matrix34 vehicleWorldTm = pVehicle->GetEntity()->GetWorldTM(); Matrix34 mat = vehicleWorldTm * localT; Vec3 vehicleSide2 = pPart->GetParent()->GetLocalTM(true, true).GetTranslation(); CPlayer *pl = this->GetOwnerPlayer(); Matrix33 mat2; if (!m_destination.IsEquivalent(ZERO)) { Vec3 diff = GetDestination() - mat.GetTranslation(); //pPart->GetWorldTM().GetTranslation(); diff.Normalize(); Matrix33 loc(mat); loc.Invert(); Vec3 diffLocal = loc.TransformVector(diff); Matrix33 desMat; desMat.SetRotationVDir(diffLocal, 0.0f); Vec3 test = GetEntity()->GetLocalTM().GetColumn0(); Ang3 testTM(desMat); float za = testTM.x - m_Angles.x; za = (za < 0.0f) ? -gf_PI : gf_PI; za *= 0.05f * ctx.fFrameTime; m_Angles.x += za; Limit(m_Angles.x, -gf_PI * 0.33f, gf_PI * 0.33f); if (testTM.z > m_Angles.z + 0.05f) { m_Angles.z += gf_PI * factor1 * ctx.fFrameTime; } else if (testTM.z < m_Angles.z - 0.05f) { m_Angles.z -= gf_PI * factor1 * ctx.fFrameTime; } else { m_Angles.z = testTM.z; } Limit(m_Angles.z, -gf_PI * 0.33f, gf_PI * 0.33f); mat2.SetRotationXYZ(m_Angles); } else { if (!m_FireBlocked) { m_Angles.x = m_Angles.x - ctx.fFrameTime * factor2 * m_Angles.x; m_Angles.z = m_Angles.z - ctx.fFrameTime * factor2 * m_Angles.z; } mat2.SetRotationXYZ(m_Angles); } mat = mat * mat2; GetEntity()->SetWorldTM(mat); if (pl) { Matrix34 worldGunMat = vehicleWorldTm * localT; if (!pl->IsDead()) { Vec3 trans = worldGunMat.GetTranslation() - worldGunMat.GetColumn2() * 0.7f; worldGunMat.SetTranslation(trans); pl->GetEntity()->SetWorldTM(worldGunMat); float dot = mat.GetColumn1().dot(worldGunMat.GetColumn0()); Update3PAnim(pl, 0.5f - dot * 0.5f, ctx.fFrameTime, mat); } else { ICharacterInstance* pCharacter = pl->GetEntity()->GetCharacter(0); int boneId = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName("Spine03") : 7; pl->LinkToMountedWeapon(0); if (IVehicleSeat* seat = pVehicle->GetSeatForPassenger(pl->GetEntityId())) { seat->Exit(false, true); } Matrix33 rot(worldGunMat); Vec3 offset(0.0f, 0.0f, 0.70f); Vec3 transformedOff = rot.TransformVector(offset); Vec3 trans = worldGunMat.GetTranslation(); trans -= transformedOff; worldGunMat.SetTranslation(trans); pl->GetEntity()->SetWorldTM(worldGunMat); pl->GetEntity()->SetPos(worldGunMat.GetTranslation()); //worldGunMat.GetTranslation()); pl->RagDollize(true); if (boneId > -1) { IPhysicalEntity *physEnt = pl->GetEntity()->GetPhysics(); if (physEnt) { pe_simulation_params simulationParams; physEnt->GetParams(&simulationParams); pe_params_pos pos; pos.pos = GetEntity()->GetPos(); physEnt->SetParams(&pos); pe_action_impulse impulse; impulse.ipart = boneId; impulse.angImpulse = Vec3(0.0f, 0.0f, 1.0f); impulse.impulse = worldGunMat.GetColumn1() * -1.5f * simulationParams.mass; physEnt->Action(&impulse); } } StopUse(GetOwnerId()); SetOwnerId(0); StopFire(); m_FireBlocked = true; } // IsDead } // pl } // pose } // characterInst } // pParentPart } // pPart } // pVehicle Base::Update(ctx, update); RequireUpdate(eIUS_General); }
//------------------------------------------------------------------------ bool CItem::SetGeometry(int slot, const ItemString& name, const ItemString& material, bool useParentMaterial, const Vec3& poffset, const Ang3& aoffset, float scale, bool forceReload) { assert(slot >= 0 && slot < eIGS_Last); bool changedfp=false; switch(slot) { case eIGS_Owner: break; case eIGS_FirstPerson: case eIGS_ThirdPerson: default: { if (name.empty() || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } DestroyAttachmentHelpers(slot); if (!name.empty()) { if (m_geometry[slot] != name) { const char* ext = PathUtil::GetExt(name.c_str()); if ((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0) ) GetEntity()->LoadCharacter(slot, name.c_str(), 0); else GetEntity()->LoadGeometry(slot, name.c_str(), 0, 0); changedfp=slot==eIGS_FirstPerson; } CreateAttachmentHelpers(slot); } /* if (slot == eIGS_FirstPerson) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if (pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); } } else */if (slot == eIGS_Destroyed) DrawSlot(eIGS_Destroyed, false); } break; } Matrix34 slotTM; slotTM = Matrix34::CreateRotationXYZ(aoffset); slotTM.ScaleColumn(Vec3(scale, scale, scale)); slotTM.SetTranslation(poffset); GetEntity()->SetSlotLocalTM(slot, slotTM); if (changedfp && m_stats.mounted) { if (m_sharedparams->pMountParams && !m_sharedparams->pMountParams->pivot.empty()) { Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false); Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_sharedparams->pMountParams->pivot.c_str(), false); tm.AddTranslation(pivot); GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm); } GetEntity()->InvalidateTM(); } m_geometry[slot] = name ? name : ItemString(); ReAttachAccessories(); IEntity* pParentEntity = gEnv->pEntitySystem->GetEntity(GetParentId()); IMaterial* pOverrideMaterial = 0; if (!material.empty()) { pOverrideMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material.c_str()); } else if (useParentMaterial && pParentEntity) { ICharacterInstance* pParentCharacter = pParentEntity->GetCharacter(slot); IEntityRenderProxy* pParentRenderProxy = static_cast<IEntityRenderProxy*>(pParentEntity->GetProxy(ENTITY_PROXY_RENDER)); if (pParentCharacter) pOverrideMaterial = pParentCharacter->GetIMaterial(); else if (pParentRenderProxy) pOverrideMaterial = pParentRenderProxy->GetSlotMaterial(slot); } if (pOverrideMaterial) { ICharacterInstance* pCharacter = GetEntity()->GetCharacter(slot); IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER)); OverrideAttachmentMaterial(pOverrideMaterial, this, slot); if (pCharacter) pCharacter->SetIMaterial_Instance(pOverrideMaterial); else if (pRenderProxy) pRenderProxy->SetSlotMaterial(slot, pOverrideMaterial); } if(slot == eIGS_FirstPerson && IsSelected()) { CActor* pOwnerActor = GetOwnerActor(); IActionController *pActionController = GetActionController(); if(pActionController && pOwnerActor && pOwnerActor->IsClient()) { UpdateScopeContexts(pActionController); } } return true; }
void CEntityObject::Render( CEntity* pEntity,SRendParams &rParams,int nRndFlags,CRenderProxy* pRenderProxy, const SRenderingPassInfo &passInfo ) { if (!bWorldTMValid) { UpdateWorldTM(pEntity); } // Override with custom slot material. IMaterial* pPrevMtl = rParams.pMaterial; if (pMaterial) rParams.pMaterial = pMaterial; int32 nOldObjectFlags = rParams.dwFObjFlags; rParams.dwFObjFlags |= dwFObjFlags; if (flags & ENTITY_SLOT_RENDER_AFTER_POSTPROCESSING) { rParams.dwFObjFlags |= FOB_RENDER_AFTER_POSTPROCESSING; } #ifdef SEG_WORLD rParams.nCustomFlags |= (1 << (COB_SW_SHIFT + pEntity->GetSwObjDebugFlag())); #endif // SEG_WORLD ////////////////////////////////////////////////////////////////////////// rParams.pInstance = this; const bool bIsInCameraSpace = (flags & ENTITY_SLOT_RENDER_NEAREST) != 0; // Draw static object. if (pStatObj) { rParams.pMatrix = &m_worldTM; rParams.dwFObjFlags |= FOB_TRANS_MASK; rParams.pFoliage = pFoliage; rParams.nSubObjHideMask = nSubObjHideMask; // make sure object motion blur can be applied to this object if (bObjectMoved) { rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT; bObjectMoved = false; } Matrix34 entityTM; if (bIsInCameraSpace) { rParams.pMatrix = &entityTM; entityTM = m_worldTM; // Camera space if (m_pCameraSpacePos) { // Use camera space relative position entityTM.SetTranslation(*m_pCameraSpacePos); } else { // We don't have camera space relative position, so calculate it out from world space // (This will not have the precision advantages of camera space rendering) entityTM.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition()); } } if (rParams.pMatrix->IsValid()) pStatObj->Render( rParams, passInfo ); else EntityWarning("CEntityObject::Render: Invalid world matrix: %s", pEntity->GetEntityTextDescription()); } else if (pCharacter) { QuatTS Offset; Matrix34 PhysLocation(pEntity->GetWorldTM()); if (m_pXForm) Offset = QuatTS(m_pXForm->localTM); else { //CRY_FIXME(03,12,2009,"Animation & Rendering of entities needs to be re-written to avoid derivation of local offset due to float inaccuracy - Richard Semmens"); if (!Matrix34::IsEquivalent(PhysLocation,m_worldTM)) { Matrix34 invPhysLocation = PhysLocation.GetInverted(); Matrix34 matOffset = invPhysLocation * m_worldTM; Offset = QuatTS(matOffset); } else { Offset.SetIdentity(); } } if (bIsInCameraSpace) { // Camera space if (m_pCameraSpacePos) { // Use camera space relative position const Matrix33 camRot = Matrix33(gEnv->pSystem->GetViewCamera().GetViewMatrix()); PhysLocation.SetTranslation(*m_pCameraSpacePos * camRot); } else { // We don't have camera space relative position, so calculate it out from world space // (This will not have the precision advantages of camera space rendering) PhysLocation.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition()); } Offset.SetIdentity(); } rParams.pMatrix = &PhysLocation; //rParams.pInstance = pCharacter; // Disable hand-placed (static) decals on characters rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT; pCharacter->Render(rParams, Offset, passInfo); const uint32 renderProxyFlags = pRenderProxy->GetFlags(); if (!passInfo.IsShadowPass() || (renderProxyFlags & CRenderProxy::FLAG_ANIMATE_OFFSCREEN_SHADOW)) { // If We render character, make sure it is also gets animation activated. if (!pEntity->m_bInActiveList) pEntity->ActivateForNumUpdates(8); } } else if (pChildRenderNode) { rParams.pMatrix = &m_worldTM; //rParams.pInstance = pChildRenderNode; pChildRenderNode->m_dwRndFlags = nRndFlags; pChildRenderNode->Render( rParams, passInfo ); } rParams.pMaterial = pPrevMtl; rParams.dwFObjFlags = nOldObjectFlags; if (!passInfo.IsShadowPass()) // Should also ignore rendering into the recursion. { if (pFoliage) { pFoliage->SetFlags(pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(rParams.nMaterialLayers & MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN); static ICVar* g_pWindActivationDist = gEnv->pConsole->GetCVar("e_FoliageWindActivationDist"); float maxdist = g_pWindActivationDist ? g_pWindActivationDist->GetFVal() : 0.0f; Vec3 pos = m_worldTM.GetTranslation(); if (pStatObj && (gEnv->pSystem->GetViewCamera().GetPosition() - pos).len2() < sqr(maxdist) && gEnv->p3DEngine->GetWind(AABB(pos),false).len2() > 101.0f) pStatObj->PhysicalizeFoliage(pEntity->GetPhysics(),m_worldTM,pFoliage,0,4); } } }
virtual void ProcessEvent(EFlowEvent event, SActivationInfo *pActInfo) { switch (event) { case eFE_Initialize:{ pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID,true); } case eFE_Activate: { pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID,true); } break; case eFE_Update: { //if (IsPortActive(pActInfo, PORT_IN_ENABLE)) //{ EntityId id = GetPortEntityId(pActInfo,EIP_EntityID); EntityId parentid = GetPortEntityId(pActInfo,EIP_ParentEntityID); //IGameObject *pGameObj = gEnv->pGameFramework->GetGameObject(id); IEntity * entity = gEnv->pEntitySystem->GetEntity(id); IEntity * parententity = gEnv->pEntitySystem->GetEntity(parentid); if(entity){ Matrix34 trans; // = entity->GetWorldTM(); trans.CreateIdentity(); Matrix34 transparent; transparent.CreateIdentity(); if (parententity){ //quatParent = parententity->GetRotation(); transparent = parententity->GetWorldTM(); //CryLogAlways("Parent : [%f,%f,%f]",transparent.GetColumn0().x,transparent.GetColumn0().y,transparent.GetColumn0().z); //CryLogAlways("Parent : [%f,%f,%f]",transparent.GetColumn1().x,transparent.GetColumn1().y,transparent.GetColumn1().z); //CryLogAlways("Parent : [%f,%f,%f]",transparent.GetColumn2().x,transparent.GetColumn2().y,transparent.GetColumn2().z); //CryLogAlways("Parent : [%f,%f,%f]",transparent.GetColumn3().x,transparent.GetColumn3().y,transparent.GetColumn3().z); } Quat quat = entity->GetRotation(); quat.v = GetPortVec3( pActInfo, EIP_Rotation_XYZ); quat.w = GetPortFloat( pActInfo, EIP_Rotation_W); quat.NormalizeFast(); Vec3 position = GetPortVec3(pActInfo, EIP_Position); trans.Set(Vec3(1,1,1),quat.GetNormalized(),position); //transparent.SetTranslation(Vec3(0,0,0)); Vec3 positionlocal = transparent.TransformVector(position); trans = transparent * trans; //Matrix34 transresult ; //transresult.CreateIdentity(); //transresult.Scale trans.SetTranslation(positionlocal+parententity->GetPos()); if(trans.IsValid()){ entity->SetWorldTM(trans); } else { //CryLogAlways("[%f,%f,%f]",trans.GetColumn0().x,trans.GetColumn0().y,trans.GetColumn0().z); //CryLogAlways("[%f,%f,%f]",trans.GetColumn1().x,trans.GetColumn1().y,trans.GetColumn1().z); //CryLogAlways("[%f,%f,%f]",trans.GetColumn2().x,trans.GetColumn2().y,trans.GetColumn2().z); //CryLogAlways("[%f,%f,%f]",trans.GetColumn3().x,trans.GetColumn3().y,trans.GetColumn3().z); //CryLogAlways("rot : [%f,%f,%f,%f]",trans.GetRo); //CryLogAlways("sca : [%f,%f,%f]",trans.GetColumn0().x,trans.GetColumn0().y,trans.GetColumn0().z); } } //CryLogAlways("%i",id); //} } } }
//------------------------------------------------------------------------ void CVehicleDamageBehaviorBlowTire::Activate(bool activate) { if (activate == m_isActive) return; if (activate && m_pVehicle->IsDestroyed()) return; if (activate) { // NOTE: stance and physics position when getting into vehicles is set wrong if (!gEnv->pSystem->IsSerializingFile()) DamagePlayers(); } IVehicleComponent* pComponent = m_pVehicle->GetComponent(m_component.c_str()); if (!pComponent) return; IVehiclePart* pPart = pComponent->GetPart(0); if (!pPart) return; // if IVehicleWheel available, execute full damage behavior. if null, only apply effects IVehicleWheel* pWheel = pPart->GetIWheel(); if (activate) { IEntity* pEntity = m_pVehicle->GetEntity(); IPhysicalEntity* pPhysics = pEntity->GetPhysics(); const Matrix34& wheelTM = pPart->GetLocalTM(false); const SVehicleStatus& status = m_pVehicle->GetStatus(); if (pWheel) { const pe_cargeomparams* pParams = pWheel->GetCarGeomParams(); // handle destroyed wheel pe_params_wheel wheelParams; wheelParams.iWheel = pWheel->GetWheelIndex(); wheelParams.minFriction = wheelParams.maxFriction = 0.5f * pParams->maxFriction; pPhysics->SetParams(&wheelParams); if (IVehicleMovement* pMovement = m_pVehicle->GetMovement()) { SVehicleMovementEventParams params; params.pComponent = pComponent; params.iValue = pWheel->GetWheelIndex(); pMovement->OnEvent(IVehicleMovement::eVME_TireBlown, params); } if (status.speed > 0.1f) { // add angular impulse pe_action_impulse angImp; float amount = m_pVehicle->GetMass() * status.speed * Random(0.25f, 0.45f) * -sgn(wheelTM.GetTranslation().x); angImp.angImpulse = pEntity->GetWorldTM().TransformVector(Vec3(0,0,amount)); pPhysics->Action(&angImp); } m_aiImmobilizedTimer = m_pVehicle->SetTimer(-1, AI_IMMOBILIZED_TIME*1000, this); } if (!gEnv->pSystem->IsSerializingFile()) { // add linear impulse pe_action_impulse imp; imp.point = pPart->GetWorldTM().GetTranslation(); float amount = m_pVehicle->GetMass() * Random(0.1f, 0.15f); if (pWheel) { amount *= max(0.5f, min(10.f, status.speed)); if (status.speed < 0.1f) amount = -0.5f*amount; } else amount *= 0.5f; imp.impulse = pEntity->GetWorldTM().TransformVector(Vec3(0,0,amount)); pPhysics->Action(&imp); // effect IParticleEffect* pEffect = gEnv->pParticleManager->FindEffect(TIRE_BLOW_EFFECT); if (pEffect) { int slot = pEntity->LoadParticleEmitter(-1, pEffect); if (slot > -1) { float rotation = pWheel ? 0.5f * gf_PI * -sgn(wheelTM.GetTranslation().x) : gf_PI; Matrix34 tm = Matrix34::CreateRotationZ(rotation); tm.SetTranslation(wheelTM.GetTranslation()); pEntity->SetSlotLocalTM(slot, tm); } } // remove affected decals { Vec3 pos = pPart->GetWorldTM().GetTranslation(); AABB aabb = pPart->GetLocalBounds(); float radius = aabb.GetRadius(); Vec3 vRadius(radius,radius,radius); AABB areaBox(pos-vRadius, pos+vRadius); IRenderNode * pRenderNode = NULL; if (IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER)) pRenderNode = pRenderProxy->GetRenderNode(); gEnv->p3DEngine->DeleteDecalsInRange(&areaBox, pRenderNode); } } } else { if (pWheel) { // restore wheel properties IPhysicalEntity* pPhysics = m_pVehicle->GetEntity()->GetPhysics(); pe_params_wheel wheelParams; for (int i=0; i<m_pVehicle->GetWheelCount(); ++i) { const pe_cargeomparams* pParams = m_pVehicle->GetWheelPart(i)->GetIWheel()->GetCarGeomParams(); wheelParams.iWheel = i; wheelParams.bBlocked = 0; wheelParams.suspLenMax = pParams->lenMax; wheelParams.bDriving = pParams->bDriving; wheelParams.minFriction = pParams->minFriction; wheelParams.maxFriction = pParams->maxFriction; pPhysics->SetParams(&wheelParams); } if (IVehicleMovement* pMovement = m_pVehicle->GetMovement()) { SVehicleMovementEventParams params; params.pComponent = pComponent; params.iValue = pWheel->GetWheelIndex(); // reset the particle status pMovement->OnEvent(IVehicleMovement::eVME_TireRestored, params); } } m_aiImmobilizedTimer = -1; } m_isActive = activate; }
//------------------------------------------------------------------------ bool CItem::SetGeometry(int slot, const ItemString &name, const Vec3 &poffset, const Ang3 &aoffset, float scale, bool forceReload) { bool changedfp=false; switch(slot) { case eIGS_Arms: { if(!name || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } ResetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME); ICharacterInstance *pCharacter=0; if(name && name[0]) { if(name != m_geometry[slot]) GetEntity()->LoadCharacter(slot, name); DrawSlot(eIGS_Arms, false); pCharacter = GetEntity()->GetCharacter(eIGS_Arms); } else if(m_pForcedArms) { pCharacter = m_pForcedArms; } else { int armsId=m_stats.hand==eIH_Right?0:1; pCharacter = GetOwnerActor()?GetOwnerActor()->GetFPArms(armsId):0; } if(pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); SetCharacterAttachment(eIGS_FirstPerson, ITEM_ARMS_ATTACHMENT_NAME, pCharacter, 0); } } break; case eIGS_FirstPerson: case eIGS_ThirdPerson: default: { if(!name || forceReload) { GetEntity()->FreeSlot(slot); #ifndef ITEM_USE_SHAREDSTRING m_geometry[slot].resize(0); #else m_geometry[slot].reset(); #endif } DestroyAttachmentHelpers(slot); if(name && name[0]) { if(m_geometry[slot] != name) { const char *ext = PathUtil::GetExt(name.c_str()); if((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0)) GetEntity()->LoadCharacter(slot, name, 0); else GetEntity()->LoadGeometry(slot, name, 0, 0); changedfp=slot==eIGS_FirstPerson; } CreateAttachmentHelpers(slot); SetDefaultIdleAnimation(slot, g_pItemStrings->idle); } if(slot == eIGS_FirstPerson) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if(pCharacter) { pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE)); } } else if(slot == eIGS_Destroyed) DrawSlot(eIGS_Destroyed, false); } break; } Matrix34 slotTM; slotTM = Matrix34::CreateRotationXYZ(aoffset); slotTM.Scale(Vec3(scale, scale, scale)); slotTM.SetTranslation(poffset); GetEntity()->SetSlotLocalTM(slot, slotTM); if(changedfp && m_stats.mounted) { PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true); ForceSkinning(true); if(!m_mountparams.pivot.empty()) { Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false); Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_mountparams.pivot.c_str(), false); tm.AddTranslation(pivot); GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm); } GetEntity()->InvalidateTM(); } m_geometry[slot] = name ? name : ""; ReAttachAccessories(); return true; }
//------------------------------------------------------------------------ //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 CThrow::DoDrop() { m_pWeapon->HideItem(true); if (m_throwableId) { IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_throwableId); if (pEntity) { IPhysicalEntity *pPE = pEntity->GetPhysics(); if (pPE && (pPE->GetType() == PE_RIGID || pPE->GetType() == PE_PARTICLE)) { Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); CActor *pActor = m_pWeapon->GetOwnerActor(); IMovementController *pMC = pActor ? pActor->GetMovementController() : 0; if (pMC) { SMovementState info; pMC->GetMovementState(info); float speed = 2.5f; CPlayer *pPlayer = static_cast<CPlayer *>(m_pWeapon->GetOwnerActor()); if(info.aimDirection.z < -0.1f) { if(pPlayer) { if(SPlayerStats *pStats = static_cast<SPlayerStats *>(pPlayer->GetActorStats())) { if(pStats->grabbedHeavyEntity) { speed = 4.0f; } } } } if(CheckForIntersections(pPE, info.eyeDirection)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation() - (info.eyeDirection * 0.4f)); pEntity->SetWorldTM(newTM, ENTITY_XFORM_POS); pe_action_set_velocity asv; asv.v = (-info.eyeDirection * speed); pPE->Action(&asv); } else { pe_action_set_velocity asv; asv.v = (info.eyeDirection * speed); pPE->Action(&asv); } SEntityEvent entityEvent; entityEvent.event = ENTITY_EVENT_PICKUP; entityEvent.nParam[0] = 0; if (pPlayer) { entityEvent.nParam[1] = pPlayer->GetEntityId(); } entityEvent.fParam[0] = speed; pEntity->SendEvent( entityEvent ); } } } if (m_throwableAction) { m_throwableAction->execute(m_pWeapon); } } }