//------------------------------------------------------------------------ void CVehicleMountedWeapon::CorrectRipperEntityPosition(float timeStep) { IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if(pVehicle) { const IEntity* pVehicleEnt = pVehicle->GetEntity(); Vec3 posDiff(ZERO); IActor* pOwner = GetOwnerActor(); if (pOwner && pOwner->IsPlayer()) { CPlayer* pPlayer = static_cast<CPlayer*>(pOwner); const Matrix34& wMat = pVehicleEnt->GetWorldTM(); Vec3 vehiclePos = wMat.GetTranslation(); Vec3 currWSpaceRipUserOffset = wMat.TransformPoint(m_localRipUserOffset); posDiff = currWSpaceRipUserOffset - m_previousWSpaceOffsetPosition; // Don't want to overwrite anyone else changes with an absolute 'set' pOwner->GetEntity()->SetPos(pOwner->GetEntity()->GetWorldPos() + posDiff); m_previousWSpaceOffsetPosition = currWSpaceRipUserOffset; //Update view limit direction based on change in vehicle rotation if(pPlayer->IsClient()) { SViewLimitParams &viewLimits = pPlayer->GetActorParams().viewLimits; if(viewLimits.GetViewLimitRangeH()) //Don't do this unless we are currently horizontally constrained { Quat vehicleRotation(wMat); Quat rotationChange = vehicleRotation * m_previousVehicleRotation.GetInverted(); Vec3 viewLimitDir = rotationChange * viewLimits.GetViewLimitDir(); viewLimitDir.z = 0.f; viewLimitDir.Normalize(); viewLimits.SetViewLimit(viewLimitDir, 0.01f, 0.01f, 0.f, 0.f, SViewLimitParams::eVLS_Item); m_previousVehicleRotation = vehicleRotation; } //Reset the pitch/roll view angles over time Quat viewDirFinal = pPlayer->GetViewQuatFinal(); Ang3 viewAngles(viewDirFinal); float xAdjustment = (float)__fsel(viewAngles.x, max(-viewAngles.x, -0.5f * timeStep), min(-viewAngles.x, 0.5f * timeStep)); float yAdjustment = (float)__fsel(viewAngles.y, max(-viewAngles.y, -0.5f * timeStep), min(-viewAngles.y, 0.5f * timeStep)); if(xAdjustment || yAdjustment) { pPlayer->AddViewAngles(Ang3(xAdjustment, yAdjustment, 0.f)); } } } } }
//------------------------------------------------------------------------ void CVehicleActionDeployRope::Update(const float deltaTime) { if (!m_ropeUpperId && !m_ropeLowerId && !m_actorId) return; IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem(); assert(pActorSystem); IActor* pActor = pActorSystem->GetActor(m_actorId); if (!pActor) return; Vec3 worldPos = pActor->GetEntity()->GetWorldTM().GetTranslation(); if (IRopeRenderNode* pRopeUpper = GetRopeRenderNode(m_ropeUpperId)) { Vec3 points[2]; points[0] = m_pRopeHelper->GetWorldTM().GetTranslation(); points[1] = worldPos; pRopeUpper->SetPoints(points, 2); float lenghtLeft = max(0.0f, g_ropeLenght - (points[0].z - points[1].z)); if (IRopeRenderNode* pRopeLower = GetRopeRenderNode(m_ropeLowerId)) { Vec3 points[2]; points[0] = worldPos; points[1] = Vec3(worldPos.x, worldPos.y, worldPos.z - lenghtLeft); pRopeLower->SetPoints(points, 2); } } }
//------------------------------------------------------------------------ void CVehicleActionDeployRope::OnVehicleEvent(EVehicleEvent event, const SVehicleEventParams& params) { if (event == eVE_PassengerExit && params.iParam == m_seatId) { IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem(); assert(pActorSystem); IActor* pActor = pActorSystem->GetActor(params.entityId); if (!pActor) { assert(pActor); return; } m_actorId = pActor->GetEntityId(); DeployRope(); AttachOnRope(pActor->GetEntity()); } else if (event == eVE_Destroyed) { if (m_ropeUpperId) { gEnv->pEntitySystem->RemoveEntity(m_ropeUpperId); m_ropeUpperId = 0; } if (m_ropeLowerId) { gEnv->pEntitySystem->RemoveEntity(m_ropeLowerId); m_ropeLowerId = 0; } } }
void CMFXForceFeedbackEffect::Execute(SMFXRunTimeEffectParams& params) { FUNCTION_PROFILER(gEnv->pSystem, PROFILE_ACTION); if (params.playflags & MFX_PLAY_FORCEFEEDBACK) { float distanceToPlayerSqr = FLT_MAX; IActor *pClientActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); if (pClientActor) { distanceToPlayerSqr = (pClientActor->GetEntity()->GetWorldPos() - params.pos).GetLengthSquared(); } const float testDistanceSqr = clamp_tpl(distanceToPlayerSqr, m_forceFeedbackParams.intensityFallOffMinDistanceSqr, m_forceFeedbackParams.intensityFallOffMaxDistanceSqr); const float minMaxDiffSqr = m_forceFeedbackParams.intensityFallOffMaxDistanceSqr - m_forceFeedbackParams.intensityFallOffMinDistanceSqr; float effectIntensity = (float)__fsel(-minMaxDiffSqr, 0.0f, 1.0f - (testDistanceSqr - m_forceFeedbackParams.intensityFallOffMinDistanceSqr) / (minMaxDiffSqr + FLT_EPSILON)); effectIntensity *= effectIntensity; if (effectIntensity > 0.01f) { IForceFeedbackSystem* pForceFeedback = CCryAction::GetCryAction()->GetIForceFeedbackSystem(); assert(pForceFeedback); ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName(m_forceFeedbackParams.forceFeedbackEventName.c_str()); pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(effectIntensity, 0.0f)); } } }
void CDevMode::GotoTagPoint( int i ) { std::vector<STagFileEntry> tags = LoadTagFile(); if (tags.size() > size_t(i)) { STagFileEntry ent = tags[i]; IActor * pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return; IEntity * pEntity = pActor->GetEntity(); Quat rot; Vec3 pos = ent.pos; // pos loaded is a camera position, we must convert it into the player position. if (IMovementController * pMC = pActor->GetMovementController()) { SMovementState ms; pMC->GetMovementState(ms); pos -= (ms.eyePosition-ms.pos); } rot.SetRotationXYZ( ent.ang ); Vec3 scale = pEntity->GetScale(); pEntity->SetPosRotScale( pos, rot, scale ); pActor->SetViewRotation( rot ); } }
bool CGameRulesSpawningBase::CanPlayerSpawnThisRound(const EntityId playerId) const { bool allowed=true; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId); if (pActor->IsPlayer()) { CGameRules *pGameRules = g_pGame->GetGameRules(); IGameRulesPlayerStatsModule *playerStats = pGameRules ? pGameRules->GetPlayerStatsModule() : NULL; if (playerStats) { const SGameRulesPlayerStat *stats = playerStats->GetPlayerStats(playerId); if (stats) { if (stats->flags & SGameRulesPlayerStat::PLYSTATFL_CANTSPAWNTHISROUND) { allowed=false; } } } } CryLog("CGameRulesSpawningBase::CanPlayerSpawnThisRound() player=%s allowed=%d", pActor->GetEntity()->GetName(), allowed); return allowed; }
//------------------------------------------------------------------------ void CProjectile::Update(SEntityUpdateContext &ctx, int updateSlot) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if (updateSlot!=0) return; float color[4] = {1,1,1,1}; bool bDebug = g_pGameCVars->i_debug_projectiles > 0; if(bDebug) gEnv->pRenderer->Draw2dLabel(50,15,2.0f,color,false,"Projectile: %s",GetEntity()->GetClass()->GetName()); Vec3 pos = GetEntity()->GetWorldPos(); ScaledEffect(m_pAmmoParams->pScaledEffect); // update whiz if(m_pAmmoParams->pWhiz) { if (m_whizSoundId == INVALID_SOUNDID) { IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor(); if (pActor && (m_ownerId != pActor->GetEntityId())) { float probability = 0.85f; if (Random()<=probability) { Lineseg line(m_last, pos); Vec3 player = pActor->GetEntity()->GetWorldPos(); float t; float distanceSq=Distance::Point_LinesegSq(player, line, t); if (distanceSq < 4.7f*4.7f && (t>=0.0f && t<=1.0f)) { if (distanceSq >= 0.65*0.65) { Sphere s; s.center = player; s.radius = 4.7f; Vec3 entry,exit; int intersect=Intersect::Lineseg_Sphere(line, s, entry,exit); if (intersect==0x1 || intersect==0x3) // one entry or one entry and one exit WhizSound(true, entry, (pos-m_last).GetNormalized()); } } } } } } if (m_trailSoundId==INVALID_SOUNDID) TrailSound(true); m_totalLifetime += ctx.fFrameTime; m_last = pos; }
void CMFXParticleEffect::Execute(const SMFXRunTimeEffectParams& params) { FUNCTION_PROFILER(gEnv->pSystem, PROFILE_ACTION); Vec3 pos = params.pos; Vec3 dir = ZERO; Vec3 inDir = params.dir[0]; Vec3 reverso = inDir * -1.0f; switch (m_particleParams.directionType) { case SMFXParticleParams::eDT_Normal: dir = params.normal; break; case SMFXParticleParams::eDT_Ricochet: dir = reverso.GetRotated(params.normal, gf_PI).normalize(); break; default: dir = params.normal; break; } bool tryToAttachEffect = (CMaterialEffectsCVars::Get().mfx_EnableAttachedEffects != 0); float distToPlayer = 0.f; IActor *pClientActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); if (pClientActor) { distToPlayer = (pClientActor->GetEntity()->GetWorldPos() - params.pos).GetLength(); tryToAttachEffect = tryToAttachEffect && (pClientActor->GetEntityId() != params.trg); } SMFXParticleEntries::const_iterator end = m_particleParams.m_entries.end(); for (SMFXParticleEntries::const_iterator it = m_particleParams.m_entries.begin(); it!=end; ++it) { // choose effect based on distance if ((it->maxdist == 0.f) || (distToPlayer <= it->maxdist) && !it->name.empty() ) { IParticleEffect *pParticle = gEnv->pParticleManager->FindEffect(it->name.c_str()); if (pParticle) { const float pfx_minscale = (it->minscale != 0.f) ? it->minscale : CMaterialEffectsCVars::Get().mfx_pfx_minScale; const float pfx_maxscale = (it->maxscale != 0.f) ? it->maxscale : CMaterialEffectsCVars::Get().mfx_pfx_maxScale; const float pfx_maxdist = (it->maxscaledist != 0.f) ? it->maxscaledist : CMaterialEffectsCVars::Get().mfx_pfx_maxDist; const float truscale = pfx_minscale + ((pfx_maxscale - pfx_minscale) * (distToPlayer!=0.f ? min(1.0f, distToPlayer/pfx_maxdist) : 1.f)); bool particleSpawnedAndAttached = tryToAttachEffect ? AttachToTarget(*it, params, pParticle, dir, truscale) : false; // If not attached, just spawn the particle if (particleSpawnedAndAttached == false) { pParticle->Spawn( true, IParticleEffect::ParticleLoc(pos, dir, truscale) ); } } break; } } }
EntityId Mouse::getEntityUnderCursor() { IRenderer* pRenderer = gEnv->pRenderer; if(!gEnv->pHardwareMouse || !pRenderer || !gEnv->p3DEngine || !gEnv->pSystem || !gEnv->pEntitySystem || !g_pGame->GetIGameFramework()) return false; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if (!pClientActor) return false; float mx, my, cx, cy, cz = 0.0f; mx = m_x; my = pRenderer->GetHeight() - m_y; pRenderer->UnProjectFromScreen(mx, my, 0.0f, &cx, &cy, &cz); IPhysicalEntity *pPhysicalEnt = pClientActor->GetEntity() ? pClientActor->GetEntity()->GetPhysics() : NULL; if(!pPhysicalEnt) return false; entity_query_flags queryFlags = ent_all; // see physicsnterface.h for details static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; float fRange = gEnv->p3DEngine->GetMaxViewDistance(); Vec3 vCamPos = gEnv->pSystem->GetViewCamera().GetPosition(); Vec3 vDir = (Vec3(cx, cy, cz) - vCamPos).GetNormalizedSafe(); static ray_hit hit; if (gEnv->pPhysicalWorld && gEnv->pPhysicalWorld->RayWorldIntersection(vCamPos, vDir * fRange, queryFlags, flags, &hit, 1, pPhysicalEnt)) { CryLogAlways("Entity position: %f, %f, %f", hit.pt.x, hit.pt.y, hit.pt.z); if (IEntity* pEntity = gEnv->pEntitySystem->GetEntityFromPhysics(hit.pCollider)) { CryLogAlways("Entity name:", pEntity->GetName()); return pEntity->GetId(); } } return 0; }
bool Mouse::getWorldCoords( float& x, float& y, float& z ) { IRenderer* pRenderer = gEnv->pRenderer; if(!gEnv->pHardwareMouse || !pRenderer || !gEnv->p3DEngine || !gEnv->pSystem || !gEnv->pEntitySystem || !g_pGame->GetIGameFramework()) return false; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if (!pClientActor) return false; float mx, my, cx, cy, cz = 0.0f; mx = m_x - 4; my = pRenderer->GetHeight() - m_y + 10; pRenderer->UnProjectFromScreen(mx, my, 0.0f, &cx, &cy, &cz); IPhysicalEntity *pPhysicalEnt = pClientActor->GetEntity() ? pClientActor->GetEntity()->GetPhysics() : NULL; if(!pPhysicalEnt) return false; entity_query_flags queryFlags = ent_terrain; // see physicsnterface.h for details static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; float fRange = gEnv->p3DEngine->GetMaxViewDistance(); Vec3 vCamPos = gEnv->pSystem->GetViewCamera().GetPosition(); Vec3 vDir = (Vec3(cx, cy, cz) - vCamPos).GetNormalizedSafe(); static ray_hit hit; if (gEnv->pPhysicalWorld && gEnv->pPhysicalWorld->RayWorldIntersection(vCamPos, vDir * fRange, queryFlags, flags, &hit, 1, pPhysicalEnt)) { x = hit.pt.x; y = hit.pt.y; z = hit.pt.z; return true; } return false; }
void CTornado::OutputDistance() { IActor *pClient = g_pGame->GetIGameFramework()->GetClientActor(); if (!pClient) return; Vec3 deltaToClient(pClient->GetEntity()->GetWorldPos() - GetEntity()->GetWorldPos()); deltaToClient.z = 0; EntityScripts::CallScriptFunction(GetEntity(), GetEntity()->GetScriptTable(), "ScriptEvent", "outputDistance", deltaToClient.len(), 0); }
//------------------------------------------------------------------------ IEntity * CEditorGame::GetPlayer() { IGameFramework * pGameFramework = m_pGame->GetIGameFramework(); if(!m_pGame) return 0; IActor * pActor = pGameFramework->GetClientActor(); return pActor? pActor->GetEntity() : NULL; }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CGameRules, SvHostMigrationRequestSetup) { uint16 channelId = m_pGameFramework->GetGameChannelId(pNetChannel); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActorByChannelId(channelId); CRY_ASSERT(pActor); CryLog("SvHostMigrationRequestSetup, unpacking setup for player '%s', channel=%i", pActor->GetEntity()->GetName(), channelId); // if (pActor->IsDead() && (params.m_timeToAutoRevive > 0.f)) // { // IGameRulesSpawningModule *pSpawningModule = GetSpawningModule(); // pSpawningModule->HostMigrationInsertIntoReviveQueue(pActor->GetEntityId(), params.m_timeToAutoRevive * 1000.f); // } return true; }
//------------------------------------------------------------------------ void CEditorGame::SetPlayerPosAng(Vec3 pos,Vec3 viewDir) { IActor * pClActor = m_pGame->GetIGameFramework()->GetClientActor(); if (pClActor /*&& m_bGameMode*/) { // pos coming from editor is a camera position, we must convert it into the player position by subtructing eye height. IEntity *myPlayer = pClActor->GetEntity(); if (myPlayer) { pe_player_dimensions dim; dim.heightEye = 0; if (myPlayer->GetPhysics()) { myPlayer->GetPhysics()->GetParams( &dim ); pos.z = pos.z - dim.heightEye; } } pClActor->GetEntity()->SetPosRotScale( pos,Quat::CreateRotationVDir(viewDir),Vec3(1,1,1),ENTITY_XFORM_EDITOR|ENTITY_XFORM_POS|ENTITY_XFORM_ROT|ENTITY_XFORM_SCL); } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: { IActor* pActor = GetAIActor(pActInfo); if (!pActor) break; IEntity* pEnt = pActor->GetEntity(); if (!pEnt) break; HSCRIPTFUNCTION func = 0; int ret = 0; IScriptTable* pTable = pEnt->GetScriptTable(); if (!pTable) break; if (IsPortActive(pActInfo, 1) && pTable->GetValue("GrabObject", func)) { IEntity* pObj = gEnv->pEntitySystem->GetEntity( GetPortEntityId(pActInfo, 0) ); if (pObj) { IScriptTable* pObjTable = pObj->GetScriptTable(); Script::CallReturn(gEnv->pScriptSystem, func, pTable, pObjTable, ret); } ActivateOutput(pActInfo, 0, ret); } else if (IsPortActive(pActInfo, 2) && pTable->GetValue("DropObject", func)) { bool bThrow = GetPortBool(pActInfo, 3); Script::CallReturn(gEnv->pScriptSystem, func, pTable, bThrow, ret); ActivateOutput(pActInfo, 0, ret); } if (pTable->GetValue("GetGrabbedObject", func)) { ScriptHandle sH(0); Script::CallReturn(gEnv->pScriptSystem, func, pTable, sH); ActivateOutput(pActInfo, 1, EntityId(sH.n)); } if(func) gEnv->pScriptSystem->ReleaseFunc(func); break; } } }
void CFlowConvoyNode::SetPlayerMaxVelGround(float vel) { IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); if(pPlayerActor) { IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics(); if(pPhysicalEntity) { pe_player_dynamics ppd; ppd.maxVelGround=vel; pPhysicalEntity->SetParams(&ppd); } } }
int CFlowConvoyNode::GetCoachIndexPlayerIsOn2() { IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); Vec3 playerPos=pPlayerActor->GetEntity()->GetWorldPos(); for (size_t i = 0; i < m_coaches.size(); ++i) { AABB bbox; m_coaches[i].m_pEntity->GetLocalBounds(bbox); Vec3 localpos=m_coaches[i].m_pEntity->GetWorldTM().GetInverted().TransformPoint(playerPos); if(bbox.min.x<=localpos.x && bbox.min.y<=localpos.y && bbox.max.x>=localpos.x && bbox.max.y>=localpos.y) return i; } return -1; }
//------------------------------------------------------------------------ bool CEditorGame::SetGameMode(bool bGameMode) { m_bGameMode = bGameMode; bool on = bGameMode; if (s_pEditorGameMode->GetIVal() == 0) on = m_bPlayer; bool ok = ConfigureNetContext( on ); if (ok) { if(gEnv->IsEditor()) { m_pGame->EditorResetGame(bGameMode); } IGameFramework * pGameFramework = m_pGame->GetIGameFramework(); pGameFramework->OnEditorSetGameMode(bGameMode); IActor *pActor = m_pGame->GetIGameFramework()->GetClientActor(); if (pActor) { if (bGameMode) { // Revive actor in its current location (it will be moved to the editor viewpoint location later) const Vec3 pos = pActor->GetEntity()->GetWorldPos(); const Quat rot = pActor->GetEntity()->GetWorldRotation(); const int teamId = g_pGame->GetGameRules()->GetTeam(pActor->GetEntityId()); g_pGame->GetGameRules()->RevivePlayer(pActor, pos, rot, teamId); } } } else { GameWarning("Failed configuring net context"); } return ok; }
float CFlowConvoyNode::GetPlayerMaxVelGround() { IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); if(pPlayerActor) { IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics(); if(pPhysicalEntity) { pe_player_dynamics ppd; pPhysicalEntity->GetParams(&ppd); return ppd.maxVelGround; } } return 0; }
//------------------------------------------------------------------------ void CShake::Update(SEntityUpdateContext &ctx, int updateSlot) { IActor *pClient = g_pGame->GetIGameFramework()->GetClientActor(); if (pClient) { float dist2ToClient((pClient->GetEntity()->GetWorldPos() - GetEntity()->GetWorldPos()).len2()); float maxRange(m_radius * m_radius); if (dist2ToClient<maxRange) { IView *pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetViewByEntityId(pClient->GetEntityId()); if (pView) { float strength = (1.0f - (dist2ToClient/maxRange)) * 0.5f; pView->SetViewShake(ZERO,Vec3(m_shake*strength,0,m_shake*strength),0.1f,0.0225f,1.5f,1); } } } }
//------------------------------------------------------------------------ // Example on how to use this function: // // local params = // { // name = "dude", // class = "CSpectator", // position = {x=0, y=0, z=0}, // rotation = {x=0, y=0, z=0}, // scale = {x=1, y=1, z=1} // } // // Actor.CreateActor( channelId, params ); // int CScriptBind_ActorSystem::CreateActor( IFunctionHandler *pH, int channelId, SmartScriptTable actorParams ) { CRY_ASSERT( m_pGameFW->GetIActorSystem() != NULL ); const char *name; const char *className; Vec3 position; Vec3 scale; Vec3 rotation; #define GET_VALUE_FROM_CHAIN( valName, val, chain ) \ if ( !chain.GetValue( valName, val ) ) \ { \ CryWarning( VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CreateActor failed because <%s> field not specified", valName ); \ bFailed = true; \ } // The following code had to be enclosed in a bracket because // CScriptSetGetChain needs to be declared statically and also needs to // be destructed before EndFunction bool bFailed = false; do { CScriptSetGetChain actorChain( actorParams ); GET_VALUE_FROM_CHAIN( "name", name, actorChain ); GET_VALUE_FROM_CHAIN( "class", className, actorChain ); GET_VALUE_FROM_CHAIN( "position", position, actorChain ); GET_VALUE_FROM_CHAIN( "rotation", rotation, actorChain ); GET_VALUE_FROM_CHAIN( "scale", scale, actorChain ); } while ( false ); if ( bFailed ) return pH->EndFunction(false); Quat q; q.SetRotationXYZ( Ang3(rotation) ); IActor* pActor = m_pGameFW->GetIActorSystem()->CreateActor( channelId, name, className, position, q, scale ); if (pActor == NULL) return pH->EndFunction(); else return pH->EndFunction(pActor->GetEntity()->GetScriptTable()); }
//------------------------------------------------------------------------ void CGameRules::ClientHit(const HitInfo &hitInfo) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); IEntity *pTarget = m_pEntitySystem->GetEntity(hitInfo.targetId); IEntity *pShooter = m_pEntitySystem->GetEntity(hitInfo.shooterId); IVehicle *pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(hitInfo.targetId); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); bool dead = pActor?(pActor->GetHealth()<=0):false; if((pClientActor && pClientActor->GetEntity()==pShooter) && pTarget && (pVehicle || pActor) && !dead) { SAFE_HUD_FUNC(GetCrosshair()->CrosshairHit()); SAFE_HUD_FUNC(GetTagNames()->AddEnemyTagName(pActor?pActor->GetEntityId():pVehicle->GetEntityId())); } if(pActor == pClientActor) if (gEnv->pInput) gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f * hitInfo.damage * 0.01f, hitInfo.damage * 0.02f, 0.0f)); /* if (gEnv->pAISystem && !gEnv->bMultiplayer) { static int htMelee = GetHitTypeId("melee"); if (pShooter && hitInfo.type != htMelee) { ISurfaceType *pSurfaceType = GetHitMaterial(hitInfo.material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 5.0f; gEnv->pAISystem->BulletHitEvent(hitInfo.pos, radius, pShooter->GetAI()); } }*/ CreateScriptHitInfo(m_scriptHitInfo, hitInfo); CallScript(m_clientStateScript, "OnHit", m_scriptHitInfo); bool backface = hitInfo.dir.Dot(hitInfo.normal)>0; if (!hitInfo.remote && hitInfo.targetId && !backface) { if (!gEnv->bServer) GetGameObject()->InvokeRMI(SvRequestHit(), hitInfo, eRMI_ToServer); else ServerHit(hitInfo); } }
//------------------------------------------------------------------------ bool CVehicleActionDeployRope::DeployRope() { IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem(); assert(pActorSystem); IActor* pActor = pActorSystem->GetActor(m_actorId); if (!pActor) return false; Vec3 upperPos = m_pRopeHelper->GetWorldTM().GetTranslation(); Vec3 lowerPos(upperPos.x, upperPos.y, upperPos.z - g_ropeLenght); m_ropeUpperId = CreateRope(m_pVehicle->GetEntity()->GetPhysics(), upperPos, upperPos); m_ropeLowerId = CreateRope(pActor->GetEntity()->GetPhysics(), upperPos, lowerPos); m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate); return true; }
//------------------------------------------------------------------------ Vec3 CVehicleViewFirstPerson::GetWorldPosGoal() { Vec3 vehiclePos; if (m_pHelper) { vehiclePos = m_pHelper->GetVehicleSpaceTranslation(); } else if(!m_sCharacterBoneName.empty()) { Vec3 bonePos; IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_pSeat->GetPassenger()); ICharacterInstance* pCharacter = pEntity ? pEntity->GetCharacter(0) : NULL; if(pCharacter) { IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton(); uint32 id = rIDefaultSkeleton.GetJointIDByName(m_sCharacterBoneName); uint32 numJoints = rIDefaultSkeleton.GetJointCount(); if(numJoints > id) { bonePos = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t; } } vehiclePos = pEntity ? pEntity->GetWorldTM() * bonePos : Vec3(0,0,0); return vehiclePos; } else { IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId); CRY_ASSERT(pActor); vehiclePos = pActor->GetLocalEyePos() + m_offset; IEntity* pActorEntity = pActor->GetEntity(); const Matrix34& slotTM = pActorEntity->GetSlotLocalTM(0, false); vehiclePos = pActorEntity->GetLocalTM() * slotTM * vehiclePos; } return m_pVehicle->GetEntity()->GetWorldTM() * vehiclePos; }
int CFlowConvoyNode::GetCoachIndexPlayerIsOn() { IPhysicalEntity *pGroundCollider=NULL; IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); // if player use a mounted weapon on the train, the GroundCollider check not good if(m_coachIndex>=0) {//player can catch mounted weapon on the train if he were on it before CItem *pCurrentItem=static_cast<CItem *>(pPlayerActor->GetCurrentItem()); if ( pCurrentItem != NULL && pCurrentItem->IsMounted()) return m_coachIndex; // give back the last m_coachIndex, it should be valid } IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics(); if (pPhysicalEntity) { pe_status_living livStat; if(pPhysicalEntity->GetStatus(&livStat)) pGroundCollider=livStat.pGroundCollider; } if(!pGroundCollider) return -1; for (size_t i = 0; i < m_coaches.size(); ++i) { if(m_coaches[i].m_pEntity->GetPhysics()==pGroundCollider) return i; else {//attached objects IEntity *pCoachEntity=m_coaches[i].m_pEntity; for (int j = 0; j < pCoachEntity->GetChildCount(); ++j) { if(pCoachEntity->GetChild(j)->GetPhysics()==pGroundCollider) return i; } } } return -1; }
void CHeavyMountedWeapon::InitClient(int channelId) { CWeapon::InitClient(channelId); //Avoid calling CHeavyWeapon::InitClient as mounted weapons need special case logic to handle late joiners (Based on the ripoff state) if(m_rippingOff || m_rippedOff) { IActor *pActor = GetOwnerActor(); if(pActor) { EntityId ownerID = pActor->GetEntity()->GetId(); GetGameObject()->InvokeRMIWithDependentObject(ClRipOff(), BaseClass::SHeavyWeaponUserParams(ownerID), eRMI_ToClientChannel, ownerID, channelId); } else { GetGameObject()->InvokeRMI(ClDropped(), EmptyParams(), eRMI_ToClientChannel, channelId); } } if(m_bIsHighlighted && !m_rippingOff) { GetGameObject()->InvokeRMI(ClHeavyWeaponHighlighted(), SNoParams(), eRMI_ToClientChannel, channelId); } }
//------------------------------------------------------------------------ void CVehicleSeatActionPassengerIK::Update(float frameTime) { if (!m_passengerId) return; IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId); if (!pActor) { CRY_ASSERT(!"Invalid entity id for the actor id, Actor System didn't know it"); return; } if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0)) { ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim(); CRY_ASSERT(pSkeletonAnim); if (pSkeletonAnim->GetNumAnimsInFIFO(0) >= 1) { const CAnimation& anim = pSkeletonAnim->GetAnimFromFIFO(0, 0); const uint16 loopCount = anim.GetLoop(); const f32 animationTime = pSkeletonAnim->GetAnimationNormalizedTime( &anim ); if (!m_waitShortlyBeforeStarting || (loopCount > 0 || animationTime > 0.9f)) { for (TIKLimbVector::iterator ite = m_ikLimbs.begin(); ite != m_ikLimbs.end(); ++ite) { const SIKLimb& limb = *ite; Vec3 helperPos = limb.pHelper->GetWorldSpaceTranslation(); pActor->SetIKPos(limb.limbName.c_str(), helperPos, 1); } } } } }
//------------------------------------------- void CGameRules::ProcessClientExplosionScreenFX(const ExplosionInfo &explosionInfo) { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if (pClientActor) { //Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); //Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) CActor *pActor = (CActor *)pClientActor; SMovementState state; if (IMovementController *pMV = pActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; eyeToExplosion.Normalize(); bool inFOV = (state.eyeDirection.Dot(eyeToExplosion) > 0.68f); // if in a vehicle eyeDirection is wrong if(pActor && pActor->GetLinkedVehicle()) { Vec3 eyeDir = static_cast<CPlayer*>(pActor)->GetVehicleViewDir(); inFOV = (eyeDir.Dot(eyeToExplosion) > 0.68f); } //All explosions have radial blur (default 30m radius, to make Sean happy =)) float maxBlurDistance = (explosionInfo.maxblurdistance>0.0f)?explosionInfo.maxblurdistance:30.0f; if (maxBlurDistance>0.0f && g_pGameCVars->g_radialBlur>0.0f && m_explosionScreenFX && explosionInfo.radius>0.5f) { if (inFOV && dist < maxBlurDistance) { ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1); //If there was no obstacle between flashbang grenade and player if(!col) { if (CScreenEffects* pSE = pActor->GetScreenEffects()) { float blurRadius = (-1.0f/maxBlurDistance)*dist + 1.0f; gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Radius", blurRadius); gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Amount", 1.0f); IBlendedEffect *pBlur = CBlendedEffect<CPostProcessEffect>::Create(CPostProcessEffect(pClientActor->GetEntityId(),"FilterRadialBlurring_Amount", 0.0f)); IBlendType *pLinear = CBlendType<CLinearBlend>::Create(CLinearBlend(1.0f)); pSE->StartBlend(pBlur, pLinear, 1.0f, CScreenEffects::eSFX_GID_RBlur); pSE->SetUpdateCoords("FilterRadialBlurring_ScreenPosX","FilterRadialBlurring_ScreenPosY", explosionInfo.pos); } float distAmp = 1.0f - (dist / maxBlurDistance); if (gEnv->pInput) gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f, distAmp*3.0f, 0.0f)); } } } //Flashbang effect if(dist<explosionInfo.radius && inFOV && (!strcmp(explosionInfo.effect_class,"flashbang") || !strcmp(explosionInfo.effect_class,"FlashbangAI"))) { ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1); //If there was no obstacle between flashbang grenade and player if(!col) { float power = explosionInfo.flashbangScale; power *= max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = (eyeToExplosion.Dot(state.eyeDirection.normalize()) + 1)*0.5f; power *= lookingAt; SAFE_GAMEAUDIO_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION,MIN(power*40.0f,100.0f))); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", 1.0f + (power * 4)); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount",explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", (power * 2)); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1); } } else if(inFOV && (dist < explosionInfo.radius)) { if (explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { //Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; pActor->AddAngularImpulse(Ang3(Random(-angleX*0.5f,angleX),0.0f,Random(-angleZ,angleZ)),0.0f,dt*2.0f); } } float fDist2=(pClientActor->GetEntity()->GetWorldPos()-explosionInfo.pos).len2(); if (fDist2<250.0f*250.0f) { if (fDist2<sqr(SAFE_GAMEAUDIO_BATTLESTATUS_FUNC_RET(GetBattleRange()))) SAFE_GAMEAUDIO_BATTLESTATUS_FUNC(TickBattleStatus(1.0f)); } } }
//-------------------------------------------------------------------------------------------------- // Name: SpawnScreenExplosionEffect // Desc: Spawns screen explosion effect //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer) { // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX() const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo; if(explosionInfo.pressure < 1.0f) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor != NULL && !pClientActor->IsDead()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f; // Flashbang friends and self?... if(hasFlashBangEffect) { bool flashBangSelf = true; bool flashBangFriends = false; #ifndef _RELEASE flashBangSelf = g_pGameCVars->g_flashBangSelf != 0; flashBangFriends = g_pGameCVars->g_flashBangFriends != 0; #endif bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId; if((!flashBangSelf && ownFlashBang) || // FlashBang self? ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends? { return; } } // Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) SMovementState state; if(IMovementController *pMV = pClientActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection; eyeToExplosion.Normalize(); float eyeDirectionDP = eyeDir.Dot(eyeToExplosion); bool inFOV = (eyeDirectionDP > 0.68f); // All explosions have radial blur (default 30m radius) const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f; if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f)) { if (inFOV && (dist < maxBlurDistance)) { const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0); } } // Flashbang effect if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) || (inFOV && (dist < explosionInfo.radius)))) { ray_hit hit; const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; const int intersectionMaxHits = 1; int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos, -eyeToExplosion*dist, intersectionObjTypes, intersectionFlags, &hit, intersectionMaxHits); // If there was no obstacle between flashbang grenade and player if(!collision) { bool enabled = true; if(enabled) { CCCPOINT (FlashBang_Explode_BlindLocalPlayer); float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f); float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player"); SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); NET_BATTLECHATTER(BC_Blinded, pPlayer); if(pClientActor->GetEntityId() == explosionInfo.shooterId) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf); } else { g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time); } pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f); CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount); } } } else { CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry); } } else if(inFOV && (dist < explosionInfo.radius)) { if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { // Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; if (pClientActor) { static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f); } } } } }//-------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------ void CProjectile::Ricochet(EventPhysCollision *pCollision) { IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor(); if (!pActor) return; Vec3 dir=pCollision->vloc[0]; dir.NormalizeSafe(); float dot=pCollision->n.Dot(dir); if (dot>=0.0f) // backface return; float b=0,f=0; uint matPierceability=0; if (!gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], b, f, matPierceability)) return; matPierceability&=sf_pierceable_mask; float probability=0.25+0.25*(MAX(0,7-matPierceability)/7.0f); if ((matPierceability && matPierceability>=8) || Random()>probability) return; f32 cosine = dir.Dot(-pCollision->n); if (cosine>1.0f)cosine=1.0f; if (cosine<-1.0f) cosine=-1.0f; float angle=RAD2DEG( cry_fabsf(cry_acosf(cosine)) ); if (angle<10.0f) return; Vec3 ricochetDir = -2.0f*dot*pCollision->n+dir; ricochetDir.NormalizeSafe(); Ang3 angles=Ang3::GetAnglesXYZ(Matrix33::CreateRotationVDir(ricochetDir)); float rx=Random()-0.5f; float rz=Random()-0.5f; angles.x+=rx*DEG2RAD(10.0f); angles.z+=rz*DEG2RAD(10.0f); ricochetDir=Matrix33::CreateRotationXYZ(angles).GetColumn(1).normalized(); Lineseg line(pCollision->pt, pCollision->pt+ricochetDir*20.0f); Vec3 player = pActor->GetEntity()->GetWorldPos(); float t; float distanceSq=Distance::Point_LinesegSq(player, line, t); if (distanceSq < 7.5*7.5 && (t>=0.0f && t<=1.0f)) { if (distanceSq >= 0.25*0.25) { Sphere s; s.center = player; s.radius = 6.0f; Vec3 entry,exit; int intersect=Intersect::Lineseg_Sphere(line, s, entry,exit); if (intersect) // one entry or one entry and one exit { if (intersect==0x2) entry=pCollision->pt; RicochetSound(entry, ricochetDir); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entry, ColorB(255, 255, 255, 255), entry+ricochetDir, ColorB(255, 255, 255, 255), 2); } } } }