public void Update(float dt) { double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime; float num = MathUtils.Pow(0.5f, dt); float num2 = MathUtils.Pow(0.001f, dt); m_tmpPlayers.Clear(); foreach (ComponentPlayer componentPlayer in m_subsystemPlayers.ComponentPlayers) { if (componentPlayer.ComponentHealth.Health > 0f) { m_tmpPlayers.Add(componentPlayer); } } foreach (Pickable pickable in m_pickables) { if (pickable.ToRemove) { m_pickablesToRemove.Add(pickable); } else { Block block = BlocksManager.Blocks[Terrain.ExtractContents(pickable.Value)]; int num3 = m_pickables.Count - m_pickablesToRemove.Count; float num4 = MathUtils.Lerp(300f, 90f, MathUtils.Saturate((float)num3 / 60f)); double num5 = totalElapsedGameTime - pickable.CreationTime; if (num5 > (double)num4) { pickable.ToRemove = true; } else { TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Z)); if (chunkAtCell != null && chunkAtCell.State > TerrainChunkState.InvalidContents4) { Vector3 position = pickable.Position; Vector3 vector = position + pickable.Velocity * dt; if (!pickable.FlyToPosition.HasValue && num5 > 0.5) { foreach (ComponentPlayer tmpPlayer in m_tmpPlayers) { ComponentBody componentBody = tmpPlayer.ComponentBody; Vector3 v = componentBody.Position + new Vector3(0f, 0.75f, 0f); float num6 = (v - pickable.Position).LengthSquared(); if (num6 < 3.0625f) { bool flag = Terrain.ExtractContents(pickable.Value) == 248; IInventory inventory = tmpPlayer.ComponentMiner.Inventory; if (flag || ComponentInventoryBase.FindAcquireSlotForItem(inventory, pickable.Value) >= 0) { if (num6 < 1f) { if (flag) { tmpPlayer.ComponentLevel.AddExperience(pickable.Count, playSound: true); pickable.ToRemove = true; } else { pickable.Count = ComponentInventoryBase.AcquireItems(inventory, pickable.Value, pickable.Count); if (pickable.Count == 0) { pickable.ToRemove = true; m_subsystemAudio.PlaySound("Audio/PickableCollected", 0.7f, -0.4f, pickable.Position, 2f, autoDelay: false); } } } else if (!pickable.StuckMatrix.HasValue) { pickable.FlyToPosition = v + 0.1f * MathUtils.Sqrt(num6) * componentBody.Velocity; } } } } } if (pickable.FlyToPosition.HasValue) { Vector3 v2 = pickable.FlyToPosition.Value - pickable.Position; float num7 = v2.LengthSquared(); if (num7 >= 0.25f) { pickable.Velocity = 6f * v2 / MathUtils.Sqrt(num7); } else { pickable.FlyToPosition = null; } } else { FluidBlock surfaceBlock; float? surfaceHeight; Vector2? vector2 = m_subsystemFluidBlockBehavior.CalculateFlowSpeed(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z), out surfaceBlock, out surfaceHeight); if (!pickable.StuckMatrix.HasValue) { TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position, vector, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable); if (terrainRaycastResult.HasValue) { int contents = Terrain.ExtractContents(m_subsystemTerrain.Terrain.GetCellValue(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z)); SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(contents); for (int i = 0; i < blockBehaviors.Length; i++) { blockBehaviors[i].OnHitByProjectile(terrainRaycastResult.Value.CellFace, pickable); } if (m_subsystemTerrain.Raycast(position, position, useInteractionBoxes: false, skipAirBlocks: true, (int value2, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value2)].IsCollidable).HasValue) { int num8 = Terrain.ToCell(position.X); int num9 = Terrain.ToCell(position.Y); int num10 = Terrain.ToCell(position.Z); int num11 = 0; int num12 = 0; int num13 = 0; int?num14 = null; for (int j = -3; j <= 3; j++) { for (int k = -3; k <= 3; k++) { for (int l = -3; l <= 3; l++) { if (!BlocksManager.Blocks[m_subsystemTerrain.Terrain.GetCellContents(j + num8, k + num9, l + num10)].IsCollidable) { int num15 = j * j + k * k + l * l; if (!num14.HasValue || num15 < num14.Value) { num11 = j + num8; num12 = k + num9; num13 = l + num10; num14 = num15; } } } } } if (num14.HasValue) { pickable.FlyToPosition = new Vector3(num11, num12, num13) + new Vector3(0.5f); } else { pickable.ToRemove = true; } } else { Plane plane = terrainRaycastResult.Value.CellFace.CalculatePlane(); bool flag2 = vector2.HasValue && vector2.Value != Vector2.Zero; if (plane.Normal.X != 0f) { float num16 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.Y) + MathUtils.Sqr(pickable.Velocity.Z)) > 10f) ? 0.95f : 0.25f; pickable.Velocity *= new Vector3(0f - num16, num16, num16); } if (plane.Normal.Y != 0f) { float num17 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.X) + MathUtils.Sqr(pickable.Velocity.Z)) > 10f) ? 0.95f : 0.25f; pickable.Velocity *= new Vector3(num17, 0f - num17, num17); if (flag2) { pickable.Velocity.Y += 0.1f * plane.Normal.Y; } } if (plane.Normal.Z != 0f) { float num18 = (flag2 || MathUtils.Sqrt(MathUtils.Sqr(pickable.Velocity.X) + MathUtils.Sqr(pickable.Velocity.Y)) > 10f) ? 0.95f : 0.25f; pickable.Velocity *= new Vector3(num18, num18, 0f - num18); } vector = position; } } } else { Vector3 vector3 = pickable.StuckMatrix.Value.Translation + pickable.StuckMatrix.Value.Up * block.ProjectileTipOffset; if (!m_subsystemTerrain.Raycast(vector3, vector3, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable).HasValue) { pickable.Position = pickable.StuckMatrix.Value.Translation; pickable.Velocity = Vector3.Zero; pickable.StuckMatrix = null; } } if (surfaceBlock is WaterBlock && !pickable.SplashGenerated) { m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, pickable.Position, large: false)); m_subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 6f, autoDelay: true); pickable.SplashGenerated = true; } else if (surfaceBlock is MagmaBlock && !pickable.SplashGenerated) { m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, pickable.Position, large: false)); m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 3f, autoDelay: true); pickable.ToRemove = true; pickable.SplashGenerated = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y), Terrain.ToCell(pickable.Position.Z), pickable.Value); } else if (surfaceBlock == null) { pickable.SplashGenerated = false; } if (m_subsystemTime.PeriodicGameTimeEvent(1.0, (double)(pickable.GetHashCode() % 100) / 100.0) && (m_subsystemTerrain.Terrain.GetCellContents(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z)) == 104 || m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y + 0.1f), Terrain.ToCell(pickable.Position.Z)))) { m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), pickable.Position, 3f, autoDelay: true); pickable.ToRemove = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y), Terrain.ToCell(pickable.Position.Z), pickable.Value); } if (!pickable.StuckMatrix.HasValue) { if (vector2.HasValue && surfaceHeight.HasValue) { float num19 = surfaceHeight.Value - pickable.Position.Y; float num20 = MathUtils.Saturate(3f * num19); pickable.Velocity.X += 4f * dt * (vector2.Value.X - pickable.Velocity.X); pickable.Velocity.Y -= 10f * dt; pickable.Velocity.Y += 10f * (1f / block.Density * num20) * dt; pickable.Velocity.Z += 4f * dt * (vector2.Value.Y - pickable.Velocity.Z); pickable.Velocity.Y *= num2; } else { pickable.Velocity.Y -= 10f * dt; pickable.Velocity *= num; } } } pickable.Position = vector; } } } } foreach (Pickable item in m_pickablesToRemove) { m_pickables.Remove(item); if (this.PickableRemoved != null) { this.PickableRemoved(item); } } m_pickablesToRemove.Clear(); }
public void Update(float dt) { CollisionVelocityChange = Vector3.Zero; Velocity += m_totalImpulse; m_totalImpulse = Vector3.Zero; if (m_parentBody != null || m_velocity.LengthSquared() > 9.99999944E-11f || m_directMove != Vector3.Zero) { m_stoppedTime = 0f; } else { m_stoppedTime += dt; if (m_stoppedTime > 0.5f && !Time.PeriodicEvent(0.25, 0.0)) { return; } } Vector3 position = base.Position; TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(position.X), Terrain.ToCell(position.Z)); if (chunkAtCell == null || chunkAtCell.State <= TerrainChunkState.InvalidContents4) { Velocity = Vector3.Zero; return; } m_bodiesCollisionBoxes.Clear(); FindBodiesCollisionBoxes(position, m_bodiesCollisionBoxes); m_movingBlocksCollisionBoxes.Clear(); FindMovingBlocksCollisionBoxes(position, m_movingBlocksCollisionBoxes); if (!MoveToFreeSpace()) { ComponentHealth componentHealth = base.Entity.FindComponent <ComponentHealth>(); if (componentHealth != null) { componentHealth.Injure(1f, null, ignoreInvulnerability: true, "Crushed"); } else { base.Project.RemoveEntity(base.Entity, disposeEntity: true); } return; } if (IsGravityEnabled) { m_velocity.Y -= 10f * dt; if (ImmersionFactor > 0f) { float num = ImmersionFactor * (1f + 0.03f * MathUtils.Sin((float)MathUtils.Remainder(2.0 * m_subsystemTime.GameTime, 6.2831854820251465))); m_velocity.Y += 10f * (1f / Density * num) * dt; } } float num2 = MathUtils.Saturate(AirDrag.X * dt); float num3 = MathUtils.Saturate(AirDrag.Y * dt); m_velocity.X *= 1f - num2; m_velocity.Y *= 1f - num3; m_velocity.Z *= 1f - num2; if (IsWaterDragEnabled && ImmersionFactor > 0f && ImmersionFluidBlock != null) { Vector2?vector = m_subsystemFluidBlockBehavior.CalculateFlowSpeed(Terrain.ToCell(position.X), Terrain.ToCell(position.Y), Terrain.ToCell(position.Z)); Vector3 vector2 = vector.HasValue ? new Vector3(vector.Value.X, 0f, vector.Value.Y) : Vector3.Zero; float num4 = 1f; if (ImmersionFluidBlock.FrictionFactor != 1f) { num4 = ((SimplexNoise.Noise((float)MathUtils.Remainder(6.0 * Time.FrameStartTime + (double)(GetHashCode() % 1000), 1000.0)) > 0.5f) ? ImmersionFluidBlock.FrictionFactor : 1f); } float f = MathUtils.Saturate(WaterDrag.X * num4 * ImmersionFactor * dt); float f2 = MathUtils.Saturate(WaterDrag.Y * num4 * dt); m_velocity.X = MathUtils.Lerp(m_velocity.X, vector2.X, f); m_velocity.Y = MathUtils.Lerp(m_velocity.Y, vector2.Y, f2); m_velocity.Z = MathUtils.Lerp(m_velocity.Z, vector2.Z, f); if (m_parentBody == null && vector.HasValue && !StandingOnValue.HasValue) { if (WaterTurnSpeed > 0f) { float s = MathUtils.Saturate(MathUtils.Lerp(1f, 0f, m_velocity.Length())); Vector2 vector3 = Vector2.Normalize(vector.Value) * s; base.Rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, WaterTurnSpeed * (-1f * vector3.X + 0.71f * vector3.Y) * dt); } if (WaterSwayAngle > 0f) { base.Rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitX, WaterSwayAngle * (float)MathUtils.Sin((double)(200f / Mass) * m_subsystemTime.GameTime)); } } } if (m_parentBody != null) { Vector3 v = Vector3.Transform(ParentBodyPositionOffset, m_parentBody.Rotation) + m_parentBody.Position - position; m_velocity = ((dt > 0f) ? (v / dt) : Vector3.Zero); base.Rotation = ParentBodyRotationOffset * m_parentBody.Rotation; } StandingOnValue = null; StandingOnBody = null; StandingOnVelocity = Vector3.Zero; Vector3 velocity = m_velocity; float num5 = m_velocity.Length(); if (num5 > 0f) { float x = 0.45f * MathUtils.Min(BoxSize.X, BoxSize.Y, BoxSize.Z) / num5; float num6 = dt; while (num6 > 0f) { float num7 = MathUtils.Min(num6, x); MoveWithCollision(num7, m_velocity * num7 + m_directMove); m_directMove = Vector3.Zero; num6 -= num7; } } CollisionVelocityChange = m_velocity - velocity; if (IsGroundDragEnabled && StandingOnValue.HasValue) { m_velocity = Vector3.Lerp(m_velocity, StandingOnVelocity, 6f * dt); } if (!StandingOnValue.HasValue) { IsSneaking = false; } UpdateImmersionData(); if (ImmersionFluidBlock is WaterBlock && ImmersionDepth > 0.3f && !m_fluidEffectsPlayed) { m_fluidEffectsPlayed = true; m_subsystemAudio.PlayRandomSound("Audio/WaterFallIn", m_random.Float(0.75f, 1f), m_random.Float(-0.3f, 0f), position, 4f, autoDelay: true); m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, position, (BoundingBox.Max - BoundingBox.Min).Length() > 0.8f)); } else if (ImmersionFluidBlock is MagmaBlock && ImmersionDepth > 0f && !m_fluidEffectsPlayed) { m_fluidEffectsPlayed = true; m_subsystemAudio.PlaySound("Audio/SizzleLong", 1f, 0f, position, 4f, autoDelay: true); m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, position, (BoundingBox.Max - BoundingBox.Min).Length() > 0.8f)); } else if (ImmersionFluidBlock == null) { m_fluidEffectsPlayed = false; } }