void NetChannel::GetFlowStats(float *avgInKBSec, float *avgOutKBSec) { UpdateFlow(FLOW_OUTGOING); UpdateFlow(FLOW_INCOMING); *avgInKBSec = m_flow[FLOW_OUTGOING].avgkbytespersec; *avgOutKBSec = m_flow[FLOW_INCOMING].avgkbytespersec; }
//------------------------------------------------------------------------ void CTornado::Update(SEntityUpdateContext &ctx, int updateSlot) { if (g_pGame->GetIGameFramework()->IsEditing()) return; // wandering Matrix34 m = GetEntity()->GetWorldTM(); Vec3 dir(m.GetColumn(1)); Vec3 pos(GetEntity()->GetWorldPos()); if(!gEnv->bServer) pos = m_currentPos; Vec3 wanderPos(dir * 1.414214f); float wanderStrength(1.0f); float wanderRate(0.6f); Vec3 wanderOffset; wanderOffset.SetRandomDirection(); wanderOffset.z = 0.0f; wanderOffset.NormalizeSafe(Vec3(1,0,0)); m_wanderDir += wanderOffset * wanderRate + (m_wanderDir - wanderPos) * wanderStrength; m_wanderDir = (m_wanderDir - wanderPos).GetNormalized() + wanderPos; Vec3 wanderSteer = (dir + m_wanderDir * gEnv->pTimer->GetFrameTime()); wanderSteer.z = 0; wanderSteer.NormalizeSafe(Vec3(1,0,0)); Vec3 targetSteer(0,0,0); // go to target if (m_pTargetEntity) { Vec3 target = m_pTargetEntity->GetWorldPos() - pos; if (target.GetLength() < 10.0f) { // emit target reached event SEntityEvent event( ENTITY_EVENT_SCRIPT_EVENT ); event.nParam[0] = (INT_PTR)"TargetReached"; event.nParam[1] = IEntityClass::EVT_BOOL; bool bValue = true; event.nParam[2] = (INT_PTR)&bValue; GetEntity()->SendEvent( event ); if (m_pTargetCallback) m_pTargetCallback->Done(); m_pTargetEntity = 0; m_pTargetCallback = 0; } targetSteer = (target - dir); targetSteer.z = 0; targetSteer.NormalizeSafe(Vec3(1,0,0)); } Vec3 steerDir = (0.4f * wanderSteer + 0.6f * targetSteer).GetNormalized(); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(steerDir)); pos = pos + steerDir * gEnv->pTimer->GetFrameTime() * m_wanderSpeed; pos.z = gEnv->p3DEngine->GetTerrainElevation(pos.x, pos.y); float waterLevel = gEnv->p3DEngine->GetWaterLevel(&pos); bool prevIsOnWater = m_isOnWater; m_isOnWater = (pos.z < waterLevel); if (m_isOnWater) { pos.z = waterLevel; } // raycast does not work for oceans if (prevIsOnWater != m_isOnWater && m_isOnWater) { m_pGroundEffect->SetParticleEffect("weather.tornado.water"); } else if (!m_isOnWater) { IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); Vec3 down = Vec3(0,0,-1.0f); int matID = mfx->GetDefaultSurfaceIndex(); static const int objTypes = ent_all; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(pos, (down * 5.0f), objTypes, flags, &hit, 1, GetEntity()->GetPhysics()); if (col) { matID = hit.surface_idx; } if (m_curMatID != matID) { TMFXEffectId effectId = mfx->GetEffectId("tornado", matID); SMFXResourceListPtr pList = mfx->GetResources(effectId); if (pList && pList->m_particleList) { m_pGroundEffect->SetParticleEffect(pList->m_particleList->m_particleParams.name); } m_curMatID = matID; } } if(gEnv->bServer) { tm.SetTranslation(pos); m_currentPos = pos; CHANGED_NETWORK_STATE(this, POSITION_ASPECT); GetEntity()->SetWorldTM(tm); } else { tm.SetTranslation(m_currentPos); GetEntity()->SetWorldTM(tm); } UpdateParticleEmitters(); UpdateTornadoSpline(); UpdateFlow(); }