public void Update(float dt) { double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime; foreach (Projectile projectile in m_projectiles) { if (projectile.ToRemove) { m_projectilesToRemove.Add(projectile); } else { Block block = BlocksManager.Blocks[Terrain.ExtractContents(projectile.Value)]; if (totalElapsedGameTime - projectile.CreationTime > 40.0) { projectile.ToRemove = true; } TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Z)); if (chunkAtCell == null || chunkAtCell.State <= TerrainChunkState.InvalidContents4) { projectile.NoChunk = true; if (projectile.TrailParticleSystem != null) { projectile.TrailParticleSystem.IsStopped = true; } } else { projectile.NoChunk = false; Vector3 position = projectile.Position; Vector3 vector = position + projectile.Velocity * dt; Vector3 v = block.ProjectileTipOffset * Vector3.Normalize(projectile.Velocity); BodyRaycastResult? bodyRaycastResult = m_subsystemBodies.Raycast(position + v, vector + v, 0.2f, (ComponentBody body, float distance) => true); TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position + v, vector + v, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable); bool flag = block.DisintegratesOnHit; if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue) { CellFace? cellFace = terrainRaycastResult.HasValue ? new CellFace?(terrainRaycastResult.Value.CellFace) : null; ComponentBody componentBody = bodyRaycastResult.HasValue ? bodyRaycastResult.Value.ComponentBody : null; SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(projectile.Value)); for (int i = 0; i < blockBehaviors.Length; i++) { flag |= blockBehaviors[i].OnHitAsProjectile(cellFace, componentBody, projectile); } projectile.ToRemove |= flag; } Vector3?vector2 = null; if (bodyRaycastResult.HasValue && (!terrainRaycastResult.HasValue || bodyRaycastResult.Value.Distance < terrainRaycastResult.Value.Distance)) { if (projectile.Velocity.Length() > 10f) { ComponentMiner.AttackBody(bodyRaycastResult.Value.ComponentBody, projectile.Owner, bodyRaycastResult.Value.HitPoint(), Vector3.Normalize(projectile.Velocity), block.GetProjectilePower(projectile.Value), isMeleeAttack: false); if (projectile.Owner != null && projectile.Owner.PlayerStats != null) { projectile.Owner.PlayerStats.RangedHits++; } } if (projectile.IsIncendiary) { bodyRaycastResult.Value.ComponentBody.Entity.FindComponent <ComponentOnFire>()?.SetOnFire(projectile?.Owner, m_random.Float(6f, 8f)); } vector = position; projectile.Velocity *= -0.05f; projectile.Velocity += m_random.Vector3(0.33f * projectile.Velocity.Length()); projectile.AngularVelocity *= -0.05f; } else if (terrainRaycastResult.HasValue) { CellFace cellFace2 = terrainRaycastResult.Value.CellFace; int cellValue = m_subsystemTerrain.Terrain.GetCellValue(cellFace2.X, cellFace2.Y, cellFace2.Z); int num = Terrain.ExtractContents(cellValue); Block block2 = BlocksManager.Blocks[num]; float num2 = projectile.Velocity.Length(); SubsystemBlockBehavior[] blockBehaviors2 = m_subsystemBlockBehaviors.GetBlockBehaviors(num); for (int j = 0; j < blockBehaviors2.Length; j++) { blockBehaviors2[j].OnHitByProjectile(cellFace2, projectile); } if (num2 > 10f && m_random.Float(0f, 1f) > block2.ProjectileResilience) { m_subsystemTerrain.DestroyCell(0, cellFace2.X, cellFace2.Y, cellFace2.Z, 0, noDrop: true, noParticleSystem: false); m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f); } if (projectile.IsIncendiary) { m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, 1f); Vector3 vector3 = projectile.Position - 0.75f * Vector3.Normalize(projectile.Velocity); for (int k = 0; k < 8; k++) { Vector3 v2 = (k == 0) ? Vector3.Normalize(projectile.Velocity) : m_random.Vector3(1.5f); TerrainRaycastResult?terrainRaycastResult2 = m_subsystemTerrain.Raycast(vector3, vector3 + v2, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => true); if (terrainRaycastResult2.HasValue) { m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult2.Value.CellFace.X, terrainRaycastResult2.Value.CellFace.Y, terrainRaycastResult2.Value.CellFace.Z, 1f); } } } if (num2 > 5f) { m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f); } if (block.IsStickable && num2 > 10f && m_random.Bool(block2.ProjectileStickProbability)) { Vector3 v3 = Vector3.Normalize(projectile.Velocity); float s = MathUtils.Lerp(0.1f, 0.2f, MathUtils.Saturate((num2 - 15f) / 20f)); vector2 = position + terrainRaycastResult.Value.Distance * Vector3.Normalize(projectile.Velocity) + v3 * s; } else { Plane plane = cellFace2.CalculatePlane(); vector = position; if (plane.Normal.X != 0f) { projectile.Velocity *= new Vector3(-0.3f, 0.3f, 0.3f); } if (plane.Normal.Y != 0f) { projectile.Velocity *= new Vector3(0.3f, -0.3f, 0.3f); } if (plane.Normal.Z != 0f) { projectile.Velocity *= new Vector3(0.3f, 0.3f, -0.3f); } float num3 = projectile.Velocity.Length(); projectile.Velocity = num3 * Vector3.Normalize(projectile.Velocity + m_random.Vector3(num3 / 6f, num3 / 3f)); projectile.AngularVelocity *= -0.3f; } MakeProjectileNoise(projectile); } if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue) { if (flag) { m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, projectile.Position, projectile.Value, 1f)); } else if (!projectile.ToRemove && (vector2.HasValue || projectile.Velocity.Length() < 1f)) { if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.TurnIntoPickable) { int num4 = BlocksManager.DamageItem(projectile.Value, 1); if (num4 != 0) { if (vector2.HasValue) { CalculateVelocityAlignMatrix(block, vector2.Value, projectile.Velocity, out Matrix matrix); m_subsystemPickables.AddPickable(num4, 1, projectile.Position, Vector3.Zero, matrix); } else { m_subsystemPickables.AddPickable(num4, 1, position, Vector3.Zero, null); } } projectile.ToRemove = true; } else if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.Disappear) { projectile.ToRemove = true; } } } float num5 = projectile.IsInWater ? MathUtils.Pow(0.001f, dt) : MathUtils.Pow(block.ProjectileDamping, dt); projectile.Velocity.Y += -10f * dt; projectile.Velocity *= num5; projectile.AngularVelocity *= num5; projectile.Position = vector; projectile.Rotation += projectile.AngularVelocity * dt; if (projectile.TrailParticleSystem != null) { if (!m_subsystemParticles.ContainsParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem)) { m_subsystemParticles.AddParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem); } Vector3 v4 = (projectile.TrailOffset != Vector3.Zero) ? Vector3.TransformNormal(projectile.TrailOffset, Matrix.CreateFromAxisAngle(Vector3.Normalize(projectile.Rotation), projectile.Rotation.Length())) : Vector3.Zero; projectile.TrailParticleSystem.Position = projectile.Position + v4; if (projectile.IsInWater) { projectile.TrailParticleSystem.IsStopped = true; } } bool flag2 = IsWater(projectile.Position); if (projectile.IsInWater != flag2) { if (flag2) { float num6 = new Vector2(projectile.Velocity.X + projectile.Velocity.Z).Length(); if (num6 > 6f && num6 > 4f * MathUtils.Abs(projectile.Velocity.Y)) { projectile.Velocity *= 0.5f; projectile.Velocity.Y *= -1f; flag2 = false; } else { projectile.Velocity *= 0.2f; } float?surfaceHeight = m_subsystemFluidBlockBehavior.GetSurfaceHeight(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z)); if (surfaceHeight.HasValue) { m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, new Vector3(projectile.Position.X, surfaceHeight.Value, projectile.Position.Z), large: false)); m_subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 6f, autoDelay: true); MakeProjectileNoise(projectile); } } projectile.IsInWater = flag2; } if (IsMagma(projectile.Position)) { m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, projectile.Position, large: false)); m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true); projectile.ToRemove = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value); } if (m_subsystemTime.PeriodicGameTimeEvent(1.0, (double)(projectile.GetHashCode() % 100) / 100.0) && (m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f), Terrain.ToCell(projectile.Position.Z)) || m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f) - 1, Terrain.ToCell(projectile.Position.Z)))) { m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true); projectile.ToRemove = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value); } } } } foreach (Projectile item in m_projectilesToRemove) { if (item.TrailParticleSystem != null) { item.TrailParticleSystem.IsStopped = true; } m_projectiles.Remove(item); if (this.ProjectileRemoved != null) { this.ProjectileRemoved(item); } } m_projectilesToRemove.Clear(); }
public Dictionary <string, string> GetBlockProperties(int value) { Dictionary <string, string> dictionary = new Dictionary <string, string>(); int num = Terrain.ExtractContents(value); Block block = BlocksManager.Blocks[num]; if (block.DefaultEmittedLightAmount > 0) { dictionary.Add(LanguageControl.Get(fName, 1), block.DefaultEmittedLightAmount.ToString()); } if (block.FuelFireDuration > 0f) { dictionary.Add(LanguageControl.Get(fName, 2), block.FuelFireDuration.ToString()); } dictionary.Add(LanguageControl.Get(fName, 3), (block.MaxStacking > 1) ? string.Format(LanguageControl.Get(fName, 4), block.MaxStacking.ToString()) : LanguageControl.Get("Usual", "no")); dictionary.Add(LanguageControl.Get(fName, 5), (block.FireDuration > 0f) ? LanguageControl.Get("Usual", "yes") : LanguageControl.Get("Usual", "no")); if (block.GetNutritionalValue(value) > 0f) { dictionary.Add(LanguageControl.Get(fName, 6), block.GetNutritionalValue(value).ToString()); } if (block.GetRotPeriod(value) > 0) { dictionary.Add(LanguageControl.Get(fName, 7), string.Format(LanguageControl.Get(fName, 25), $"{(2 * block.GetRotPeriod(value) * 60f / 1200f):0.0}")); } if (block.DigMethod != 0) { dictionary.Add(LanguageControl.Get(fName, 8), LanguageControl.Get("DigMethod", block.DigMethod.ToString())); dictionary.Add(LanguageControl.Get(fName, 9), block.DigResilience.ToString()); } if (block.ExplosionResilience > 0f) { dictionary.Add(LanguageControl.Get(fName, 10), block.ExplosionResilience.ToString()); } if (block.GetExplosionPressure(value) > 0f) { dictionary.Add(LanguageControl.Get(fName, 11), block.GetExplosionPressure(value).ToString()); } bool flag = false; if (block.GetMeleePower(value) > 1f) { dictionary.Add(LanguageControl.Get(fName, 12), block.GetMeleePower(value).ToString()); flag = true; } if (block.GetMeleePower(value) > 1f) { dictionary.Add(LanguageControl.Get(fName, 13), $"{100f * block.GetMeleeHitProbability(value):0}%"); flag = true; } if (block.GetProjectilePower(value) > 1f) { dictionary.Add(LanguageControl.Get(fName, 14), block.GetProjectilePower(value).ToString()); flag = true; } if (block.ShovelPower > 1f) { dictionary.Add(LanguageControl.Get(fName, 15), block.ShovelPower.ToString()); flag = true; } if (block.HackPower > 1f) { dictionary.Add(LanguageControl.Get(fName, 16), block.HackPower.ToString()); flag = true; } if (block.QuarryPower > 1f) { dictionary.Add(LanguageControl.Get(fName, 17), block.QuarryPower.ToString()); flag = true; } if (flag && block.Durability > 0) { dictionary.Add(LanguageControl.Get(fName, 18), block.Durability.ToString()); } if (block.DefaultExperienceCount > 0f) { dictionary.Add(LanguageControl.Get(fName, 19), block.DefaultExperienceCount.ToString()); } if (block is ClothingBlock) { ClothingData clothingData = ClothingBlock.GetClothingData(Terrain.ExtractData(value)); dictionary.Add(LanguageControl.Get(fName, 20), clothingData.CanBeDyed ? LanguageControl.Get("Usual", "yes") : LanguageControl.Get("Usual", "no")); dictionary.Add(LanguageControl.Get(fName, 21), $"{(int)(clothingData.ArmorProtection * 100f)}%"); dictionary.Add(LanguageControl.Get(fName, 22), clothingData.Sturdiness.ToString()); dictionary.Add(LanguageControl.Get(fName, 23), $"{clothingData.Insulation:0.0} clo"); dictionary.Add(LanguageControl.Get(fName, 24), $"{clothingData.MovementSpeedFactor * 100f:0}%"); } return(dictionary); }