public void ApplyMagmaNeighborhoodEffect(int x, int y, int z) { m_subsystemFireBlockBehavior.SetCellOnFire(x, y, z, 1f); switch (base.SubsystemTerrain.Terrain.GetCellContents(x, y, z)) { case 61: case 62: base.SubsystemTerrain.DestroyCell(0, x, y, z, 0, noDrop: false, noParticleSystem: false); m_subsystemParticles.AddParticleSystem(new BurntDebrisParticleSystem(base.SubsystemTerrain, new Vector3((float)x + 0.5f, y + 1, (float)z + 0.5f))); break; case 8: base.SubsystemTerrain.ChangeCell(x, y, z, 2); m_subsystemParticles.AddParticleSystem(new BurntDebrisParticleSystem(base.SubsystemTerrain, new Vector3((float)x + 0.5f, y + 1, (float)z + 0.5f))); break; } }
public override bool OnUse(Ray3 ray, ComponentMiner componentMiner) { object obj = componentMiner.Raycast(ray, RaycastMode.Digging); if (obj is TerrainRaycastResult) { CellFace cellFace = ((TerrainRaycastResult)obj).CellFace; if (m_subsystemExplosivesBlockBehavior.IgniteFuse(cellFace.X, cellFace.Y, cellFace.Z)) { m_subsystemAudio.PlaySound("Audio/Match", 1f, m_random.Float(-0.1f, 0.1f), ray.Position, 1f, autoDelay: true); componentMiner.RemoveActiveTool(1); return(true); } if (m_subsystemFireBlockBehavior.SetCellOnFire(cellFace.X, cellFace.Y, cellFace.Z, 1f)) { m_subsystemAudio.PlaySound("Audio/Match", 1f, m_random.Float(-0.1f, 0.1f), ray.Position, 1f, autoDelay: true); componentMiner.RemoveActiveTool(1); return(true); } } else if (obj is BodyRaycastResult) { ComponentOnFire componentOnFire = ((BodyRaycastResult)obj).ComponentBody.Entity.FindComponent <ComponentOnFire>(); if (componentOnFire != null) { if (m_subsystemGameInfo.WorldSettings.GameMode < GameMode.Challenging || m_random.Float(0f, 1f) < 0.33f) { componentOnFire.SetOnFire(componentMiner.ComponentCreature, m_random.Float(6f, 8f)); } m_subsystemAudio.PlaySound("Audio/Match", 1f, m_random.Float(-0.1f, 0.1f), ray.Position, 1f, autoDelay: true); componentMiner.RemoveActiveTool(1); return(true); } } return(false); }
public void PostprocessExplosions(bool playExplosionSound) { Point3 point = Point3.Zero; float num = float.MaxValue; float num2 = 0f; foreach (KeyValuePair <Point3, float> item in m_pressureByPoint.ToDictionary()) { num2 += item.Value; float num3 = m_subsystemAudio.CalculateListenerDistance(new Vector3(item.Key)); if (num3 < num) { num = num3; point = item.Key; } float num4 = 0.001f * MathUtils.Pow(num2, 0.5f); float num5 = MathUtils.Saturate(item.Value / 15f - num4) * m_random.Float(0.2f, 1f); if (num5 > 0.1f) { m_explosionParticleSystem.SetExplosionCell(item.Key, num5); } } foreach (KeyValuePair <Point3, SurroundingPressurePoint> item2 in m_surroundingPressureByPoint.ToDictionary()) { int cellValue = m_subsystemTerrain.Terrain.GetCellValue(item2.Key.X, item2.Key.Y, item2.Key.Z); int num6 = Terrain.ExtractContents(cellValue); SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(num6); if (blockBehaviors.Length != 0) { for (int i = 0; i < blockBehaviors.Length; i++) { blockBehaviors[i].OnExplosion(cellValue, item2.Key.X, item2.Key.Y, item2.Key.Z, item2.Value.Pressure); } } float probability = item2.Value.IsIncendiary ? 0.5f : 0.2f; Block block = BlocksManager.Blocks[num6]; if (block.FireDuration > 0f && item2.Value.Pressure / block.ExplosionResilience > 0.2f && m_random.Bool(probability)) { m_subsystemFireBlockBehavior.SetCellOnFire(item2.Key.X, item2.Key.Y, item2.Key.Z, item2.Value.IsIncendiary ? 1f : 0.3f); } } foreach (ComponentBody body in m_subsystemBodies.Bodies) { CalculateImpulseAndDamage(body, null, out Vector3 impulse, out float damage); impulse *= m_random.Float(0.5f, 1.5f); damage *= m_random.Float(0.5f, 1.5f); body.ApplyImpulse(impulse); body.Entity.FindComponent <ComponentHealth>()?.Injure(damage, null, ignoreInvulnerability: false, "Blasted by explosion"); body.Entity.FindComponent <ComponentDamage>()?.Damage(damage); ComponentOnFire componentOnFire = body.Entity.FindComponent <ComponentOnFire>(); if (componentOnFire != null && m_random.Float(0f, 1f) < MathUtils.Min(damage - 0.1f, 0.5f)) { componentOnFire.SetOnFire(null, m_random.Float(6f, 8f)); } } foreach (Pickable pickable in m_subsystemPickables.Pickables) { Block block2 = BlocksManager.Blocks[Terrain.ExtractContents(pickable.Value)]; CalculateImpulseAndDamage(pickable.Position + new Vector3(0f, 0.5f, 0f), 20f, null, out Vector3 impulse2, out float damage2); if (damage2 / block2.ExplosionResilience > 0.1f) { TryExplodeBlock(Terrain.ToCell(pickable.Position.X), Terrain.ToCell(pickable.Position.Y), Terrain.ToCell(pickable.Position.Z), pickable.Value); pickable.ToRemove = true; } else { Vector3 vector = (impulse2 + new Vector3(0f, 0.1f * impulse2.Length(), 0f)) * m_random.Float(0.75f, 1f); if (vector.Length() > 10f) { Projectile projectile = m_subsystemProjectiles.AddProjectile(pickable.Value, pickable.Position, pickable.Velocity + vector, m_random.Vector3(0f, 20f), null); if (m_random.Float(0f, 1f) < 0.33f) { m_subsystemProjectiles.AddTrail(projectile, Vector3.Zero, new SmokeTrailParticleSystem(15, m_random.Float(0.75f, 1.5f), m_random.Float(1f, 6f), Color.White)); } pickable.ToRemove = true; } else { pickable.Velocity += vector; } } } foreach (Projectile projectile2 in m_subsystemProjectiles.Projectiles) { if (!m_generatedProjectiles.ContainsKey(projectile2)) { CalculateImpulseAndDamage(projectile2.Position + new Vector3(0f, 0.5f, 0f), 20f, null, out Vector3 impulse3, out float _); projectile2.Velocity += (impulse3 + new Vector3(0f, 0.1f * impulse3.Length(), 0f)) * m_random.Float(0.75f, 1f); } } Vector3 position = new Vector3(point.X, point.Y, point.Z); float delay = m_subsystemAudio.CalculateDelay(num); if (num2 > 1000000f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionEnormous", 1f, m_random.Float(-0.1f, 0.1f), position, 40f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 100f); } else if (num2 > 100000f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionHuge", 1f, m_random.Float(-0.2f, 0.2f), position, 30f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 70f); } else if (num2 > 20000f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionLarge", 1f, m_random.Float(-0.2f, 0.2f), position, 26f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 50f); } else if (num2 > 4000f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionMedium", 1f, m_random.Float(-0.2f, 0.2f), position, 24f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 40f); } else if (num2 > 100f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionSmall", 1f, m_random.Float(-0.2f, 0.2f), position, 22f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 35f); } else if (num2 > 0f) { if (playExplosionSound) { m_subsystemAudio.PlaySound("Audio/ExplosionTiny", 1f, m_random.Float(-0.2f, 0.2f), position, 20f, delay); } m_subsystemNoise.MakeNoise(position, 1f, 30f); } }
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(); }